Files
CH32V208WBU6/DRV/drv_uart.c
T
2024-03-04 01:01:14 +08:00

365 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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);
}