HAL库——UART的DMA发送(对比接收)

本文详细介绍了STM32使用HAL库进行UART的DMA发送过程,对比了发送和接收的区别。在启动发送后,当DMA发送完成,会触发中断。在normal模式下,会进入UART中断请求,调用特定的中断处理函数;而在circular模式下,处理方式与接收类似,直接调用发送完成回调。文章强调理解不同工作模式下的回调函数和中断处理机制的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面讲到的UART接收执行过程:

  • 启动UART的DMA接收(这里面还定义了DMA回调函数):HAL_UART_Receive_DMA
  • 接收完成后,请求DMA中断(判断中断的类型):HAL_DMA_IRQHandler
  • 调用DMA接收完成回调函数(同时关闭了DMA接收):UART_DMAReceiveCplt
  • 调用UART接收回调函数(处理数据,启动DMA接收):HAL_UART_RxCpltCallback

 UART的DMA发送和接收的过程类似,部分细节不同,DMA的发送执行过程如下:

  • 启动UART的DMA发送(其中定义了发送的回调函数):HAL_UART_Transmit_DMA
  • 发送完成,请求DMA中断(判断中断的类型):HAL_DMA_IRQHandler
  • 调用DMA发送完成回调函数:UART_DMATransmitCplt

到这一步还是一样的,执行到 UART_DMATransmitCplt里面时,开始不一样了。看一下UART_DMATransmitCplt说了啥:

static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
  UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
  /* DMA Normal mode*/                                //看这里1
  if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
  {
    huart->TxXferCount = 0x00U;

    /* Disable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

    /* Enable the UART Transmit Complete Interrupt */
    SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);

  }
  /* DMA Circular mode */                             //看这里2
  else
  {
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
    /*Call registered Tx complete callback*/
    huart->TxCpltCallback(huart);
#else
    /*Call legacy weak Tx complete callback*/
    HAL_UART_TxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
  }
}

程序不长,看着好像和UART_DMAReceiveCplt没啥区别,不过还是不一样的,说明如下:

  • DMA发送的回调函数处理需要区分DMA传输的模式(即区分normal和circul
### HALUARTDMA结合使用教程 #### 初始化配置 为了使STM32微控制器能够通过UART接口利用DMA传输数据,在`main.c`文件中的初始化部分需调用特定函数来设置DMA接收模式。具体来说,创建了一个名为`hdmarx`的结构体变量用于保存UART接收DMA句柄参数[^1]。 ```c // 定义全局缓冲区数组以及大小常量 #define BUFF_SIZE 64 uint8_t rx_buffer[BUFF_SIZE]; ``` 在主程序初始化阶段,除了常规外设初始化之外,还需要特别加入如下两行代码以确保串口可以正常工作并响应中断请求: ```c HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rx_buffer, BUFF_SIZE); __HAL_DMA_DISABLE_IT((&hdma_usart1_rx), DMA_IT_HT); ``` 上述操作分别实现了启用基于空闲检测机制下的异步DMA接收功能,并禁用了半满状态触发的中断事件,从而优化了系统的性能表现[^2]。 #### 数据处理逻辑 当接收到的数据填满了指定长度(`BUFF_SIZE`)之后,会自动触发一次完整的DMA传输完成中断。此时可以在相应的回调函数内对接收的数据进行进一步解析或存储等后续动作。下面是一个简单的例子展示如何定义这样的回调方法: ```c void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (Size > 0){ // 对接收到的数据做相应处理... // 继续监听新的消息到来 HAL_UARTEx_ReceiveToIdle_DMA(huart, rx_buffer, BUFF_SIZE); } } ``` 此段代码片段展示了在一个完整的DMA传输结束后应采取的动作——即先对已获取到的信息执行必要的业务流程;随后再次激活相同的DMA接收过程等待下一批次的数据到达。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值