You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F413串口发送时接收数据丢失问题求助

STM32F413串口发送期间丢接收数据的解决方案

针对你遇到的发送大数据包时忽略后续接收数据的问题,结合STM32F413的硬件特性,给出以下几个可行方案:

  • 配置DMA双缓冲区(Ping-Pong)接收
    启用UART DMA的循环接收模式,搭配两个独立的接收缓冲区。当DMA填满一个缓冲区时,立即触发中断并切换到另一个缓冲区继续接收,同时在中断回调里把已完成的缓冲区数据转存到后台队列,完全不会被发送操作阻塞。建议缓冲区大小设为4KB以上,足以容纳你的2K数据包。

  • 用后台发送队列+DMA发送完成中断驱动
    不要在接收完成后直接调用阻塞式发送函数,而是把待发送数据存入线程安全的环形队列,由DMA发送完成中断触发下一轮发送。这样发送大数据包时,CPU可以继续处理接收中断,不会因为等待发送完成而丢包。参考代码示例:

    // 定义环形发送队列
    uint8_t tx_ring_buf[64 * 1024];
    volatile uint32_t tx_head = 0;
    volatile uint32_t tx_tail = 0;
    volatile uint8_t tx_busy = 0;
    
    // 接收完成后将数据入队
    void uart_rx_done(uint8_t* data, uint32_t len) {
        for (uint32_t i = 0; i < len; i++) {
            tx_ring_buf[tx_head] = data[i];
            tx_head = (tx_head + 1) % sizeof(tx_ring_buf);
        }
        // 若当前无发送任务,启动DMA发送
        if (!tx_busy) {
            uint32_t send_len = (tx_head - tx_tail + sizeof(tx_ring_buf)) % sizeof(tx_ring_buf);
            if (send_len > 0) {
                HAL_UART_Transmit_DMA(&huart1, &tx_ring_buf[tx_tail], send_len);
                tx_tail = (tx_tail + send_len) % sizeof(tx_ring_buf);
                tx_busy = 1;
            }
        }
    }
    
    // DMA发送完成回调
    void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
        tx_busy = 0;
        // 检查队列剩余数据,继续发送
        uint32_t send_len = (tx_head - tx_tail + sizeof(tx_ring_buf)) % sizeof(tx_ring_buf);
        if (send_len > 0) {
            HAL_UART_Transmit_DMA(huart, &tx_ring_buf[tx_tail], send_len);
            tx_tail = (tx_tail + send_len) % sizeof(tx_ring_buf);
            tx_busy = 1;
        }
    }
    
  • 启用UART硬件FIFO并调整触发阈值
    STM32F413的UART自带16字节硬件FIFO,默认可能未启用。调用HAL_UARTEx_EnableFIFO()开启FIFO,再设置合适的中断触发阈值(比如8字节或14字节),可以减少中断触发频率,同时利用FIFO的缓冲能力,避免短时间内接收数据溢出。配置代码:

    HAL_UARTEx_EnableFIFO(&huart1);
    HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RX_FIFO_THRESHOLD_8_ITEMS);
    
  • 引入RTOS拆分任务
    如果项目未使用RTOS,建议引入FreeRTOS这类轻量级系统,将接收、发送拆分为独立任务,给接收任务设置更高优先级。接收任务仅负责把数据存入队列,发送任务从队列取数发送,彻底隔离发送和接收的执行流程,避免互相阻塞。

  • 优化DMA和UART优先级
    在CubeMX中检查DMA通道优先级,将接收DMA的优先级设为高于发送DMA,确保接收数据的DMA请求不会被发送抢占,保证数据及时从UART寄存器传输到内存。

内容的提问来源于stack exchange,提问作者shlee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:01:23