你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

用库#include <stdarg.h>实现串口printf函数

[复制链接]
与龙共舞 发布时间:2018-4-27 14:31
本帖最后由 与龙共舞 于 2018-4-27 14:57 编辑

问题引入:上位机C编程,第一句一般是printf你好世界到终端,而下位机没有终端,一般就是串口了。
串口输出并不困难,本文第一步也就是再次完成这个实验。
而格式化输出就要想办法了,比如刘洋说的三个步骤是Keil打钩用编译器来帮助。本文第二部分就是自己用库函数来实现。
第一步:串口输出
11.png
22.png
33.png
44.png
没有文字介绍了,挺容易的吧。
PC找一个USB--TTL的CH340
TX RX GND和板子的3个对应连接。
就可以看到实验效果。

第一步:串口格式化输出
为了方便移植,我们自己做一个模块。
logger.c
logger.h
最后主函数如下。
66.png
也就是要从
HAL_UART_Transmit(&huart1, (uint8_t *)Buffer, 10,0xFFFF);
升级到
logUsart("%d\t++++%s\n",a,s);        

下面开始实行这个模块。
直接放代码
  1. #ifndef _LOGGER_H_
  2. #define _LOGGER_H_

  3. #include        "stm32f1xx_hal.h"



  4. extern void logUsartInit(UART_HandleTypeDef *husart);
  5. extern int logUsart(const char* format, ...);

  6. #endif
复制代码
  1. #include "logger.h"
  2. #include <string.h>
  3. #include <stdarg.h>
  4. typedef unsigned char uint8_t;


  5.       
  6. #define MAX_HEX_STR         4
  7. #define MAX_HEX_STR_LENGTH  128
  8. char hexStr[MAX_HEX_STR][MAX_HEX_STR_LENGTH];
  9. uint8_t hexStrIdx = 0;
  10. #define USART_TIMEOUT          1000


  11. UART_HandleTypeDef *pLogUsart = 0;
  12. uint8_t logUsartTx(uint8_t *data, int dataLen);


  13. void logUsartInit(UART_HandleTypeDef *husart)
  14. {
  15.     pLogUsart = husart;
  16. }

  17. uint8_t logUsartTx(uint8_t *data, int dataLen)
  18. {
  19.   if(pLogUsart == 0)
  20.     return 0;
  21.   return HAL_UART_Transmit(pLogUsart, data, dataLen, USART_TIMEOUT);
  22. }

  23. int logUsart(const char* format, ...)
  24. {
  25.     #define LOG_BUFFER_SIZE 256
  26.     char buf[LOG_BUFFER_SIZE];
  27.     va_list argptr;
  28.     va_start(argptr, format);
  29.     int cnt = vsnprintf(buf, LOG_BUFFER_SIZE, format, argptr);
  30.     va_end(argptr);  

  31.     logUsartTx((uint8_t*)buf, strlen(buf));
  32.     return cnt;
  33. }
复制代码
效果如下
77.png

初始化是 挂钩你需要debug的串口。
格式化的核心是如下几句话:
va_list argptr;
va_start(argptr, format);
int cnt = vsnprintf(buf, LOG_BUFFER_SIZE, format, argptr);
va_end(argptr);


++++参考ST开发板代码+++
附近是即插即用的模块。
注意:在头文件中#include 不合理 会有很多错误!

logger.zip

下载

1.02 KB, 下载次数: 4

模块

收藏 评论3 发布时间:2018-4-27 14:31

举报

3个回答
Inc_brza 回答时间:2018-4-28 10:02:56
嗯嗯,很好,我现在就是这么用的,不过,也又一个比较明显的缺点,就是编译出来的bin会很大,你可以从map中看的到,所以其实也不难,自己写一个很简单的。
与龙共舞 回答时间:2018-4-28 11:13:46
Inc_brza 发表于 2018-4-28 10:02
嗯嗯,很好,我现在就是这么用的,不过,也又一个比较明显的缺点,就是编译出来的bin会很大,你可以从map中 ...

哦 那要做一个开关  正式版本程序把logger关闭
回答时间:2018-4-28 11:28:57
可以直接使用printf的,楼主难道不知道吗?自己写bug还不少,不如直接用底层驱动库,ST的例程里面也都写了。

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
  
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
        USART_SendData(USART1,ch);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
        {}
  return ch;
}

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版