关于STM32用DMA传输UART空闲中断中接收的数据时无法接收数据问题以及解决办法
创始人
2025-06-01 17:58:13
0

一、stm32 cube ide 配置

1、DMA串口接收数据的ide配置如下图所示

 

        串口1相关的设置及printf函数的使用,这里没放,建议先实现串口打印功能

2、相关的知识点

        普通模式和循环模式的区别在于,普通模式下,DMA只会接收一次数据,接收完成后就会停止,需要接收时再开启;而循环模式下,DMA会一直接收数据,直到接收缓存区满或者手动停止。

       根据自己需求定模式,如果是数据有间隔,空闲中断的这种情况下,处理一帧数据,建议用Normal,有很多例程用Circular模式的情况下处理一帧数据,还要在中断中使用函数HAL_UART_DMAStop(); 来停止此次接收,处理数据后再重新启动接收,就显得有点多次两举了,如果用Circular模式,没有用HAL_UART_DMAStop停止接收的话,DMA会一直循环填充数据,size为最大,因为数据是循环填充的,所以数据的位置不定,看上去是乱的。

        关于禁用DMA传输的半传输中断,在空闲中断接收数据时,因为是不定长,假如在开启接收最大长度为128,那么当接收到64字节数据的时候就会触发半传输中断,因为这个触发用不到,所以禁用了。当然不禁用也行,半传输中断的回调函数是HAL_UART_RxHalfCpltCallback();

 

 二、无法接收数据问题

1、初始化顺序不对导致DMA无法正常传输串口接收的数据。

        具体原因查看:

使用STM32 CUBE IDE配置STM32F7 用DMA传输多通道ADC数据_stm32cubeide 配置adc_一只小白啊的博客-CSDN博客        文章最后部分的注意事项。

解决办法:先初始化DMA再初始化串口。

2、开启传输失败,导致DMA传输被重置为标准接收模式,无法触发空闲中断。

        产生原因:在使用HAL_UARTEx_ReceiveToIdle_DMA时,如果出现错误,即函数返回值=HAL_ERROR时,会被重置为HAL_UART_RECEPTION_STANDARD 标准接收模式,即中断回调函数为HAL_UART_RxCpltCallback,触发条件为当接收的数据满启动时指定的Size,如启动接收时指定接收长度为128字节,当接收到128字节时就会触发一次中断(如果DMA为循环模式)。

        这个错误可能出现的情况:开启状态下已经触发了一个中断,比如溢出或者重启时别的设备发送了一串数据,触发了一个空闲中断,同时有数据在串口的缓冲区,就会导致开启HAL_UARTEx_ReceiveToIdle_DMA时产生一个错误返回值,同时被置为标准接收模式。

        解决办法:清空接收缓冲区(不清空的话,依旧会返回HAL_ERROR),同时清除错误标志。调用HAL_UART_AbortReceive函数可以同时满足停止DMA传输、清空接收缓冲区、清除标志。

三、代码实例

整个实现逻辑如下图所示:

1、基本设置

/******************************************************************************* 参数:UART*****************************************************************************/
#define USART_REC_LEN 128 // 一次最大接收的字节数typedef struct
{uint8_t Receive_buffer[USART_REC_LEN]; // DMA数据接收缓存_Bool Receive_state;                   // 接收状态 表示一帧数据是否完成接收uint8_t Receive_length;                // 表示一帧数据长度,因为最大接收长度定义为128 所以uint8_t 够用_Bool Receive_flag;                    // 表示一帧数据正确,如果判断接收的数据为符合协议的能用的数据,则置1} UART_Receive_Def;
UART_Receive_Def UART5_DMA;/******************************************************************************* 功能:串口错误代码*****************************************************************************/
uint8_t Error_code_uart5;/******************************************************************************* 功能:打印串口状态标志*****************************************************************************/
void print_uart_sr(UART_HandleTypeDef *huart)
{printf("UART_FLAG_RWU       UART_FLAG_SBKF -->  %X -->  %X\r\n", __HAL_UART_GET_FLAG(huart, UART_FLAG_RWU), __HAL_UART_GET_FLAG(huart, UART_FLAG_SBKF));printf("UART_FLAG_CMF       UART_FLAG_BUSY -->  %X -->  %X\r\n", __HAL_UART_GET_FLAG(huart, UART_FLAG_CMF), __HAL_UART_GET_FLAG(huart, UART_FLAG_BUSY));printf("UART_FLAG_ABRF      UART_FLAG_ABRE -->  %X -->  %X\r\n", __HAL_UART_GET_FLAG(huart, UART_FLAG_ABRF), __HAL_UART_GET_FLAG(huart, UART_FLAG_ABRE));printf("UART_FLAG_CTS       UART_FLAG_LBDF -->  %X -->  %X\r\n", __HAL_UART_GET_FLAG(huart, UART_FLAG_CTS), __HAL_UART_GET_FLAG(huart, UART_FLAG_LBDF));printf("UART_FLAG_TXE         UART_FLAG_TC -->  %X -->  %X\r\n", __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE), __HAL_UART_GET_FLAG(huart, UART_FLAG_TC));printf("UART_FLAG_RXNE      UART_FLAG_RTOF -->  %X -->  %X\r\n", __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE), __HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF));printf("UART_FLAG_IDLE       UART_FLAG_ORE -->  %X -->  %X\r\n", __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE), __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE));printf("UART_FLAG_NE          UART_FLAG_FE -->  %X -->  %X\r\n", __HAL_UART_GET_FLAG(huart, UART_FLAG_NE), __HAL_UART_GET_FLAG(huart, UART_FLAG_FE));printf("UART_FLAG_PE                       --> %X \r\n", __HAL_UART_GET_FLAG(huart, UART_FLAG_PE));
}

2、初始化,不查看错误代码的话,启动只需要一条命令。

    /******************************************************************************* 功能:DMA接收,空闲中断*****************************************************************************/// 开启DMA传输UART空闲中断中接收的数据,并在接收到UART空闲中断后停止传输。Error_code_uart5 = HAL_UARTEx_ReceiveToIdle_DMA(&huart5, UART5_DMA.Receive_buffer, USART_REC_LEN);__HAL_DMA_DISABLE_IT(&hdma_uart5_rx, DMA_IT_HT);// 打印UART状态标志和错误码print_uart_sr(&huart5);printf("Error_code_uart5 --> %ld \r\n", Error_code_uart5);// 如果有错误的话if (Error_code_uart5 != HAL_OK){// 清空缓冲,置位一些标志,具体看函数内部HAL_UART_AbortReceive(&huart5);// 重启接收Error_code_uart5 = HAL_UARTEx_ReceiveToIdle_DMA(&huart5, UART5_DMA.Receive_buffer, USART_REC_LEN);}// 打印UART状态标志和错误码print_uart_sr(&huart5);printf("Error_code_uart5 --> %ld \r\n", Error_code_uart5);

3、中断回调,触发了空闲中断,接收到了一帧数据

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *UartHandle, uint16_t Size)
{if (UartHandle == &huart5){/******************************************************************************* 功能:DMA接收,空闲中断*****************************************************************************///处理数据(UART5_DMA.Receive_buffer, Size)//串口1打印或者其他处理,调试查看等//HAL_UART_Transmit(&huart1, UART5_DMA.Receive_buffer, Size, 0xFFFF);//重启接收HAL_UARTEx_ReceiveToIdle_DMA(&huart5, UART5_DMA.Receive_buffer, USART_REC_LEN);__HAL_DMA_DISABLE_IT(&hdma_uart5_rx, DMA_IT_HT);
}
}

相关内容

热门资讯

视频号家居消费趋势洞察与人设营... 今天分享的是:视频号家居消费趋势洞察与人设营销指南(2026版) 报告共计:93页 《视频号家居消费...
原创 优... 一家房企负责人在上海土地竞价大厅里,为徐汇区低密别墅地块举起第28轮竞价牌,他紧盯着的不再是周转速度...
券商发力养老金融空间广阔 养老金融是中央金融工作会议提出的金融“五篇大文章”之一。券商在为养老事业注入金融活水的同时,正构筑自...
美联储主席人选敲定在即,继任者... 来源:环球市场播报 接替杰罗姆・H・鲍威尔的人选,将不可避免地陷入一场难以摆脱的公信力危机。 凯文...
浦发银行:激活创新动能,助力债... 【大河财立方 记者 朱娟 文 朱哲 李博 马腾飞 摄影】12月17日下午,2025债券市场高质量发展...
厘定薪酬约束 公募生态再优化 监管机构正构建一套“长周期、强绑定、硬约束”的激励相容机制,其核心在于通过透明的规则和长期的利益捆绑...
国际能源署预测今年全球煤炭需求... 来源:财联社 国际能源署(IEA)周三表示,全球煤炭需求在2025年达到创纪录高位,但预计到2030...
原创 中... 文 | 钱钱 编辑 | 阿景 12月3日,一艘满载20万吨高品位铁矿石的货轮从几内亚马瑞巴亚港缓缓启...
原创 1... 写在文章前的声明:在本文之前的说明:本文中所列的投资信息,只是一个对基金资产净值进行排行的客观描述,...
港股速报 | 港股突发 狂买超... 每经记者:曾子建 每经编辑:袁东 12月17日,港股市场终于迎来反攻。 截至收盘,恒生指数报收于25...
地产新周期,贝好家C2M是房企... 2025年中国地产转向“好房子”建设,贝壳旗下贝好家以C2M模式探索房地产开发从“以土地为核心”转向...
劲拓股份聘任胡毅担任董秘:无上... 来源:挖贝网 挖贝网12月17日,劲拓股份[300400]近日发布聘任副总经理、董事会秘书的公告,董...
贵州将添一家“万亿”银行!贵州... 又一家省级农商行“航母”获批开业! 12月15日,国家金融监督管理总局贵州监管局批复称,同意贵州农商...
AI加速推动增长,Notion... 这家公司主营一款广受欢迎的生产力软件,如今正致力于转型为“全能型AI应用”平台。最新数据显示,其年度...
封关不是“封岛”! 原标题:封关不是“封岛”,这些说法不准确! 海南自由贸易港将于本月18日封关运作。封关不是“封岛”,...
突发!马云减持! 12月10日,华谊兄弟发布公告称,公司受经济形势影响,因部分回款资金未能如约到位,造成暂时性流动资金...
原创 缺... 美国明明自家地底下埋着不少稀土矿,够用好一阵子了,可工厂一缺货就得停摆,非得从咱们这儿买,这里面水深...
橡胶鞋厂逆袭,悦龙科技实控人一... 本文时代商业研究院 作者:陆烁宜 来源丨时代商业研究院 作者丨陆烁宜 编辑丨郑琳 从一家橡胶鞋厂到...
重庆A股49家上涨 三羊马三连... 12月17日,78家重庆A股上市公司中有49家上涨。 同花顺iFinD数据显示,三羊马以上涨10....