处理DMA+FIFO+空闲中断接收不定长数据时,时序竞争主要源于DMA传输、FIFO半满/溢出中断与空闲中断的异步触发。建议采用双缓冲(乒乓缓冲)机制:将DMA配置为循环模式,并启用半传输和传输完成中断,分别对应两个缓冲区。在中断服务程序中,先读取DMA的CNDTR寄存器(当前剩余数据量)和FIFO状态寄存器,锁定当前有效数据位置,再根据中断类型(半满/全满/空闲)切换缓冲区并处理数据。关键点:1) 在进入中断后立即禁用DMA或暂停传输(如使用DMA_Cmd或HAL_DMA_Abort),避免新数据覆盖;2) 处理完数据后,重新配置DMA的M0AR/M1AR和NDTR,并清除所有标志位,再使能DMA。对于FIFO溢出,需在溢出中断中读取FIFO剩余数据(如通过DR寄存器),并重置FIFO。空闲中断应作为帧结束标志,此时DMA可能仍在传输,需等待DMA空闲(检查EN位)再切换。实操建议:使用HAL库时,在DMA中断回调中调用HAL_DMA_GetState确认状态,并利用__HAL_DMA_GET_COUNTER获取精确计数。
mcuku 阿沐 · 2026-08-27