stm32 h5 串口采用DMA循环BUFF接收数据

当使用STM32H5系列的MCU进行串口(USART)通信,并希望使用DMA(Direct Memory Access)进行循环缓冲区(Circular Buffer)接收数据时,你需要进行以下配置步骤:

  1. 初始化串口(USART)

    • 设置串口波特率、数据位、停止位和校验位。
    • 使能串口接收中断(虽然DMA传输不需要CPU中断处理,但可能需要中断来检测DMA传输完成或其他状态)。
    • 配置串口DMA接收。
  2. 配置DMA

    • 初始化DMA句柄。
    • 设置DMA通道,对于USART通常是固定的(比如USART1_RX通常使用DMA2的某个通道)。
    • 设置DMA传输方向为内存到内存(实际上是从USART接收数据到内存),但这是DMA的一种抽象,实际上是从外设(USART)到内存。
    • 配置DMA为循环模式(Circular Mode),这样当缓冲区满时,DMA会自动回到缓冲区的起始地址继续接收数据。
    • 设置DMA优先级和其他相关参数。
  3. 配置循环缓冲区

    • 定义一个循环缓冲区结构体,包含起始地址、大小、读/写指针等。
    • 初始化循环缓冲区。
  4. 启动DMA传输

    • 启动DMA传输,将USART接收的数据传输到循环缓冲区。
// 假设你已经定义了循环缓冲区的结构体和变量  
typedef struct {  
    uint8_t *buffer;  
    uint16_t size;  
    volatile uint16_t head; // 读指针  
    volatile uint16_t tail; // 写指针  
    // ... 其他可能的成员变量  
} CircularBuffer_t;  
  
CircularBuffer_t rxBuffer = { /* 初始化缓冲区 */ };  
  
// USART和DMA的初始化函数  
void USART_DMA_Init(void) {  
    // 1. 初始化USART(配置GPIO、波特率、数据格式等)  
    MX_USART_UART_Init(); // 假设你有一个这样的函数来初始化USART  
  
    // 2. 初始化DMA  
    // 假设你使用HAL库,并且USART1的RX DMA通道是DMA2的某个通道  
    // 这里只是伪代码,你需要根据STM32H5的参考手册和HAL库文档来配置DMA  
    DMA_HandleTypeDef hdma_usart1_rx;  
    hdma_usart1_rx.Instance = DMA2_ChannelX; // X是USART1 RX对应的DMA通道号  
    hdma_usart1_rx.Init.Direction = DMA_MEMORY_TO_MEMORY; // 实际上是从USART到内存  
    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_LOW;  
    hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;  
    // ... 其他配置  
    HAL_DMA_Init(&hdma_usart1_rx);  
  
    // 将DMA与USART关联起来  
    __HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx); // huart1是USART句柄  
  
    // 配置USART的DMA接收  
    HAL_UART_Receive_DMA(&huart1, rxBuffer.buffer, rxBuffer.size);  
  
    // 3. 启动DMA传输(这一步通常在HAL_UART_Receive_DMA中完成)  
    // HAL_DMA_Start_IT(&hdma_usart1_rx, (uint32_t)&huart1.Instance->DR, (uint32_t)rxBuffer.buffer, rxBuffer.size);  
  
    // ... 其他可能的配置和使能中断等  
}  
  
// ... 其他处理函数,如中断服务例程(ISR)来处理DMA完成或其他事件

以下是一个详细的配置实例,结合了参考文章中的信息并进行了适当的调整和补充:

1. STM32CubeMX配置

  1. 选择单片机型号:在STM32CubeMX中选择你使用的STM32H5系列单片机型号。

  2. 配置时钟:设置适当的系统时钟。

  3. 配置USART

    • 选择USART通道(例如USART1)。
    • 配置波特率、数据位、停止位和校验位。
    • 启用USART接收(RX)功能,并设置为循环模式(如果有这个选项)。
    • 关联USART的RX引脚到对应的GPIO引脚。
  4. 配置DMA

    • 在DMA配置中选择与USART RX关联的DMA通道(例如DMA2的某个通道)。
    • 设置DMA传输方向为从外设(USART)到内存。
    • 设置DMA模式为循环模式(Circular Mode)。
    • 设置数据宽度、优先级和其他相关参数。
UART_HandleTypeDef huart1; // 假设使用USART1  
  
void MX_USART_UART_Init(void)  
{  
    // 初始化USART结构体  
    huart1.Instance = USART1;  
    huart1.Init.BaudRate = 115200; // 波特率  
    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)  
    {  
        // 初始化错误处理  
    }  
}
DMA_HandleTypeDef hdma_usart1_rx;  
  
void MX_DMA_Init(void)  
{  
    __HAL_RCC_DMA2_CLK_ENABLE(); // 使能DMA2时钟  
  
    hdma_usart1_rx.Instance = DMA2_ChannelX; // 替换X为USART1 RX对应的DMA通道号  
    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_LOW; // 优先级  
    hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; // FIFO模式禁用  
    hdma_usart1_rx.Init.MemBurst = DMA_MBURST_INC4; // 存储器突发传输  
    hdma_usart1_rx.Init.PeriphBurst = DMA_PBURST_SINGLE; // 外设突发传输  
    if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)  
    {  
        // DMA初始化错误处理  
    }  
  
    // 关联USART和DMA  
    __HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);  
  
    // 配置USART的DMA接收  
    HAL_UART_Receive_DMA(&huart1, rxBuffer, BUFFER_SIZE); // 假设rxBuffer是已定义的接收缓冲区,BUFFER_SIZE是缓冲区大小  
}

相关推荐

  1. stm32 h5 串口采用DMA循环BUFF接收数据

    2024-06-07 13:38:08       26 阅读
  2. STM32F1 DMA串口接收数据

    2024-06-07 13:38:08       63 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 13:38:08       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 13:38:08       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 13:38:08       87 阅读
  4. Python语言-面向对象

    2024-06-07 13:38:08       96 阅读

热门阅读

  1. 用 Sentence Transformers v3 训练和微调嵌入模型

    2024-06-07 13:38:08       24 阅读
  2. 解决跨域问题

    2024-06-07 13:38:08       29 阅读
  3. 供应链管理是什么?能解决什么问题?

    2024-06-07 13:38:08       28 阅读
  4. 分布式防止重复请求或者高并发防止重复提交

    2024-06-07 13:38:08       21 阅读
  5. Flutter与iOS原生混合开发 iOS项目集成Flutter

    2024-06-07 13:38:08       36 阅读
  6. KNN算法实例_电影类型判断

    2024-06-07 13:38:08       32 阅读
  7. C++中为什么尽量使用using 代替 typedef

    2024-06-07 13:38:08       29 阅读
  8. Vue 组件之间的通信

    2024-06-07 13:38:08       34 阅读
  9. 连续分配存储管理方式

    2024-06-07 13:38:08       22 阅读
  10. C++实现图像的模拟运动模糊

    2024-06-07 13:38:08       24 阅读
  11. 1103. 分糖果 II

    2024-06-07 13:38:08       27 阅读
  12. 力扣每日一题 6/7

    2024-06-07 13:38:08       35 阅读
  13. input 输入框只能输入数字的处理方式

    2024-06-07 13:38:08       26 阅读