STM32串口如何接收字符串多次进入中断呢
出处:网络整理 发布于:2025-07-18 16:48:30
在 STM32 上使用串口接收字符串时,如果多次进入中断,通常是由于 接收中断(RXNE)频繁触发 导致的。为了避免数据丢失或处理混乱,可以采用 缓冲区 + DMA/中断管理 的方式。以下是几种常见解决方案:
方法 1:使用 HAL 库 + 环形缓冲区(推荐)
步骤:
启用串口接收中断
在初始化时开启接收中断(HAL_UART_Receive_IT()
),并设置一个缓冲区。c
uint8_t rx_buf[128]; // 接收缓冲区 HAL_UART_Receive_IT(&huart1, rx_buf, 1); // 每次接收 1 字节触发中断
在中断回调函数中处理数据
重写HAL_UART_RxCpltCallback()
,将数据存入环形缓冲区(FIFO)并重新启动接收。void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { ring_buffer_push(rx_buf); // 存入自定义环形缓冲区 HAL_UART_Receive_IT(&huart1, rx_buf, 1); // 重新启用接收 } }
在主循环中处理完整字符串
检查环形缓冲区是否包含完整字符串(如以\n
结尾),然后处理。
方法 2:使用 DMA + 空闲中断(IDLE)
步骤:
配置 DMA 接收
使用 DMA 自动接收数据到缓冲区,避免频繁中断。c
uint8_t dma_buf[256]; HAL_UART_Receive_DMA(&huart1, dma_buf, sizeof(dma_buf));
启用空闲中断(IDLE)
在串口初始化时启用空闲中断:__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
在中断中处理数据
当总线空闲(IDLE)时,表示一帧数据接收完成:void USART1_IRQHandler(void) { if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG(&huart1); uint16_t len = sizeof(dma_buf) - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); process_data(dma_buf, len); // 处理数据 HAL_UART_Receive_DMA(&huart1, dma_buf, sizeof(dma_buf)); // 重启 DMA } HAL_UART_IRQHandler(&huart1); }
方法 3:低功耗场景(LL 库 + 基本中断)
如果使用 LL 库,可以直接操作寄存器:
void USART1_IRQHandler(void) { if (LL_USART_IsActiveFlag_RXNE(USART1)) { uint8_t data = LL_USART_ReceiveData8(USART1); ring_buffer_push(data); // 存入缓冲区 } }
常见问题
数据覆盖
如果中断处理太慢,新数据会覆盖旧数据。解决方法:增大缓冲区或使用 DMA。
字符串截断
通过超时或特定字符(如
\n
)判断字符串结束。
性能优化
DMA + 空闲中断是方案,适合高速数据流。
示例代码(HAL + 空闲中断)
uint8_t rx_data[256]; uint32_t rx_len = 0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { rx_len++; HAL_UART_Receive_IT(&huart1, &rx_data[rx_len], 1); } } void USART1_IRQHandler(void) { if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG(&huart1); process_complete_string(rx_data, rx_len); rx_len = 0; } HAL_UART_IRQHandler(&huart1); }
版权与免责声明
凡本网注明“出处:老太阳集团tcy8722网站电子市场网”的所有作品,版权均属于老太阳集团tcy8722网站电子市场网,转载请必须注明老太阳集团tcy8722网站电子市场网,,违反者本网将追究相关法律责任。
本网转载并注明自其它出处的作品,目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品出处,并自负版权等法律责任。
如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。
- 简述计算机总线的分类2025/9/4 17:12:23
- 深度剖析三进线两母联供电系统设计方案2025/9/3 10:37:39
- 汇流排是什么汇流排好还是线接好2025/8/28 17:13:00
- 安森美 USB - C 电池充电器解决方案2025/8/28 15:45:10
- I2C 总线加上拉电阻的必要性2025/8/25 16:42:09