头文件
/**
******************************************************************************
* @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);