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

【经验分享】STM32 UART收发-中断方式接收-重定向printf函数

[复制链接]
STMCU小助手 发布时间:2022-4-12 10:00
环境:
1、STM32CubeMX 5.3
2、Atollic TrueSTUDIO for STM32 9.3.0
3、战舰迷你板(stm32f103rb)


(一)配置串口
波特率:115200
数据长度:8bit
停止位:1位
校验位:无

0{CJ5]DZVE1SQVJQX3`1F@5.png

(二)配置串口接收中断

设置中断分组为第二组,使能串口中断,串口中断优先级设置成主优先级3,次优先级0:

6F{DR2XXAH_GHB~YD(PCZZA.png

(三)修改代码

在函数MX_USART1_UART_Init中添加如下代码,使能串口中断:

  1. HAL_UART_Receive_IT(&huart1, RecvBuffer, 1);                // 使能接收中断
复制代码

然后覆写接收中断回调函数:

  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  2. {
  3.         if (huart->Instance == huart1.Instance)
  4.         {
  5.                 HAL_UART_Transmit(&huart1, RecvBuffer, 1, 0xFFFF);                // 将收到的数据在发回去
  6.                 HAL_UART_Receive_IT(&huart1, RecvBuffer, 1);                        // 再次使能接收中断
  7.         }
  8. }
复制代码

然后添加如下代码重定向printf函数:

  1. #ifdef __GNUC__
  2. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  3. #else
  4. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  5. #endif
  6. PUTCHAR_PROTOTYPE
  7. {
  8.         HAL_UART_Transmit(&huart1, (uint8_t *) &ch, 1, 100);
  9.         return ch;
  10. }
复制代码

效果如下图:

@LBDZDCKVOQRN}7Y7NR[$K1.png

(四)使printf函数可以打印浮点数
项目->属性:


20191018092753343.png

(五)重新实现printf函数
  1. void debug_printf(const void* fmt, ...)
  2. {
  3.         static char buf[1024];
  4.     va_list ap;
  5.     va_start(ap, fmt);
  6.     vsprintf(buf, (char *)fmt, ap);
  7.     va_end(ap);
  8.     HAL_UART_Transmit(&huart1, (uint8_t *)buf, strlen(buf), 100);
  9. }
复制代码

(六)串口接收与处理
  1. #define UART1_RX_LEN 0xFF                                 // 串口一次接受数据的最大长度
  2. uint8_t UART1_RX_BUF[UART1_RX_LEN];                // 串口接收缓存
  3. uint8_t UART1_RX_BYTE = 0;                                // 串口中断接收一个字节
  4. uint16_t UART1_RX_STA = 0;                                // 串口接受状态,第15位表示接收到了换行符,第14为表示接收到了回车符,第0~7位表示本次接收到的数据长度
复制代码
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  2. {
  3.         if (huart->Instance == huart1.Instance)
  4.         {
  5.                 if ((UART1_RX_STA & 0x8000) == 0)                        // 接收未完毕
  6.                 {
  7.                         if (UART1_RX_STA & 0x4000)                                // 接收到了回车符
  8.                         {
  9.                                 if (UART1_RX_BYTE == '\n')                        // 本次接受到的是换行符
  10.                                         UART1_RX_STA |= 0x8000;                        // 标记接收结束
  11.                                 else
  12.                                         UART1_RX_STA = 0;                                // 否则接收错误,状态置为初始
  13.                         }
  14.                         else
  15.                         {
  16.                                 if (UART1_RX_BYTE == '\r')                        // 本次接收到的是回车符
  17.                                         UART1_RX_STA |= 0x4000;                        // 标记接收到了回车符
  18.                                 else
  19.                                 {
  20.                                         UART1_RX_BUF[UART1_RX_STA & 0x3FFF] = UART1_RX_BYTE;        // 本次接收到的是数据
  21.                                         if (UART1_RX_STA++ >= UART1_RX_LEN)                                                // 连续接收到的数据高于最大接收长度,则视为接收错误
  22.                                                 UART1_RX_STA = 0;                                                                        // 状态置为初始
  23.                                 }
  24.                         }
  25.                 }
  26.                 HAL_UART_Receive_IT(&huart1, &UART1_RX_BYTE, 1);                                        // 再次使能接收中断
  27.         }
  28. }

  29. /**
  30. * 串口1接收处理函数
  31. */
  32. void UART1_RecvHandler(void)
  33. {
  34.         if (UART1_RX_STA & 0x8000)                                                        // 有数据收到
  35.         {
  36.                 UART1_RX_BUF[UART1_RX_STA & 0x3FFF] = '\0';                // 添加结束符
  37.                 printf("%s\r\n", UART1_RX_BUF);                                        // 串口打印出来
  38.                 UART1_RX_STA = 0;                                                                // 状态置为初始
  39.         }
  40. }
复制代码

ends…


收藏 评论0 发布时间:2022-4-12 10:00

举报

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