STM32使用HAL库DMA+空闲中断实现串口不定长数据接收

STM32使用HAL库DMA+空闲中断实现串口不定长数据接收


环境:

  • STM32CubeIDE
  • STM32F103RB
  • WIN10
  • HAL库V1.8

首先配置串口:

在这里插入图片描述

开启串口中断:
在这里插入图片描述
开启DMA接收:
在这里插入图片描述
配置中断分组:
在这里插入图片描述
取消自动生成串口1的中断服务程序,我们自己写:
在这里插入图片描述
然后生成代码就可以了。

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

1#define UART_RX_LEN 1024 // 一次最大接收的数据量 2uint8_t UART_RX_BUF[UART_RX_LEN]; // DMA数据接收缓存 3__IO uint16_t UART_RX_STA = 0; // 第15bit表示一帧数据接收完成,第14~0位表示接收到的数据量 4 5void 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}

使能空闲中断和DMA接收:

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

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

1if(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 3#define UART_RX_LEN 1024 4uint8_t UART_RX_BUF[UART_RX_LEN]; 5__IO uint16_t UART_RX_STA = 0; 6 7void USART1_IRQHandler(void) 8{ 9 if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) // 空闲中断标记被置位 10 { 11 __HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清楚中断标记 12 HAL_UART_DMAStop(&huart1); // 停止DMA接收 13 UART_RX_STA = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx); // 总数据量减去未接收到的数据量为已经接收到的数据量 14 UART_RX_BUF[UART_RX_STA] = 0; // 添加结束符 15 UART_RX_STA |= 0X8000; // 标记接收结束 16 HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN); // 重新启动DMA接收 17 } 18} 19 20 21int main(void) 22{ 23 HAL_Init(); 24 SystemClock_Config(); 25 MX_GPIO_Init(); 26 MX_DMA_Init(); 27 MX_USART1_UART_Init(); 28 HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN); // 启动DMA接收 29 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 使能空闲中断 30 while (1) 31 { 32 if(UART_RX_STA & 0X8000) 33 { 34 HAL_UART_Transmit(&huart1, UART_RX_BUF, UART_RX_STA & 0X7FFF, 100); // 将接收到的数据发送回去 35 UART_RX_STA = 0; 36 } 37 } 38} 39 40/* USER CODE END 0 */

程序效果:
在这里插入图片描述


ends…

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

STM32使用HAL库DMA+空闲中断实现串口不定长数据接收 - HelloWorld