串口USART通信可以支持我们使用一些扩展设备,如陀螺仪、遥控器、裁判系统等等
usart.h和usart.cpp文件的使用
usart.h
#pragma once
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_uart.h"
#define UART_MAX_LEN 100
class UART
{
public:
UART& Init(USART_TypeDef* Instance, uint32_t BaudRate);
UART& DMATxInit(void);
UART& DMARxInit(const uint8_t *buffer = nullptr,const uint32_t size = UART_MAX_LEN);
void DMATransmit(uint8_t* pData, uint32_t Size) const;
void OnUARTITHandler(uint16_t Size);
void OnDMAITHandler(void) const;
void RxIdleItCallback(uint16_t rxSize) const;
void UARTTransmit(uint8_t* pData, uint32_t Size);
static void DMAClearAllFlags(DMA_HandleTypeDef *dmax)
{
const auto ele = reinterpret_cast<uint32_t>(dmax->Instance);
(ele == reinterpret_cast<uint32_t>DMA1_Stream0) ? (DMA1->LIFCR = 0x0000003D) :\
(ele == reinterpret_cast<uint32_t>DMA1_Stream1) ? (DMA1->LIFCR = 0x00000F40) :\
(ele == reinterpret_cast<uint32_t>DMA1_Stream2) ? (DMA1->LIFCR = 0x003D0000) :\
(ele == reinterpret_cast<uint32_t>DMA1_Stream3) ? (DMA1->LIFCR = 0x0F400000) :\
(ele == reinterpret_cast<uint32_t>DMA1_Stream4) ? (DMA1->HIFCR = 0x0000003D) :\
(ele == reinterpret_cast<uint32_t>DMA1_Stream5) ? (DMA1->HIFCR = 0x00000F40) :\
(ele == reinterpret_cast<uint32_t>DMA1_Stream6) ? (DMA1->HIFCR = 0x003D0000) :\
(ele == reinterpret_cast<uint32_t>DMA1_Stream7) ? (DMA1->HIFCR = 0x0F400000) :\
(ele == reinterpret_cast<uint32_t>DMA2_Stream0) ? (DMA2->LIFCR = 0x0000003D) :\
(ele == reinterpret_cast<uint32_t>DMA2_Stream1) ? (DMA2->LIFCR = 0x00000F40) :\
(ele == reinterpret_cast<uint32_t>DMA2_Stream2) ? (DMA2->LIFCR = 0x003D0000) :\
(ele == reinterpret_cast<uint32_t>DMA2_Stream3) ? (DMA2->LIFCR = 0x0F400000) :\
(ele == reinterpret_cast<uint32_t>DMA2_Stream4) ? (DMA2->HIFCR = 0x0000003D) :\
(ele == reinterpret_cast<uint32_t>DMA2_Stream5) ? (DMA2->HIFCR = 0x00000F40) :\
(ele == reinterpret_cast<uint32_t>DMA2_Stream6) ? (DMA2->HIFCR = 0x003D0000) :\
(DMA2->HIFCR = 0x0F400000);
}
UART_HandleTypeDef huart;
uint8_t m_uartrx[UART_MAX_LEN];
};
extern UART uart1,uart2, uart4, uart6;// , uart6, uart7;
usart.cpp
#include "usart.h"
#include "RC.h"
#include "judgement.h"
UART& UART::Init(USART_TypeDef* Instance, const uint32_t BaudRate)
{
huart.Instance = Instance;
huart.Init.BaudRate = BaudRate;
huart.Init.WordLength = UART_WORDLENGTH_8B;
huart.Init.StopBits = UART_STOPBITS_1;
huart.Init.Parity = UART_PARITY_NONE;
huart.Init.Mode = UART_MODE_TX_RX;
huart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart);
return *this;
}
UART& UART::DMATxInit(void)
{
__HAL_DMA_DISABLE(huart.hdmatx);
huart.hdmatx->Instance->PAR = reinterpret_cast<uint32_t>(&huart.Instance->DR);
huart.hdmatx->Instance->M0AR = 0;
DMAClearAllFlags(huart.hdmatx);
//开启DMA发送中断
__HAL_DMA_ENABLE_IT(huart.hdmatx, DMA_IT_TC);
SET_BIT(huart.Instance->CR3, USART_CR3_DMAT);
return *this;
}
UART& UART::DMARxInit(const uint8_t *buffer, const uint32_t size)
{
//使能串口DMA接收
__HAL_DMA_DISABLE(huart.hdmarx);
huart.hdmarx->Instance->PAR = reinterpret_cast<uint32_t>(&huart.Instance->DR);//PAR is DMA stream x peripheral address register
huart.hdmarx->Instance->NDTR = size;
if (buffer == nullptr)buffer = m_uartrx;
huart.hdmarx->Instance->M0AR = reinterpret_cast<uint32_t>(buffer);
DMAClearAllFlags(huart.hdmarx);
__HAL_DMA_ENABLE(huart.hdmarx);
SET_BIT(huart.Instance->CR3, USART_CR3_DMAR);
//开启串口空闲中断
__HAL_UART_CLEAR_PEFLAG(&huart);
__HAL_UART_ENABLE_IT(&huart, UART_IT_IDLE);
return *this;
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if (uartHandle->Instance == USART1)
{
static DMA_HandleTypeDef hdma_rx;
static DMA_HandleTypeDef hdma_tx;
/* USART6 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART6 GPIO Configuration
PG14 ------> USART6_TX
PG9 ------> USART6_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART6 DMA Init */
__HAL_RCC_DMA2_CLK_ENABLE();
/* USART6_RX Init */
hdma_rx.Instance = DMA2_Stream2;
hdma_rx.Init.Channel = DMA_CHANNEL_4;
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode = DMA_NORMAL;
hdma_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_rx);
__HAL_LINKDMA(uartHandle, hdmarx, hdma_rx);
/* USART6_TX Init */
hdma_tx.Instance = DMA2_Stream7;
hdma_tx.Init.Channel = DMA_CHANNEL_4;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_tx);
__HAL_LINKDMA(uartHandle, hdmatx, hdma_tx);
/* USART6 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* DMA interrupt init */
/* DMA2_Stream1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
/* DMA2_Stream6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
}
if (uartHandle->Instance == USART2)
{
static DMA_HandleTypeDef hdma_rx;
static DMA_HandleTypeDef hdma_tx;
/* USART6 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART6 GPIO Configuration
PG14 ------> USART6_TX
PG9 ------> USART6_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART6 DMA Init */
__HAL_RCC_DMA1_CLK_ENABLE();
/* USART6_RX Init */
hdma_rx.Instance = DMA1_Stream5;
hdma_rx.Init.Channel = DMA_CHANNEL_4;
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode = DMA_NORMAL;
hdma_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_rx);
__HAL_LINKDMA(uartHandle, hdmarx, hdma_rx);
/* USART6_TX Init */
hdma_tx.Instance = DMA1_Stream6;
hdma_tx.Init.Channel = DMA_CHANNEL_4;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_tx);
__HAL_LINKDMA(uartHandle, hdmatx, hdma_tx);
/* USART6 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* DMA interrupt init */
/* DMA2_Stream1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* DMA2_Stream6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
}
if (uartHandle->Instance == UART4)
{
static DMA_HandleTypeDef hdma_rx;
static DMA_HandleTypeDef hdma_tx;
/* USART1 clock enable */
__HAL_RCC_UART4_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA0 ------> UART4_TX
PA1 ------> UART4_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 DMA Init */
__HAL_RCC_DMA1_CLK_ENABLE();
/* USART1_RX Init */
hdma_rx.Instance = DMA1_Stream2;
hdma_rx.Init.Channel = DMA_CHANNEL_4;
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode = DMA_NORMAL;
hdma_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_rx);
__HAL_LINKDMA(uartHandle, hdmarx, hdma_rx);
/* USART1_TX Init */
hdma_tx.Instance = DMA1_Stream4;
hdma_tx.Init.Channel = DMA_CHANNEL_4;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_tx);
__HAL_LINKDMA(uartHandle, hdmatx, hdma_tx);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(UART4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(UART4_IRQn);
/* DMA interrupt init */
/* DMA2_Stream2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
/* DMA2_Stream7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
}
if (uartHandle->Instance == USART6)
{
static DMA_HandleTypeDef hdma_rx;
static DMA_HandleTypeDef hdma_tx;
/* USART1 clock enable */
__HAL_RCC_USART6_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**USART1 GPIO Configuration
PC6 ------> USART6_TX
PC7 ------> USART6_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USART6 DMA Init */
__HAL_RCC_DMA2_CLK_ENABLE();
/* USART6_RX Init */
hdma_rx.Instance = DMA2_Stream1;
hdma_rx.Init.Channel = DMA_CHANNEL_5;
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode = DMA_NORMAL;
hdma_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_rx);
__HAL_LINKDMA(uartHandle, hdmarx, hdma_rx);
/* USART6_TX Init */
hdma_tx.Instance = DMA2_Stream6;
hdma_tx.Init.Channel = DMA_CHANNEL_5;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_tx);
__HAL_LINKDMA(uartHandle, hdmatx, hdma_tx);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART6_IRQn);
/* DMA interrupt init */
/* DMA2_Stream2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
/* DMA2_Stream7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
}
}
void UART::RxIdleItCallback(const uint16_t rxSize) const
{
if (huart.Instance == USART1)
{
if (nuc.rxData[0] == 'w'&&nuc.rxData[1] == 'h'&&nuc.rxData[2] == 'i'&&nuc.rxData[3] == 'c'&&nuc.rxData[4] == 'h')
{
if (judgement.ready == true)
{
uint8_t red[2] = "R";
uint8_t blue[2] = "B";
if (judgement.data.ext_game_robot_status_t.robot_id < 10)
{
uart1.UARTTransmit(red, 1);
}
else
{
uart1.UARTTransmit(blue, 1);
}
}
}
else
nuc.OnIRQHandler(rxSize);
}
if (huart.Instance == USART2)
{
rc.OnIRQHandler(rxSize);
}
if (huart.Instance == UART4)
{
imu.OnIRQHandler(rxSize);
}
if (huart.Instance == USART6)
{
judgement.OnIRQHandler(rxSize);
}
}
void UART::OnUARTITHandler(const uint16_t Size = UART_MAX_LEN)
{
if (__HAL_UART_GET_FLAG(&huart, UART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(&huart, UART_IT_IDLE))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart);
__HAL_DMA_DISABLE(huart.hdmarx);
DMAClearAllFlags(huart.hdmarx);
RxIdleItCallback(Size - __HAL_DMA_GET_COUNTER(huart.hdmarx));
__HAL_DMA_SET_COUNTER(huart.hdmarx, Size);
__HAL_DMA_ENABLE(huart.hdmarx);
}
HAL_UART_IRQHandler(&huart);
}
void UART::OnDMAITHandler(void) const
{
UART::DMAClearAllFlags(huart.hdmatx);
__HAL_DMA_DISABLE(huart.hdmatx);
}
extern "C" void USART1_IRQHandler(void)
{
uart1.OnUARTITHandler();
}
extern "C" void USART2_IRQHandler(void)
{
uart2.OnUARTITHandler();
}
//extern "C" void USART6_IRQHandler(void)
//{
// uart6.OnUARTITHandler();
//}
extern "C" void UART4_IRQHandler(void)
{
uart4.OnUARTITHandler();
}
extern "C" void USART6_IRQHandler(void)//Question
{
uart6.OnUARTITHandler();
}
extern "C" void DMA1_Stream2_IRQHandler(void)
{
}
extern "C" void DMA1_Stream4_IRQHandler(void)
{
uart4.OnDMAITHandler();
}
extern "C" void DMA2_Stream6_IRQHandler(void)
{
uart6.OnDMAITHandler();
}
void UART::DMATransmit(uint8_t*const pData, const uint32_t Size) const
{
__HAL_DMA_DISABLE(huart.hdmatx);
huart.hdmatx->Instance->NDTR = Size;
huart.hdmatx->Instance->M0AR = reinterpret_cast<uint32_t>(pData);
DMAClearAllFlags(huart.hdmatx);
__HAL_DMA_ENABLE(huart.hdmatx);
}
void UART::UARTTransmit(uint8_t* pData, uint32_t Size)
{
HAL_UART_Transmit(&huart, static_cast<uint8_t*>(pData), Size, 0xffff);
}
extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
}
将我们的项目文件添加如上两个文件,文件中包括USART通信的收发方式,可以更方便我们使用USART通信来进行扩展模块代码的编写。