HAL库DMA不定长接收
时间: 2025-02-06 20:45:47 浏览: 59
### 使用HAL库通过DMA实现串口不定长接收
为了在STM32 HAL库中利用DMA实现串口中断方式下的不定长数据接收,需遵循特定的配置流程。这不仅涉及硬件资源初始化,还包括软件层面逻辑处理的设计。
#### 配置过程概述
- **定义缓冲区**:创建用于存储接收到的数据的数组`receive_buff[]`[^1]。
- **使能UART空闲线中断**:调用宏`__HAL_UART_ENABLE_IT()`启用UART的IDLE(空闲检测)中断功能,以便当检测到线路处于空闲状态时触发相应的回调函数。
- **启动DMA传输**:借助API `HAL_UART_Receive_DMA()`开启基于DMA机制的数据流输入操作,参数指定了目标缓存地址以及最大预期接收量。
```c
// 定义全局变量作为接收缓冲区
uint8_t receive_buff[RECEIVE_BUFFER_SIZE];
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void){
/* 初始化所有外设 */
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
// 启动USART IDLE中断
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
// 开始DMA接收
HAL_UART_Receive_DMA(&huart1, (uint8_t *)receive_buff, RECEIVE_BUFFER_SIZE);
while (1){}
}
```
#### 关键点解析
- 当发生空闲事件时,会进入对应的ISR(Interrupt Service Routine),此时应立即停止当前正在进行中的DMA活动以防止后续新到来的信息覆盖原有未处理完毕的消息片段[^2]。
- 对于带有Cache特性的MCU型号如STM32F7系列,在访问由DMA写入RAM内的数据之前务必确保已经禁用了相关通道上的DMA工作,从而避免因高速缓存一致性问题而导致读取错误的结果。
#### 处理空闲中断的服务例程
下面给出了一段简化版的例子来展示如何编写一个有效的空闲中断服务程序:
```c
extern "C" {
#include "stm32fxxx_hal.h"
}
/* 接收完成标志位 */
volatile uint8_t rx_done_flag = RESET;
void USART1_IRQHandler(void){
if (__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){
// 清除IDLE标志并暂停DMA
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_DMAStop(&huart1);
// 获取实际接收到的有效字节数目
size_t received_length = huart1.hdmarx->Instance->NDTR;
// 更新有效数据范围
memset(receive_buff + (RECEIVE_BUFFER_SIZE - received_length), '\0', received_length);
// 设置接收完成标记
rx_done_flag = SET;
}
}
```
阅读全文
相关推荐


















