头文件

/**
  ******************************************************************************
  * @file           : usart_driver.hpp
  * @brief          : usart_driver program head
  ******************************************************************************
  * @attention
  ******************************************************************************
  */
#ifndef __USART_DRIVER_H
#define __USART_DRIVER_H

#ifdef __cplusplus
extern "C" {
#endif
#include "string.h"
#include "stdint.h"
#include "stm32f4xx_hal.h"
#include "main.h"     
#ifdef __cplusplus
}
#endif

#define UART_BUFFSIZE 32

typedef struct
{
    uint8_t  flag;               
    uint8_t  data[UART_BUFFSIZE];
    uint16_t index;              
}UartMsg;
//uart hardwere class
class Serial {
public:
    Serial(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_rx, DMA_HandleTypeDef *hdma_tx, uint32_t baud_rate, uint32_t nvic_priority)
        : huart(huart), hdma_rx(hdma_rx), hdma_tx(hdma_tx), baud_rate(baud_rate), nvic_priority(nvic_priority) {}
            
    UART_HandleTypeDef *huart;
    DMA_HandleTypeDef *hdma_rx;
    DMA_HandleTypeDef *hdma_tx;
            
    uint8_t SerialInitialize(USART_TypeDef *UARTx);
    uint8_t SendData(const uint8_t* data, size_t size);
    void RecvDataProcess(const void* data, size_t len);
    void RecvDataCheck(); // 在中断中调用以接收数据
            
private:
    const uint32_t baud_rate;
    const uint32_t nvic_priority;

    UartMsg recv_message;

    uint8_t InitializeGPIO();
    uint8_t InitializeDMA();
    uint8_t InitializeNVIC();

    Serial(const Serial&) = delete;
    Serial& operator=(const Serial&) = delete;
};



#endif

源文件


/**
  * @brief GPIO 初始化
  * @retval
  */
uint8_t Serial::InitializeGPIO(){
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    
    if(this->huart->Instance==UART4){
        __HAL_RCC_UART4_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**UART4 GPIO Configuration
        PA0-WKUP     ------> UART4_TX
        PA1     ------> UART4_RX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
        GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }else if(this->huart->Instance==UART5){
        /* UART5 clock enable */
        __HAL_RCC_UART5_CLK_ENABLE();
        __HAL_RCC_GPIOC_CLK_ENABLE();
        __HAL_RCC_GPIOD_CLK_ENABLE();
        /**UART5 GPIO Configuration
        PC12     ------> UART5_TX
        PD2     ------> UART5_RX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_12;
        GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

        GPIO_InitStruct.Pin = GPIO_PIN_2;
        GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
        HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    }else if(this->huart->Instance==USART1){
        /* USART1 clock enable */
        __HAL_RCC_USART1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**USART1 GPIO Configuration
        PA9     ------> USART1_TX
        PA10     ------> USART1_RX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);     
    }else if(this->huart->Instance==USART2){
        /* USART2 clock enable */
        __HAL_RCC_USART2_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**USART2 GPIO Configuration
        PA2     ------> USART2_TX
        PA3     ------> USART2_RX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }else if(this->huart->Instance==USART3){
        /* USART3 clock enable */
        __HAL_RCC_USART3_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();
        /**USART3 GPIO Configuration
        PB10     ------> USART3_TX
        PB11     ------> USART3_RX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }else if(this->huart->Instance==USART6){
        /* USART6 clock enable */
        __HAL_RCC_USART6_CLK_ENABLE();
        __HAL_RCC_GPIOC_CLK_ENABLE();
        /**USART6 GPIO Configuration
        PC6     ------> USART6_TX
        PC7     ------> USART6_RX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
        GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    }else{
        return 1;
    }
    return 0;
}
/**
  * @brief DMA 初始化
  * @retval
  */
uint8_t Serial::InitializeDMA() {
    DMA_HandleTypeDef *hdma_rx = this->hdma_rx;
    DMA_HandleTypeDef *hdma_tx = this->hdma_tx;

    this->hdma_rx->Init.Channel = DMA_CHANNEL_4;
    this->hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY;
    this->hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE;
    this->hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
    this->hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    this->hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    this->hdma_rx->Init.Mode = DMA_NORMAL;
    this->hdma_rx->Init.Priority = DMA_PRIORITY_LOW;
    this->hdma_rx->Init.FIFOMode = DMA_FIFOMODE_DISABLE;

    this->hdma_tx->Init.Channel = DMA_CHANNEL_4;
    this->hdma_tx->Init.Direction = DMA_MEMORY_TO_PERIPH;
    this->hdma_tx->Init.PeriphInc = DMA_PINC_DISABLE;
    this->hdma_tx->Init.MemInc = DMA_MINC_ENABLE;
    this->hdma_tx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    this->hdma_tx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    this->hdma_tx->Init.Mode = DMA_NORMAL;
    this->hdma_tx->Init.Priority = DMA_PRIORITY_LOW;
    this->hdma_tx->Init.FIFOMode = DMA_FIFOMODE_DISABLE;

    if (this->huart->Instance == USART1) {
        hdma_rx->Instance = DMA2_Stream2;
        hdma_tx->Instance = DMA2_Stream7;
    } else if (this->huart->Instance == USART2) {
        hdma_rx->Instance = DMA1_Stream5;
        hdma_tx->Instance = DMA1_Stream6;
    } else if (this->huart->Instance == USART3) {
        hdma_rx->Instance = DMA1_Stream1;
        hdma_tx->Instance = DMA1_Stream3;
    } else if (this->huart->Instance == UART4) {
        hdma_rx->Instance = DMA1_Stream2;
        hdma_tx->Instance = DMA1_Stream4;
    } else if (this->huart->Instance == UART5) {
        hdma_rx->Instance = DMA1_Stream0;
        hdma_tx->Instance = DMA1_Stream7;
    } else if (this->huart->Instance == USART6) {
        hdma_rx->Instance = DMA2_Stream1;
        hdma_tx->Instance = DMA2_Stream6;
    } else {
        return 1; 
    }

    if (HAL_DMA_Init(hdma_rx) != HAL_OK || HAL_DMA_Init(hdma_tx) != HAL_OK) {
        Error_Handler();
        return 1;
    }

    __HAL_LINKDMA(this->huart, hdmarx, *hdma_rx);
    __HAL_LINKDMA(this->huart, hdmatx, *hdma_tx);

    return 0;
}
/**
  * @brief NVIC初始化
  * @retval
  */
uint8_t Serial::InitializeNVIC() {
    IRQn_Type irqn;

    if (this->huart->Instance == USART1) {
        irqn = USART1_IRQn;
    } else if (this->huart->Instance == USART2) {
        irqn = USART2_IRQn;
    } else if (this->huart->Instance == USART3) {
        irqn = USART3_IRQn;
    } else if (this->huart->Instance == UART4) {
        irqn = UART4_IRQn;
    } else if (this->huart->Instance == UART5) {
        irqn = UART5_IRQn;
    } else if (this->huart->Instance == USART6) {
        irqn = USART6_IRQn;
    } else {
        Error_Handler();
        return 1; 
    }
    HAL_NVIC_SetPriority(irqn, this->nvic_priority, 0);
    HAL_NVIC_EnableIRQ(irqn);

    __HAL_UART_ENABLE_IT(this->huart, UART_IT_IDLE);
    __HAL_DMA_ENABLE_IT(this->hdma_rx, DMA_IT_HT);
    __HAL_DMA_ENABLE_IT(this->hdma_rx, DMA_IT_TC);
    return 0;
}
/**
  * @brief 串口初始化
  * @retval
  */
uint8_t Serial::SerialInitialize(USART_TypeDef *UARTx){
    this->huart->Instance = UARTx;
    this->huart->Init.BaudRate = baud_rate;
    this->huart->Init.WordLength = UART_WORDLENGTH_8B;
    this->huart->Init.StopBits = UART_STOPBITS_1;
    this->huart->Init.Parity = UART_PARITY_NONE;
    this->huart->Init.Mode = UART_MODE_TX_RX;
    this->huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
    this->huart->Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(this->huart) != HAL_OK){
        Error_Handler();
    }  
    if(this->InitializeGPIO() != HAL_OK){
        Error_Handler();
    }  
    if(this->InitializeDMA() != HAL_OK){
        Error_Handler();
    }
    if(this->InitializeNVIC() != HAL_OK ){
        Error_Handler();
    }
    return 0;
}
/**
  * @brief 数据发送
  * @retval
  */
uint8_t Serial::SendData(const uint8_t* data, size_t size){
    if(HAL_UART_Transmit_DMA(this->huart,data,size) != HAL_OK)
        return 1;
    return 0;
}

使用

extern DMA_HandleTypeDef hdma_uart5_rx;
extern DMA_HandleTypeDef hdma_uart5_tx;
Serial serial5(&huart5,&hdma_uart5_rx,&hdma_uart5_tx,115200,0);
/**
  * @brief 给C调用的入口函数
  * @retval 
  */
uint8_t test[4] = {0x00,0x01,0x02,0x04};
void UserAppMain(void){
    UserTask user_task; //实例化用户线程
    
    serial5.SerialInitialize(UART5);
    serial5.SendData(test,4);
    HAL_Delay(1);
    serial5.SendData(test,4);
    HAL_Delay(1);
    serial5.SendData(test,4);
    HAL_Delay(1);
    serial5.SendData(test,4);
    HAL_Delay(1);
    serial5.SendData(test,4);
12-03 14:26