STM32自定义printf实现多串口互用

发布者:SereneMeadow7最新更新时间:2024-10-16 来源: cnblogs关键字:STM32 手机看文章 扫描二维码
随时随地手机看文章

STM32 串口使用频繁的朋友可能知道一个问题,库自带的 USART_SendData 函数一次只能发送 1 Byte 字符 如果我们要输出一个带格式、带参数的串口数据就只能通过 sprintf 打印到一个临时数组,然后再使用一个for循环调用USART_SendData一个字符一个字符的输出,过程非常麻烦!


姜斌是一个非常怕麻烦的人所以这种方法无疑让我发疯!后来在原子(OpenEDV)那里购买了开发板拿到了例程。里面重定向了printf函数作为串口输出函数,有了这个函数之后就能够很轻松的参数输出,但问题就在这里我们串口1 串口2 都要带参数输出怎么办?


本次实验:自定义printf函数
实验数据来源:
  

  1. 配置usart2的串口配置

  2. 勾选usb micro lib,跟上面类似

  3. 添加头文件#include ,,#include 

    编写USART2的printf函数:


  1. void USART2_printf (char *fmt, ...)

  2. {

  3. char buffer[CMD_BUFFER_LEN+1]; // CMD_BUFFER_LEN长度自己定义吧

  4. u8 i = 0;


  5. va_list arg_ptr;

  6. va_start(arg_ptr, fmt);

  7. vsnprintf(buffer, CMD_BUFFER_LEN+1, fmt, arg_ptr);

  8. while ((i < CMD_BUFFER_LEN) && buffer[i])

  9. {

  10.         USART_SendData(USART2, (u8) buffer[i++]);

  11. while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);

  12. }

  13. va_end(arg_ptr);

  14. }


注明:以上代码中的红色字体部分替换为USART1就成了串口1的printf函数,以此类推。

我们使用以上代码后发现可以带参数输出了OK! 就这样结束了!是吗?

姜斌在一次实际的项目中使用到了以上网友提供的函数发现在传输数据的时候经常丢数据导致CRC验证不通过,起初以为是硬件设计问题后来一一排除后发现问题就出在以上这个函数中。


  1. while ((i < CMD_BUFFER_LEN) && buffer[i])

这个条件中说明 如果我们传输的数据是以下数据,那么我们0x00就传输不出去,那么网友的代码为什么要加入这个判断呢?其实他是想判断一个字符串的结尾。

u8 Text[8] = {0x05,0x03,0x00,0x04,0x06,0x06,0x06,0x06};

如果这个printf函数用来输出字符串数据那绝对是没问题的!因为字符串结束符号 '' 对应的就是0x00,所以我们需要改进一下这个printf函数使其更加的具有通用性。

代码中的 vsnprintf 函数  用于向字符串中打印数据、数据格式用户自定义 ,其实网友忽略了它有返回值

返回值: 执行成功,返回写入到字符数组str中的字符个数(不包含终止符),最大不超过size;执行失败,返回负值,并置erron

我们这里只要利用这个返回值就能知道我们需要输出多少个字符,所以改进版本的printf函数如下:

  1. void usart1Printf(char *fmt, ...)

  2. {

  3.     char buffer[CMD_BUFFER_LEN - 1];

  4.     u8 i = 0;

  5.     u8 len;


  6.     va_list arg_ptr; //Define convert parameters variable

  7.     va_start(arg_ptr, fmt); //Init variable

  8.     len = vsnprintf(buffer, CMD_BUFFER_LEN+1, fmt, arg_ptr); //parameters list format to buffer

  9.     

  10.     while ((i < CMD_BUFFER_LEN) && (i < len) && (len > 0))

  11.     {

  12.         USART_SendData(USART1, (u8) buffer[i++]);

  13.         while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

  14.     }

  15.     va_end(arg_ptr);

  16. }



关键字:STM32 引用地址:STM32自定义printf实现多串口互用

上一篇:STM32启动流程
下一篇:STM32万年历时钟调试经验(时间精度问题,断电RTC不持续运行)

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved