STM32 HAL库串口重定向实现简单三步(附代码)

目录

第一步:添加标准输入输出头文件

第二步:重写fputc()函数

第三步:重写fgetc()函数

代码汇总(直接复制使用)-需要直接来复制


在PC上进行C语言程序开发时,我们可以利用C语言的格式化输出函数 printf()将程序的运行结果发送到显示屏上显示,也可以利用格式化输人函数 scanf()读取由键盘输入的信息。在嵌入式系统的开发中,我们也希望能够将程序的运行结果或者调试信息发送到 PC 上显示,并读取由键盘输入的信息,实现良好的人机交互。

HAL库提供的串口收发函数,功能比较简单,不能进行格式化的输入输出。如果要实现类似 C语言中的格式化输入输出函数,需要把printf()函数的输出和 scanf( )函数的输入重新定向到串口。

具体的实现方法如下:用户编写与C 语言标准库函数中同名的函数,当链接器检查到用户编写了与标准库函数同名的函数时,将优先使用用户编写的函数,从而实现对标准库函数的间接修改(标准库函数中的同名函数采用了 weak 属性定义)。

由于printf()函数通过调用fputc()函数来实现数据的输出,scanf()函数通过调用fgetc()函数来实现数据的输入,因此用户需要改写这两个函数来实现串口的重定向。

在进行重定向之前,需要配置好串口,使用到串口的轮寻模式。

注意:由于 printf()函数和scan()函数是由MDK 软件所提供的 C语言标准库函数,在完成程序编写后,用户还需要在MDK 软件的工程设置窗口中选择“Target”标签页勾选其中的“Use MicroLIB”选项。如果不勾选“Use MicroLIB”选项,则无法使用。

第一步:由于主程序中调用了printf()函数和scanf()函数,因此需要添加标准输入输出头文件:stdio.h。

/* USER CODE BEGIN Includes*/

#include <stdio.h>// 包含标准输入输出头文件

/* USER CODE END Includes*/

第二步:重写fputc()函数

int fputc(int ch,FILE *f)

{

//采用轮询方式发送1字节数据,超时时间设置为无限等待

HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);

return ch;

}

注意:由于入口参数ch是整型变量,而函数HAL_UART_Transmit()的入口参数pdata是指向无符号字符型的指针,因此需要进行强制类型转换,将int转换为uint8_t*。

HAL_MAX_DELAY意味着无限等待,可以修改,比如修改为1000。

第三步:重写fgetc()函数

int fgetc(FILE *f)

{

uint8_t ch;

// 采用轮询方式接收 1字节数据,超时时间设置为无限等待

HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );

return ch;

}

注意:调用scanf()函数读取串口数据时,需要以空格作为输入的结束。因此在串口调试助手中输入数据时,必须以空格作为结束,然后再点击发送按钮,否则无法正确接收数据。

scanf()函数只能接收不带空格的字符串。如果用户需要接收一个带空格的字符串,需要先逐个字节的接收,在接收过程中通过不断判断是否接收到 ‘\r’和‘\n’两个字符,来确定字符串是否接收完成。此时,串口调试助手的发送区中应该在输入一个完整字符串后,再按下键盘的“ENTER”键作为结束

代码汇总(直接复制使用):

#include <stdio.h>// 包含标准输入输出头文件

int fputc(int ch,FILE *f)
{
//采用轮询方式发送1字节数据,超时时间设置为无限等待
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch;
// 采用轮询方式接收 1字节数据,超时时间设置为无限等待
HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );
return ch;
}

物联沃分享整理
物联沃-IOTWORD物联网 » STM32 HAL库串口重定向实现简单三步(附代码)

发表评论