365 lines
11 KiB
C
365 lines
11 KiB
C
/*
|
||
* drv_usart.c
|
||
*
|
||
* Created on: Mar 31, 2023
|
||
* Author: gxms0
|
||
*/
|
||
|
||
#include <drv_uart.h>
|
||
|
||
|
||
UART_t uart1;
|
||
UART_t uart2;
|
||
UART_t uart3;
|
||
|
||
|
||
void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
|
||
|
||
//void DMA1_Channel5_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||
|
||
|
||
|
||
//初始化串口,
|
||
/*
|
||
void USART1_Init(uint32_t BaudRate,uint16_t WordLength,uint16_t StopBits,uint16_t Parity)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||
USART_InitTypeDef USART_InitStructure = {0};
|
||
DMA_InitTypeDef DMA_InitStructure = {0};
|
||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||
|
||
|
||
//DMA设置
|
||
//RX DMA1_Channel5
|
||
DMA_DeInit(DMA1_Channel5);
|
||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DATAR;
|
||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buff_rx;
|
||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||
DMA_InitStructure.DMA_BufferSize = sizeof(buff_rx);//设置buffer大小
|
||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
||
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
|
||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
|
||
|
||
//TX DMA1_Channel4
|
||
DMA_DeInit(DMA1_Channel4);
|
||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DATAR;
|
||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buff_tx;
|
||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
||
DMA_InitStructure.DMA_BufferSize = sizeof(buff_tx);
|
||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
|
||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
|
||
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
|
||
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
|
||
DMA_ITConfig(DMA1_Channel5, DMA_IT_TE, ENABLE);
|
||
|
||
//打开接收
|
||
DMA_Cmd(DMA1_Channel5, ENABLE);
|
||
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
|
||
|
||
//打开发送(不需要,等到发送时打开即可)
|
||
|
||
USART_Cmd(USART1, ENABLE);
|
||
}
|
||
*/
|
||
|
||
|
||
|
||
void usart_init(void)
|
||
{
|
||
usart_config(&uart1,USART1 ,GPIOA, GPIO_Pin_9, GPIOA, GPIO_Pin_10, 0,115200, USART_WordLength_8b, USART_StopBits_1, USART_Parity_No,128,128);
|
||
usart_config(&uart3,USART3 ,GPIOC, GPIO_Pin_10, GPIOC, GPIO_Pin_11, GPIO_PartialRemap_USART3,19200,USART_WordLength_8b, USART_StopBits_1, USART_Parity_No,128,128);
|
||
}
|
||
|
||
|
||
void usart_config(UART_ptr ptr,USART_TypeDef *UART, GPIO_TypeDef *GPIO_Tx, uint32_t Pin_Tx, GPIO_TypeDef *GPIO_Rx, uint32_t Pin_Rx, uint32_t GPIO_Remap,
|
||
uint32_t BaudRate, uint16_t WordLength, uint16_t StopBits, uint16_t Parity,
|
||
uint32_t buff_tx_len,uint32_t buff_rx_len)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||
USART_InitTypeDef USART_InitStructure = {0};
|
||
//DMA_InitTypeDef DMA_InitStructure = {0};
|
||
NVIC_InitTypeDef NVIC_InitStructure = {0};
|
||
uint32_t RCC_Periph = RCC_APB2Periph_USART1;
|
||
|
||
|
||
ptr->USART = UART;
|
||
ptr->GPIO_Tx = GPIO_Tx;
|
||
ptr->Pin_Tx = Pin_Tx;
|
||
ptr->GPIO_Rx = GPIO_Rx;
|
||
ptr->Pin_Rx = Pin_Rx;
|
||
|
||
if (ptr->buffer_rx)
|
||
free(ptr->buffer_rx);
|
||
if (ptr->buffer_tx)
|
||
free(ptr->buffer_tx);
|
||
|
||
ptr->buffer_rx = (uint8_t *)malloc(buff_rx_len);
|
||
ptr->buffer_tx = (uint8_t *)malloc(buff_tx_len);
|
||
ptr->buffer_rx_len = buff_rx_len;
|
||
ptr->buffer_tx_len = buff_tx_len;
|
||
ptr->buffer_tx_len_2 = buff_tx_len / 2;
|
||
|
||
if(ptr->USART == USART1){RCC_Periph = RCC_APB2Periph_USART1;RCC_APB2PeriphClockCmd(RCC_Periph, ENABLE);}
|
||
else if(ptr->USART == USART2){RCC_Periph = RCC_APB1Periph_USART2;RCC_APB1PeriphClockCmd(RCC_Periph, ENABLE);}
|
||
else if(ptr->USART == USART3){RCC_Periph = RCC_APB1Periph_USART3;RCC_APB1PeriphClockCmd(RCC_Periph, ENABLE);}
|
||
else if(ptr->USART == UART4){RCC_Periph = RCC_APB1Periph_UART4;RCC_APB1PeriphClockCmd(RCC_Periph, ENABLE);}
|
||
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
||
|
||
if(GPIO_Remap)
|
||
{
|
||
GPIO_PinRemapConfig(GPIO_Remap, ENABLE);
|
||
}
|
||
|
||
//初始化IO口
|
||
//init tx
|
||
if(ptr->GPIO_Tx == GPIOA)RCC_Periph = RCC_APB2Periph_GPIOA;
|
||
else if(ptr->GPIO_Tx == GPIOB)RCC_Periph = RCC_APB2Periph_GPIOB;
|
||
else if(ptr->GPIO_Tx == GPIOC)RCC_Periph = RCC_APB2Periph_GPIOC;
|
||
else if(ptr->GPIO_Tx == GPIOD)RCC_Periph = RCC_APB2Periph_GPIOD;
|
||
else if(ptr->GPIO_Tx == GPIOE)RCC_Periph = RCC_APB2Periph_GPIOE;
|
||
|
||
RCC_APB2PeriphClockCmd(RCC_Periph, ENABLE);
|
||
GPIO_InitStructure.GPIO_Pin = ptr->Pin_Tx;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_Init(ptr->GPIO_Tx, &GPIO_InitStructure);
|
||
|
||
//init rx
|
||
if(ptr->GPIO_Rx == GPIOA)RCC_Periph = RCC_APB2Periph_GPIOA;
|
||
else if(ptr->GPIO_Rx == GPIOB)RCC_Periph = RCC_APB2Periph_GPIOB;
|
||
else if(ptr->GPIO_Rx == GPIOC)RCC_Periph = RCC_APB2Periph_GPIOC;
|
||
else if(ptr->GPIO_Rx == GPIOD)RCC_Periph = RCC_APB2Periph_GPIOD;
|
||
else if(ptr->GPIO_Rx == GPIOE)RCC_Periph = RCC_APB2Periph_GPIOE;
|
||
|
||
RCC_APB2PeriphClockCmd(RCC_Periph, ENABLE);
|
||
GPIO_InitStructure.GPIO_Pin = ptr->Pin_Rx;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_Init(ptr->GPIO_Rx, &GPIO_InitStructure);
|
||
|
||
|
||
USART_InitStructure.USART_BaudRate = BaudRate;
|
||
USART_InitStructure.USART_WordLength = WordLength;
|
||
USART_InitStructure.USART_StopBits = StopBits;
|
||
USART_InitStructure.USART_Parity = Parity;
|
||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
|
||
|
||
USART_Init(ptr->USART, &USART_InitStructure);
|
||
|
||
USART_ITConfig(ptr->USART, USART_IT_RXNE, ENABLE);//读取数据
|
||
|
||
USART_ITConfig(ptr->USART, USART_IT_IDLE, ENABLE);//读取整包数据(读取fifo)
|
||
|
||
USART_ITConfig(ptr->USART, USART_IT_TXE, DISABLE);//发送可以不开中断,只要传到dma即可
|
||
|
||
uint8_t NVIC_IRQChannel = USART1_IRQn;
|
||
|
||
if(ptr->USART == USART1)NVIC_IRQChannel = USART1_IRQn;
|
||
else if(ptr->USART == USART2)NVIC_IRQChannel = USART2_IRQn;
|
||
else if(ptr->USART == USART3)NVIC_IRQChannel = USART3_IRQn;
|
||
else if(ptr->USART == UART4)NVIC_IRQChannel = UART4_IRQn;
|
||
|
||
|
||
NVIC_InitStructure.NVIC_IRQChannel = NVIC_IRQChannel;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
|
||
USART_Cmd(ptr->USART, ENABLE);
|
||
|
||
}
|
||
|
||
size_t usart_read(UART_ptr ptr,unsigned char *buff,const unsigned int len)
|
||
{
|
||
size_t i = 0;
|
||
|
||
if (ptr->buffer_rx_len)
|
||
{
|
||
size_t blen = ptr->buffer_rx_head - ptr->buffer_rx_tail;
|
||
if (blen < 0)
|
||
{
|
||
blen += ptr->buffer_rx_len;
|
||
}
|
||
if (blen > ptr->buffer_rx_max)
|
||
{
|
||
ptr->buffer_rx_max = blen;
|
||
}
|
||
for (; i < len; ++i)
|
||
{
|
||
if (ptr->buffer_rx_tail != ptr->buffer_rx_head)
|
||
{
|
||
buff[i] = ptr->buffer_rx[ptr->buffer_rx_tail++];
|
||
if (ptr->buffer_rx_tail >= ptr->buffer_rx_len)
|
||
{
|
||
ptr->buffer_rx_tail = 0;
|
||
}
|
||
}
|
||
else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return i;
|
||
}
|
||
|
||
size_t usart_write(UART_ptr ptr,const unsigned char *buff,const unsigned int len)
|
||
{
|
||
size_t size = len;
|
||
|
||
ptr->pkg_tx++;
|
||
|
||
if (ptr->buffer_tx_len)
|
||
{
|
||
for (size_t i = 0; i < len; ++i)
|
||
{
|
||
ptr->buffer_tx[ptr->buffer_tx_head++] = buff[i];
|
||
if (ptr->buffer_tx_head >= ptr->buffer_tx_len)
|
||
{
|
||
ptr->buffer_tx_head = 0;
|
||
}
|
||
}
|
||
int blen = ptr->buffer_tx_head - ptr->buffer_tx_tail;
|
||
if (blen < 0)
|
||
{
|
||
blen += ptr->buffer_tx_len;
|
||
}
|
||
if (blen > ptr->buffer_tx_max)
|
||
{
|
||
ptr->buffer_tx_max = blen;
|
||
}
|
||
if (ptr->buffer_tx_tail != ptr->buffer_tx_head)
|
||
{
|
||
if (ptr->GPIOx)
|
||
{
|
||
GPIO_WriteBit(ptr->GPIOx, ptr->GPIO_Pin, Bit_SET);
|
||
}
|
||
|
||
/* enable the USARTx transmit interrupt */
|
||
USART_ITConfig(ptr->USART, USART_IT_TXE, ENABLE);
|
||
}
|
||
}
|
||
|
||
return size;
|
||
}
|
||
|
||
void UART_IRQHandler(UART_ptr ptr)
|
||
{
|
||
if (RESET != USART_GetITStatus(ptr->USART, USART_IT_RXNE))
|
||
{
|
||
/* Read one byte from the receive data register */
|
||
ptr->buffer_rx[ptr->buffer_rx_head++] = (uint8_t)USART_ReceiveData(ptr->USART);
|
||
ptr->byt_rx++;
|
||
|
||
if (ptr->buffer_rx_head >= ptr->buffer_rx_len)
|
||
{
|
||
ptr->buffer_rx_head = 0;
|
||
}
|
||
}
|
||
|
||
if ((RESET != USART_GetITStatus(ptr->USART, USART_IT_IDLE)))
|
||
{
|
||
USART_ClearITPendingBit(ptr->USART, USART_IT_IDLE);
|
||
USART_ReceiveData(ptr->USART);
|
||
//发出一个可以读取FIFO的信号
|
||
}
|
||
|
||
//发送中断时使用
|
||
if (RESET != USART_GetITStatus(ptr->USART, USART_IT_TXE))
|
||
{
|
||
USART_ClearITPendingBit(ptr->USART, USART_IT_TXE);
|
||
|
||
if (ptr->buffer_tx_tail == ptr->buffer_tx_head)
|
||
{
|
||
/* disable the USARTx transmit interrupt */
|
||
USART_ITConfig(ptr->USART, USART_IT_TXE, DISABLE);
|
||
USART_ITConfig(ptr->USART, USART_IT_TC, ENABLE);
|
||
}
|
||
else
|
||
{
|
||
/* Write one byte to the transmit data register */
|
||
USART_SendData(ptr->USART, ptr->buffer_tx[ptr->buffer_tx_tail++]);
|
||
ptr->byt_tx++;
|
||
if (ptr->buffer_tx_tail >= ptr->buffer_tx_len)
|
||
{
|
||
ptr->buffer_tx_tail = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
//发送完成中断
|
||
if (RESET != USART_GetITStatus(ptr->USART, USART_IT_TC))
|
||
{
|
||
USART_ClearITPendingBit(ptr->USART, USART_IT_TC);
|
||
USART_ITConfig(ptr->USART, USART_IT_TC, DISABLE);
|
||
if (ptr->GPIOx)
|
||
{
|
||
GPIO_WriteBit(ptr->GPIOx, ptr->GPIO_Pin, Bit_RESET);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void USART1_IRQHandler(void)
|
||
{
|
||
UART_IRQHandler(&uart1);
|
||
}
|
||
|
||
void USART2_IRQHandler(void)
|
||
{
|
||
UART_IRQHandler(&uart2);
|
||
}
|
||
|
||
void USART3_IRQHandler(void)
|
||
{
|
||
UART_IRQHandler(&uart3);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|