这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取逻辑分析仪】printf重定向至串口的几种方法

共6条 1/1 1 跳转至

【换取逻辑分析仪】printf重定向至串口的几种方法

助工
2024-09-30 21:00:58     打赏

一、前言

    本文将介绍在IDE工具中如何将printf函数重定向至串口输出,printf函数是经典的一个控制台字符打印函数,最大的优点是可以很方便的进行各种格式化输出操作,比如字符、字符串、整型、浮点型等内容格式化输出。printf 函数默认输出设备是显示器,如果要实现在串口或者 LCD 上显示,必须重定义标准库函数里调用的与输出设备相关的函数。比如使用 printf 输出到串口, 需要将 fputc 里面的输出指向串口,这一过程就叫重定向。

二、Keil串口重定向,使用微库MicroLib

    使用CubeMX生成基本Keil项目工程,使能串口外设1,波特率设为115200bps

~`EZ_]}[)ZJARZUVG`L]C}C.png

Keil工程结构

$5KCI1RF(}1OJHM2L9P5B(5.png

方法一串口重定向需要使用Keil工具内置的MicroLib

JX1J245_X_@YG32AAMCD5~I.png

微库勾选后重写fputc函数,printf函数执行后会调用fputc函数

在main.c begin1区域插入如下代码

/* USER CODE BEGIN 0 */
#include <stdio.h>
int fputc(int ch, FILE *f)
{
    /* 发送一个字节数据到串口DEBUG_USART */
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);    
    
    return (ch);
}
/* USER CODE END 0 */

while循环体加入测试代码

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		HAL_Delay(300);
		printf("Hello.\n");
		printf("num_float=%f\n",5.656);
		//HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

实验结果

VE4L2M8UZF$~VC5(M2GHEKP.png

可以看到字符串、浮点数可以正确打印出来

三、Keil串口重定向,不使用微库MicroLib

在某些情况下主程序因为使用了微库而无法正常运行,这时候不得不取消微库使用

此时可以使用以下方法解决,取消勾选微库

_S{](@14TFGP4SZ1B0ET0%S.png

在main.c begin1区域插入如下代码

#if 1
/* 告知连接器不从C库链接使用半主机的函数 */
#pragma import(__use_no_semihosting)

/* 定义 _sys_exit() 以避免使用半主机模式 */
void _sys_exit(int x)
{
    x = x;
}

/* 标准库需要的支持类型 */
struct FILE
{
    int handle;
};

FILE __stdout;

/*  */
//int fputc(int ch, FILE *stream)
//{
//    /* 堵塞判断串口是否发送完成 */
//    while((USART1->ISR & 0X40) == 0);

//    /* 串口发送完成,将该字符发送 */
//    USART1->TDR = (uint8_t) ch;

//    return ch;
//}
int fputc(int ch, FILE *f)
{
    /* 发送一个字节数据到串口DEBUG_USART */
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
    return (ch);
}
#endif

while循环体加入测试代码

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		HAL_Delay(300);
		printf("Hello.\n");
		printf("num_float=%f\n",3.141592);
		//HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

编译程序无误,烧录固件至开发板

{Y1J@VZD7QYPL3ZTW6O)E8K.png

字符串、浮点数可以正确打印出来

四、CubeIDE串口重定向,使用标准库

新建CubeIDE基本项目工程,工程结构如下

`LH]KTRLPB[44A`651%%~84.png

在main.c begin0区域插入如下代码

/* USER CODE BEGIN 0 */
#include <stdio.h>
// 重定向printf start
//_write函數在syscalls.c中, 使用__weak定義, 所以可以直接在其他文件中定義_write函數
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
	if(HAL_UART_Transmit(&huart1,ptr,len,0xffff) != HAL_OK)
	{
		Error_Handler();
	}
}
// 重定向printf end
/* USER CODE END 0 */

while循环体加入测试代码

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		HAL_Delay(300);
		printf("Hello.\n");
		printf("num_float=%f\n",3.141592/2);
		//HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

实验结果,CubeIDE默认不支持浮点数格式化

WB6YWZB@`F]ETE1PO_TN]OO.png

CubeIDE做如下设置

H2E5W9`TS7(1MBOKT6R7X$6.png

在弹出界面找到settings

@4LZ(H%EH{~00EB9A[92NA8.png

点击+号添加如下标志

-u _printf_float

ZEVUA}R8I]UFNVXF{2[J2B0.png

保存设置并关闭当前小窗口。编译程序无误,重新烧录固件至开发板

G0])TD)VT7HL2N)Q$TZ)0(A.png

字符串、浮点数可以正确打印出来




关键词: printf重定向    

专家
2024-10-01 09:34:03     打赏
2楼

谢谢分享


专家
2024-10-01 14:40:51     打赏
3楼

重写fputc函数,printf函数执行后会自动调用fputc函数


专家
2024-10-02 09:16:50     打赏
4楼

感谢楼主分享


院士
2024-10-03 10:15:12     打赏
5楼

谢谢楼主分享

反正,我是不建议使用这个重定向


高工
2024-10-05 09:10:02     打赏
6楼

重定向操作有啥优势啊


共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]