HAL库串口DMA收发
时间: 2025-01-25 10:47:34 浏览: 43
### 使用 HAL 库实现 STM32 串口 DMA 收发
#### 初始化配置
为了使用 HAL 库中的 UART 和 DMA 功能,初始化设置至关重要。这通常涉及硬件资源的分配以及中断优先级的设定。
```c
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_DMA_Init(void)
{
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_usart1_rx.Instance = DMA1_Channel5;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);
}
```
上述代码展示了如何初始化 `USART1` 及其对应的 DMA 接收通道[^1]。
#### 开启 DMA 接收功能
一旦完成了必要的初始化工作之后,在应用程序逻辑里可以调用如下函数来启动基于 DMA 的异步接收过程:
```c
uint8_t Rx_Buf[RECEIVE_BUFFER_SIZE];
uint16_t Rx_Len = 0;
uint8_t Rx_Flag = 0;
if(HAL_UART_Receive_DMA(&huart1, Rx_Buf, RECEIVE_BUFFER_SIZE) != HAL_OK){
// 错误处理...
}
```
这段程序片段说明了怎样利用 `HAL_UART_Receive_DMA()` 函数配合指定缓冲区执行非阻塞式的 DMA 数据采集操作。
#### 处理接收到的数据
当检测到空闲线(IDLE line)事件发生时(意味着一帧完整的数据已被发送完毕),可以在相应的中断服务例程(ISR)内完成进一步的操作:
```c
extern "C" void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))
{
/* 清除IDLE标志位 */
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
/* 停止DMA接收 */
HAL_UART_DMAStop(&huart1);
/* 计算实际接收到的有效字节数 */
uint32_t temp = __HAL_DMA_GET_COUNTER(hdma_usart1_rx);
Rx_Len = sizeof(Rx_Buf)-temp;
/* 设置接收完成标记 */
Rx_Flag = 1;
/* 继续下一轮DMA接收 */
HAL_UART_Receive_DMA(&huart1,Rx_Buf,sizeof(Rx_Buf));
}
}
```
此部分解释了在遇到 IDLE 中断的情况下应采取哪些措施以确保正确解析所获取的信息并准备新一轮的数据捕获活动[^2]。
阅读全文
相关推荐


















