分享一些项目上所运用串口收发代码
#define USART2_TX_MAX_SIZE 1024
#define USART2_RX_MAX_SIZE 1024
#define USART2_RX_MAX_TIME 5
#define USART2_TX_PIN GPIOD_USART2_TX /* GPIOD */
#define USART2_RX_PIN GPIOD_USART2_RX /* GPIOD */
#define DIRVER_USART2_INIT true /* 普通串口配置 */
#define DIRVER_USART2_DMA_CONFIG true /* DMA串口配置 */
unsigned char usart2_tx_buffer[USART2_TX_MAX_SIZE];
unsigned char usart2_rx_buffer[USART2_RX_MAX_SIZE];
unsigned short usart2_rx_size = 0;
unsigned char usart2_rx_time = 0;
bool usart2_rx_flag = false;
static void Usart2_GPIO_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);
GPIO_InitStructure.GPIO_Pin = USART2_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = USART2_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void Usart2_Init(uint32_t baudrate, uint16_t parity, uint16_t stopbits, uint16_t wordlength)
{
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
Usart2_GPIO_Init();
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_Parity = parity;
USART_InitStructure.USART_StopBits = stopbits;
USART_InitStructure.USART_WordLength = wordlength;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
#if DIRVER_USART2_DMA_CONFIG == true
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
#elif DIRVER_USART2_DMA_CONFIG == false
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
#endif
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
/* 注释的情况下,该中断采用默认配置的优先级 */
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART2, ENABLE);
}
static void Usart2_DMA_TX_Init()
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_DeInit(DMA1_Stream6);
while (DMA_GetCmdStatus(DMA1_Stream6) != DISABLE)
;
/* config usart2_tx_dma */
DMA_InitStructure.DMA_Channel = DMA_Channel_4; /* 当前所用外设所处通道 */
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /* 传输方向,当前为内存->外设 */
DMA_InitStructure.DMA_BufferSize = USART2_TX_MAX_SIZE; /* 数据长度 */
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR); /* 外设目标地址 */
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; /* 外设传输带宽,当前为字节 */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 当前地址是否自增,当前为否 */
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; /* 传输模式,单次或突发模式,当前为单次,突发模式需要FIFO支持缓冲区 */
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)usart2_tx_buffer; /* 源内存地址 */
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* 内存传输带宽,当前为字节 */
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 当前地址是否自增,当前为是 */
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /* 传输模式,单次或突发模式,当前为单次,突发模式需要FIFO支持缓冲区 */
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; /* FIFO模式是否使能,当前为否 */
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; /* FIFO阈值 */
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* DMA模式 */
DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* 中断优先级 */
DMA_Init(DMA1_Stream6, &DMA_InitStructure);
DMA_ITConfig(DMA1_Stream6, DMA_IT_TC, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn;
/* 注释的情况下,该中断采用默认配置的优先级 */
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Stream6, DISABLE);
}
static void Usart2_DMA_RX_Init()
{
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Stream5);
while (DMA_GetCmdStatus(DMA1_Stream5) != DISABLE)
;
/* config usart2_rx_dma */
DMA_InitStructure.DMA_Channel = DMA_Channel_4; /* 当前所用外设所处通道 */
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; /* 传输方向,当前为外设->内存 */
DMA_InitStructure.DMA_BufferSize = USART2_RX_MAX_SIZE; /* 数据长度 */
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR); /* 外设源地址 */
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; /* 外设传输带宽,当前为字节 */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 当前地址是否自增,当前为否 */
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; /* 传输模式,单次或突发模式,当前为单次,突发模式需要FIFO支持缓冲区 */
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)usart2_rx_buffer; /* 目标内存地址 */
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* 内存传输带宽,当前为字节 */
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 当前地址是否自增,当前为是 */
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /* 传输模式,单次或突发模式,当前为单次,突发模式需要FIFO支持缓冲区 */
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; /* FIFO模式是否使能,当前为否 */
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; /* FIFO阈值 */
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; /* DMA模式 */
DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* 中断优先级 */
DMA_Init(DMA1_Stream5, &DMA_InitStructure);
USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
DMA_Cmd(DMA1_Stream5, ENABLE);
}
void Usart2_DMA_Init(uint32_t baudrate, uint16_t parity, uint16_t stopbits, uint16_t wordlength)
{
Usart2_DMA_TX_Init();
Usart2_DMA_RX_Init();
Usart2_Init(baudrate, parity, stopbits, wordlength);
}
/* USART2 Rx Config */
static void Usart2_Rx_Config()
{
usart2_rx_time = USART2_RX_MAX_TIME;
usart2_rx_flag = true;
}
#if (DIRVER_USART2_DMA_CONFIG == false)
/* USART2 Normal Rx Config */
static void Usart2_Normal_Rx_Config()
{
if (usart2_rx_size >= USART2_RX_MAX_SIZE)
{
usart2_rx_size = USART2_RX_MAX_SIZE;
}
usart2_rx_buffer[usart2_rx_size++] = USART_ReceiveData(USART2);
Usart2_Rx_Config();
}
/* usart2 normal send func */
void Usart2_Send_Data(uint8_t *data, uint16_t length)
{
for (uint16_t i = 0; i < length; i++)
{
USART_SendData(USART2, *(data + i));
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
;
}
}
#elif (DIRVER_USART2_DMA_CONFIG == true)
/* USART2 DMA Rx Config */
static void Usart2_DMA_Rx_Config()
{
DMA_Cmd(DMA1_Stream5, DISABLE);
usart2_rx_size = (USART2_RX_MAX_SIZE - DMA_GetCurrDataCounter(DMA1_Stream5));
DMA_Cmd(DMA1_Stream5, ENABLE);
Usart2_Rx_Config();
}
/* usart2 DMA send func */
void Usart2_DMA_Send_Data(uint8_t *data, uint16_t length)
{
for (uint16_t i = 0; i < length; i++)
{
usart2_tx_buffer[i] = *(data + i);
}
DMA_SetCurrDataCounter(DMA1_Stream6, length);
DMA_Cmd(DMA1_Stream6, ENABLE);
}
#endif
void USART2_IRQHandler()
{
if (USART_GetITStatus(USART2, USART_IT_RXNE))
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
#if DIRVER_USART2_DMA_CONFIG == false
Usart2_Normal_Rx_Config();
#endif
}
if (USART_GetITStatus(USART2, USART_IT_TXE))
{
USART_ClearITPendingBit(USART2, USART_IT_TXE);
}
if (USART_GetITStatus(USART2, USART_IT_IDLE))
{
/* 清空IDLE标识位的时序 */
(void)USART2->SR;
(void)USART2->DR;
#if DIRVER_USART2_DMA_CONFIG == true
Usart2_DMA_Rx_Config();
#endif
}
}
void DMA1_Stream6_IRQHandler(void)
{
if (DMA_GetITStatus(DMA1_Stream6, DMA_IT_TCIF6) != RESET)
{
/* 清除标志位 */
DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);
/* 关闭DMA */
DMA_Cmd(DMA1_Stream6, DISABLE);
}
}
/* 该函数运行时基为1ms */
void Usart2_Rx_task()
{
if ((usart2_rx_flag == true) || (usart2_rx_time > 0))
{
usart2_rx_time--;
usart2_rx_flag = false;
if (usart2_rx_time == 0)
{
/* add you app */
memset(usart2_rx_buffer, 0, usart2_rx_size);
usart2_rx_size = 0;
}
}
}