HAL库——UART的DMA接收

一:USART协议基础

USART:Universal Synchronous/Asynchronous Receiver/Transmitter,通用同步/异步收发器。

  • 可配置成同步或者异步通信的方式,通常使用异步方式
  • 全双工通信
  • 独立的高精度波特率发生器,不占用定时/计数器
  • 数据帧包括:起始位、数据段、校验位、停止位
  • 在STM32中,挂载在APB2时钟上
  • 可以通过轮询、中断、DMA的方式发送和接收数据

 

二:DMA基础 

DMA:Direct Memory Access,直接内存存取。顾名思义,就是数据不需要经过MCU,直接在外设和内存之间实现存取,由DMA控制器自动实现,不占用MCU资源。

  • 两个DMA控制器总共由16个数据流
  • 每个数据流总共可以有多达 8 个通道(或称请求)
  • DMA请求可以配置不同的优先级,
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是基于 STM32 HAL 库的 UART2 DMA 初始化代码示例: ```c /* 定义 UART2 接收缓冲区大小 */ #define UART2_RX_BUF_SIZE 64 /* 定义 DMA 缓冲区大小 */ #define DMA_BUF_SIZE 128 /* 定义 UART2 句柄和 DMA 句柄 */ UART_HandleTypeDef huart2; DMA_HandleTypeDef hdma_usart2_rx; /* 定义 UART2 接收缓冲区和 DMA 缓冲区 */ uint8_t uart2_rx_buf[UART2_RX_BUF_SIZE]; uint8_t dma_rx_buf[DMA_BUF_SIZE]; void UART2_DMA_Init(void) { /* 使能 DMA 时钟 */ __HAL_RCC_DMA1_CLK_ENABLE(); /* 配置 DMA 句柄 */ hdma_usart2_rx.Instance = DMA1_Channel6; hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart2_rx.Init.Mode = DMA_CIRCULAR; hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH; hdma_usart2_rx.Init.Request = DMA_REQUEST_2; if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK) { /* 初始化 DMA 失败 */ Error_Handler(); } /* 关联 DMA 句柄到 UART2 */ __HAL_LINKDMA(&huart2, hdmarx, hdma_usart2_rx); /* 使能 UART2 时钟 */ __HAL_RCC_USART2_CLK_ENABLE(); /* 配置 UART2 */ huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { /* 初始化 UART2 失败 */ Error_Handler(); } /* 开启 UART2 接收 DMA */ HAL_UART_Receive_DMA(&huart2, dma_rx_buf, DMA_BUF_SIZE); } /* UART2 接收 DMA 中断回调函数 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* 处理接收到的数据 */ // ... } /* DMA 传输错误中断回调函数 */ void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { /* 处理 DMA 错误 */ // ... } ``` 在上述代码中,我们首先定义了 UART2 接收缓冲区大小和 DMA 缓冲区大小,然后定义了 UART2 句柄和 DMA 句柄以及这两个缓冲区。接着在 `UART2_DMA_Init()` 函数中,我们首先使能 DMA 时钟,并配置 DMA 句柄。然后我们将 DMA 句柄关联到 UART2 句柄上,并使能 UART2 时钟,最后配置 UART2 句柄。最后,我们通过调用 `HAL_UART_Receive_DMA()` 函数开启 UART2 接收 DMA。在 DMA 传输完成后,`HAL_UART_RxCpltCallback()` 函数会被调用,我们可以在这个回调函数中处理接收到的数据。如果 DMA 传输出现错误,`HAL_UART_ErrorCallback()` 函数会被调用。需要注意的是,这里的 DMA 模式是循环模式,即 DMA 缓冲区满后会自动重新从缓冲区头开始填充,因此我们需要在处理数据时注意判断 DMA 缓冲区指针的位置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值