Raspberry Pi Pico UART:如何优雅检测DMA接收串行数据块的结束?
RP2040 DMA接收串行数据的问题解答
1. 更优雅的块结束检测方式
推荐用UART空闲线中断替代定时器轮询,这是硬件级的检测方案,高效且精准:
- RP2040的UART支持空闲线中断,当接收线上持续空闲超过一个完整字符帧的时间(9600波特率下约1041μs)时触发。你的场景是每秒一个500字节块,块之间的空闲时间远大于单字符间隔,刚好能触发这个中断识别块结束。
- 具体实现思路:
- 配置DMA为循环模式,将UART接收数据持续写入环形缓冲区(比如设置1000字节缓冲,足够容纳两个块)。
- 开启UART的空闲线中断,当中断触发时,读取当前DMA的写入指针(
dma_channel_hw_addr(chan)->write_addr),结合上一次的指针位置计算当前块的字节数,提取并处理这500字节数据。 - 处理完成后更新指针标记,无需中断DMA传输,彻底解决同步问题。
2. UART是否支持接收超时检测
RP2040的UART没有专门的"接收超时"寄存器,但空闲线中断可以完全替代超时检测功能。空闲中断的触发条件就是接收线无数据的时间超过一个字符帧(起始位+8数据位+停止位,共10位),对于9600波特率来说约1041μs,这本质就是硬件级的接收超时判断,完全适配你的块结束检测需求。
3. DMA激活时UART中断无法触发的原因
常见原因有这几个:
- 未正确开启对应UART中断源:比如使用空闲线中断时,需要调用
uart_set_irq_enables(uart, false, false, true, false)(第三个参数设为true开启空闲中断),没开的话自然不会触发。 - 中断优先级配置冲突:如果DMA中断优先级高于UART中断,且系统中断资源紧张,可能导致UART中断被抢占无法触发。可以通过
irq_set_priority调整UART中断优先级(比如设为3,高于默认DMA优先级)。 - 误关闭UART中断使能:有些代码启动DMA接收时会关闭UART接收中断避免冲突,但空闲中断独立于接收中断,不需要关闭,反而要确保对应的中断掩码处于开启状态。
- 中断处理函数未正确注册:如果没通过
irq_set_exclusive_handler或irq_add_shared_handler注册UART空闲中断的处理函数,中断触发后也不会执行对应逻辑。
内容的提问来源于stack exchange,提问作者user12537
相关产品推荐
相关产品推荐

