文章目录
- STM32CubeMX配置
- DMA控制语句
-
- HAL_UART_Receive_DMA
-
- [普通定长 DMA 接收](#普通定长 DMA 接收)
- [循环 DMA + 半满/全满中断](#循环 DMA + 半满/全满中断)
- HAL_UART_Receive_DMA
-
- [DMA + 空闲中断(不定长)](#DMA + 空闲中断(不定长))
- 中断控制语句
STM32CubeMX配置
基础配置

DMA 的 Normal 和 Circular
| 模式 | 行为 | 适合场景 |
|---|---|---|
| Normal | 传输完一次就停,需要重新调用启动函数 | 定长收发、一次性发送 |
| Circular | 缓冲区写满后自动回到开头继续写 | 连续接收、ADC、音频、串口流 |


DMA 的FIFO配置
DMA Request Synchronization Settings
- DMA Request Synchronization Settings 是 STM32H7 里 DMAMUX 的"同步触发"功能,用来让 DMA 传输被某个外部事件(比如 EXTI、定时器 TRGO、DMA 完成事件等)门控触发。
- DMA 传输必须严格跟随某个外部触发信号,比如:
- 定时器 TRGO 触发 ADC DMA 采样
- EXTI 触发 SPI DMA 发送
- 某个外设事件到来后,才允许 DMA 搬运 N 个数据
DMA 的中断配置

关闭MPU

DMA控制语句
HAL_UART_Receive_DMA
普通定长 DMA 接收
c
HAL_UART_Receive_DMA(&huart1, rx_buf, len);
- 触发条件 :DMA 计数器减到 0,即收满
len字节。 - 回调 :
HAL_UART_RxCpltCallback()。 - 适用:已知长度的帧,比如固定 8 字节寄存器应答。
- 局限:必须预知长度;收不满不会回调。
循环 DMA + 半满/全满中断
c
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
HAL_UART_Receive_DMA(&huart1, rx_buf, size);
- 触发条件:缓冲区半满、全满时分别触发 HT / TC 事件。可配合__HAL_DMA_ENABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
- 回调 :
HAL_UART_RxHalfCpltCallback()、HAL_UART_RxCpltCallback()。 - 适用:高速连续数据流,避免缓冲区被覆盖。
- 局限:不能直接判断"一帧结束",通常还要配合超时或协议解析。
- Circular 模式是 DMA 写满缓冲区后从之前索引位置继续写,所以启动一次就够了。实测重新启动也不会从usart3_rx_dma_buf0的位置续写。
HAL_UART_Receive_DMA
DMA + 空闲中断(不定长)
c
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rx_buf, size);
- 触发条件 :收满
size字节,或 RX 线出现空闲。 - 回调 :
HAL_UARTEx_RxEventCallback(huart, Size),Size是实际接收长度。 - 适用:Modbus RTU、AT 指令、传感器不定长上报。
- 注意 :回调里处理完数据后必须重新调用
HAL_UARTEx_ReceiveToIdle_DMA,否则下一帧收不到;DMA 模式通常用Normal即可。
中断控制语句
__HAL_DMA_DISABLE_IT
__HAL_DMA_DISABLE_IT宏用来关闭指定 DMA 通道的某些中断源。 参数含义:
| 参数 | 含义 |
|---|---|
__HANDLE__ |
DMA 句柄指针,例如 &hdma_usart1_rx |
__INTERRUPT__ |
要禁用的 DMA 中断源,可组合使用,DMA_IT_TC:传输完成中断,DMA_IT_HT半传输完成中断,DMA_IT_TE:传输错误中断 |
-
使用示例
-
如果不想让 DMA 接收触发半传输中断,可以写:__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
-
如果要同时关闭传输完成和传输错误中断:__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_TC | DMA_IT_TE);
-
-
注意事项
- 它只关闭 DMA 通道自身的中断使能位 ,不等于关闭 NVIC 中断通道。如果 NVIC 里已经使能了该 DMA 中断,必要时还要配合
HAL_NVIC_DisableIRQ()。 - 它和
__HAL_DMA_DISABLE()不同:__HAL_DMA_DISABLE()是关闭 DMA 通道本身,即清除CCR的EN位;而__HAL_DMA_DISABLE_IT()只是关闭中断。 - 在 CubeMX 生成的 HAL 工程里,DMA 初始化后如果想屏蔽某些不必要的 DMA 中断,就可以用这个宏。
- 它只关闭 DMA 通道自身的中断使能位 ,不等于关闭 NVIC 中断通道。如果 NVIC 里已经使能了该 DMA 中断,必要时还要配合
__HAL_DMA_ENABLE_IT
- 同理