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

【经验分享】STM32使用HAL库DMA+空闲中断实现串口不定长数据接收

[复制链接]
STMCU小助手 发布时间:2022-4-10 21:55
首先配置串口:

V~7F]1~1DR$S0$$%C`}0@CU.png

开启串口中断:

ZJH@T_F`WF[`H@6$E6O$QGC.png

开启DMA接收:

MR{5DNR]34L5HW_8R4PZF]E.png

配置中断分组:

M~]XVNW_]TZWS`765LI7O_W.png

取消自动生成串口1的中断服务程序,我们自己写:

[J@)QLG}$H%(4R04YBH3GLP.png

然后生成代码就可以了。


进入代码,添加串口1中断服务程序:


  1. #define UART_RX_LEN 1024           // 一次最大接收的数据量
  2. uint8_t UART_RX_BUF[UART_RX_LEN];  // DMA数据接收缓存
  3. __IO uint16_t UART_RX_STA = 0;     // 第15bit表示一帧数据接收完成,第14~0位表示接收到的数据量

  4. void USART1_IRQHandler(void)
  5. {
  6.         if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)  // 空闲中断标记被置位
  7.         {
  8.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);  // 清除中断标记
  9.             HAL_UART_DMAStop(&huart1);           // 停止DMA接收
  10.             UART_RX_STA = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx);  // 总数据量减去未接收到的数据量为已经接收到的数据量
  11.             UART_RX_BUF[UART_RX_STA] = 0;  // 添加结束符
  12.             UART_RX_STA |= 0X8000;         // 标记接收结束
  13.             HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN);  // 重新启动DMA接收
  14.         }
  15. }
复制代码

使能空闲中断和DMA接收:

  1.         HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN);  // 启动DMA接收
  2.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);              // 使能空闲中断
复制代码

while死循环中加入发回的代码:

  1. if(UART_RX_STA & 0X8000)
  2. {
  3.         HAL_UART_Transmit(&huart1, UART_RX_BUF, UART_RX_STA & 0X7FFF, 100);    // 将接收到的数据发送回去
  4.         UART_RX_STA = 0;  // 清除标记
  5. }
复制代码

完整代码如下:

  1. /* USER CODE BEGIN 0 */

  2. #define UART_RX_LEN 1024
  3. uint8_t UART_RX_BUF[UART_RX_LEN];
  4. __IO uint16_t UART_RX_STA = 0;

  5. void USART1_IRQHandler(void)
  6. {
  7.         if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)  // 空闲中断标记被置位
  8.         {
  9.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);  // 清楚中断标记
  10.             HAL_UART_DMAStop(&huart1);           // 停止DMA接收
  11.             UART_RX_STA = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx);  // 总数据量减去未接收到的数据量为已经接收到的数据量
  12.             UART_RX_BUF[UART_RX_STA] = 0;  // 添加结束符
  13.             UART_RX_STA |= 0X8000;         // 标记接收结束
  14.             HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN);  // 重新启动DMA接收
  15.         }
  16. }


  17. int main(void)
  18. {
  19.         HAL_Init();
  20.         SystemClock_Config();
  21.         MX_GPIO_Init();
  22.         MX_DMA_Init();
  23.         MX_USART1_UART_Init();
  24.         HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN);  // 启动DMA接收
  25.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);              // 使能空闲中断
  26.         while (1)
  27.         {
  28.                 if(UART_RX_STA & 0X8000)
  29.                 {
  30.                         HAL_UART_Transmit(&huart1, UART_RX_BUF, UART_RX_STA & 0X7FFF, 100);    // 将接收到的数据发送回去
  31.                         UART_RX_STA = 0;
  32.                 }
  33.         }
  34. }

  35. /* USER CODE END 0 */
复制代码

程序效果:


20200903164720325.gif

ends…


收藏 评论0 发布时间:2022-4-10 21:55

举报

0个回答

所属标签

相似技术帖

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