STM32 串口使用频繁的朋友可能知道一个问题,库自带的 USART_SendData 函数一次只能发送 1 Byte 字符 如果我们要输出一个带格式、带参数的串口数据就只能通过 sprintf 打印到一个临时数组,然后再使用一个for循环调用USART_SendData一个字符一个字符的输出,过程非常麻烦!
姜斌是一个非常怕麻烦的人所以这种方法无疑让我发疯!后来在原子(OpenEDV)那里购买了开发板拿到了例程。里面重定向了printf函数作为串口输出函数,有了这个函数之后就能够很轻松的参数输出,但问题就在这里我们串口1 串口2 都要带参数输出怎么办?
本次实验:自定义printf函数
实验数据来源:
配置usart2的串口配置
勾选usb micro lib,跟上面类似
添加头文件#include
,,#include
编写USART2的printf函数:
void USART2_printf (char *fmt, ...)
{
char buffer[CMD_BUFFER_LEN+1]; // CMD_BUFFER_LEN长度自己定义吧
u8 i = 0;
va_list arg_ptr;
va_start(arg_ptr, fmt);
vsnprintf(buffer, CMD_BUFFER_LEN+1, fmt, arg_ptr);
while ((i < CMD_BUFFER_LEN) && buffer[i])
{
USART_SendData(USART2, (u8) buffer[i++]);
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}
va_end(arg_ptr);
}
注明:以上代码中的红色字体部分替换为USART1就成了串口1的printf函数,以此类推。
我们使用以上代码后发现可以带参数输出了OK! 就这样结束了!是吗?
姜斌在一次实际的项目中使用到了以上网友提供的函数发现在传输数据的时候经常丢数据导致CRC验证不通过,起初以为是硬件设计问题后来一一排除后发现问题就出在以上这个函数中。
while ((i < CMD_BUFFER_LEN) && buffer[i])
这个条件中说明 如果我们传输的数据是以下数据,那么我们0x00就传输不出去,那么网友的代码为什么要加入这个判断呢?其实他是想判断一个字符串的结尾。
u8 Text[8] = {0x05,0x03,0x00,0x04,0x06,0x06,0x06,0x06};
如果这个printf函数用来输出字符串数据那绝对是没问题的!因为字符串结束符号 '