STM32串口如何接收字符串多次进入中断呢

出处:网络整理 发布于:2025-07-18 16:48:30

STM32 上使用串口接收字符串时,如果多次进入中断,通常是由于 接收中断(RXNE)频繁触发 导致的。为了避免数据丢失或处理混乱,可以采用 缓冲区 + DMA/中断管理 的方式。以下是几种常见解决方案:

方法 1:使用 HAL 库 + 环形缓冲区(推荐)

步骤:

  1. 启用串口接收中断
    在初始化时开启接收中断(HAL_UART_Receive_IT()),并设置一个缓冲区。

    c

    uint8_t rx_buf[128];  // 接收缓冲区 HAL_UART_Receive_IT(&huart1, rx_buf, 1);  // 每次接收 1 字节触发中断

  2. 在中断回调函数中处理数据
    重写 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);  // 重新启用接收
        } }

  3. 在主循环中处理完整字符串
    检查环形缓冲区是否包含完整字符串(如以 \n 结尾),然后处理。

方法 2:使用 DMA + 空闲中断(IDLE)

步骤:

  1. 配置 DMA 接收
    使用 DMA 自动接收数据到缓冲区,避免频繁中断。

    c

    uint8_t dma_buf[256]; HAL_UART_Receive_DMA(&huart1, dma_buf, sizeof(dma_buf));

  2. 启用空闲中断(IDLE)
    在串口初始化时启用空闲中断:

    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);

  3. 在中断中处理数据
    总线空闲(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);  // 存入缓冲区
    } }


常见问题

  1. 数据覆盖

    • 如果中断处理太慢,新数据会覆盖旧数据。解决方法:增大缓冲区或使用 DMA。

  2. 字符串截断

    • 通过超时或特定字符(如 \n)判断字符串结束。

  3. 性能优化

    • 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); }

关键词:STM32串口

版权与免责声明

凡本网注明“出处:老太阳集团tcy8722网站电子市场网”的所有作品,版权均属于老太阳集团tcy8722网站电子市场网,转载请必须注明老太阳集团tcy8722网站电子市场网,,违反者本网将追究相关法律责任。

本网转载并注明自其它出处的作品,目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品出处,并自负版权等法律责任。

如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。

OEM清单文件: OEM清单文件
*公司名:
*联系人:
*手机号码:
QQ:
有效期:

扫码下载APP,
一键连接广大的电子世界。

在线人工客服

买家服务:
卖家服务:
技术客服:

0571-85317607

网站技术支持

13606545031

客服在线时间周一至周五
9:00-17:30

关注官方微信号,
第一时间获取资讯。

建议反馈

联系人:

联系方式:

按住滑块,拖拽到最右边
>>
感谢您向阿库提出的宝贵意见,您的参与是老太阳集团tcy8722网站提升服务的动力!意见一经采纳,将有感恩红包奉上哦!