在STM32上,串口DMA接收定长数据并触发中断,核心思路是:配置DMA为循环模式,利用空闲中断(IDLE)或DMA传输完成中断(TC)来判定一帧数据就绪。推荐使用DMA循环模式+空闲中断,因为定长数据可能连续到达,循环模式可避免频繁重配。
**实现步骤**:
1. 初始化UART,使能IDLE中断(USART_CR1的IDLEIE位)。
2. 配置DMA为循环模式,外设地址为USART_DR,内存为缓冲区,数据长度设为定长N。
3. 在IDLE中断中,读取USART_SR和USART_DR以清除标志,然后计算当前DMA剩余数据量(DMA_CNDTR),用N减去剩余量即为本次接收长度。
4. 处理数据后,无需重配DMA,循环模式自动继续。
```c
void USART1_IRQHandler(void) {
if (USART_GetITStatus(USART1, USART_IT_IDLE)) {
USART_ReceiveData(USART1); // 清除IDLE标志
uint16_t remain = DMA_GetCurrDataCounter(DMA1_Channel5);
uint16_t received = N - remain;
// 处理received字节,缓冲区从0开始
process_data(rx_buffer, received);
}
}
```
**注意**:若定长数据间隔固定,也可用DMA传输完成中断(非循环模式),但需在中断中重新配置DMA,略繁琐。建议优先循环+IDLE。
mcuku 阿沐 · 2026-08-19