GD32 USART 高级编程 让你的串口不在阻塞发送

2019-04-15 17:42发布


#ifndef __USART_H__ #define __USART_H__ #include "stdio.h" //#define infoprintf printf("[%d-%s()] : ",__LINE__, __FUNCTION__);printf #define infoprintf(...) int usart_init(int usart_num, int baud_rate); int usart_send(int usart_num, const void *_send_buf, const int send_count); int usart_send_it(int usart_num, const void *_send_buf, const int send_count); int usart_receive_read(int usart_num, void *_receive_buf, const int receive_count); void usart_rbne_it(int usart_num); void usart_tbe_it(int usart_num); #endif


/******************************************************************************* file : platform_uasrt.c author : huohongpeng date : 2017-01-25 description : advance application for usart, base on gd lib *******************************************************************************/ #include "platform_usart.h" #include "gd32f1x0.h" #define TX_BUF_SIZE 128 #define RX_BUF_SIZE 128 struct usart_dev { unsigned char tx_buf[TX_BUF_SIZE]; unsigned short tx_rd; unsigned short tx_wr; unsigned char rx_buf[RX_BUF_SIZE]; unsigned short rx_rd; unsigned short rx_wr; }; static struct usart_dev usart1_dev, usart2_dev; /** description : init uasrt1 and set baud rate param : usart_num - 1,2 baud_rate - 4800,9600,14400, ... retval : 0 - success author : huohongpeng date : 2017-01-25 */ int usart_init(int usart_num, int baud_rate) { GPIO_InitPara GPIO_InitParaStruct; USART_InitPara USART_InitParaStruct; USART_TypeDef * usart_index[] = {0, USART1, USART2}; if(usart_num == 1) { RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_USART1, ENABLE); RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOA, ENABLE); /*usart1 Rx*/ GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_AF; GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_10; GPIO_InitParaStruct.GPIO_PuPd = GPIO_PUPD_PULLUP; GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_2MHZ; GPIO_Init(GPIOA, &GPIO_InitParaStruct); /*usart1 Tx*/ GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_AF; GPIO_InitParaStruct.GPIO_OType = GPIO_OTYPE_PP; GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_9; GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_2MHZ; GPIO_Init(GPIOA, &GPIO_InitParaStruct); GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE10, GPIO_AF_1); GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE9, GPIO_AF_1); } else if(usart_num == 2) { RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_USART2, ENABLE); RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOA, ENABLE); /*usart2 Rx*/ GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_AF; GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_15; GPIO_InitParaStruct.GPIO_PuPd = GPIO_PUPD_PULLUP; GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_2MHZ; GPIO_Init(GPIOA, &GPIO_InitParaStruct); /*usart2 Tx*/ GPIO_InitParaStruct.GPIO_Mode = GPIO_MODE_AF; GPIO_InitParaStruct.GPIO_OType = GPIO_OTYPE_PP; GPIO_InitParaStruct.GPIO_Pin = GPIO_PIN_14; GPIO_InitParaStruct.GPIO_Speed = GPIO_SPEED_2MHZ; GPIO_Init(GPIOA, &GPIO_InitParaStruct); GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE14, GPIO_AF_1); GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE15, GPIO_AF_1); } else { return -1; } /*usartx attribute config*/ USART_InitParaStruct.USART_BRR = baud_rate; USART_InitParaStruct.USART_HardwareFlowControl = USART_HARDWAREFLOWCONTROL_NONE; USART_InitParaStruct.USART_Parity = USART_PARITY_RESET; USART_InitParaStruct.USART_RxorTx = USART_RXORTX_RX |USART_RXORTX_TX; USART_InitParaStruct.USART_STBits = USART_STBITS_1; USART_InitParaStruct.USART_WL = USART_WL_8B; USART_Init(usart_index[usart_num], &USART_InitParaStruct); USART_Enable(usart_index[usart_num], ENABLE); USART_INT_Set(usart_index[usart_num], USART_INT_RBNE, ENABLE); return 0; } /** description : usart send send_count characters param : usart_num - 1, 2 _send_buf - send buffer send_count - number of send retval : 0 - success author : huohongpeng date : 2017-01-25 */ int usart_send(int usart_num, const void *_send_buf, const int send_count) { const char *send_buf = (const char *)_send_buf; USART_TypeDef * usart_index[] = {0, USART1, USART2}; int i; if(usart_num < 1 || usart_num > 2) { return -1; } USART_INT_Set(usart_index[usart_num], USART_INT_RBNE, DISABLE); for(i = 0; i < send_count; i++) { while(USART_GetBitState(usart_index[usart_num], USART_FLAG_TBE) == RESET); USART_DataSend(usart_index[usart_num], send_buf[i]); } USART_INT_Set(usart_index[usart_num], USART_INT_RBNE, ENABLE); return 0; } /** description : rewrite fputc for printf param : ... retval : 0 - success author : huohongpeng date : 2017-01-25 other : options->C/C++ compiler->preprocessor add symbal _DLIB_FILE_DESCRIPTOR */ int fputc(int ch, FILE *f) { usart_send_it(1, &ch, 1); return ch; } /** description : usart send base on usart send interrupt param : usart_num - 1, 2 _send_buf - send buffer send_count - number of send retval : 0 - success author : huohongpeng date : 2017-01-26 */ int usart_send_it(int usart_num, const void *_send_buf, const int send_count) { struct usart_dev *usart_dev; struct usart_dev *usart_dev_index[] = {0, &usart1_dev, &usart2_dev}; USART_TypeDef* usart_index[] = {0, USART1, USART2}; const char *send_buf = (const char *)_send_buf; int i; if(usart_num < 1 || usart_num > 2) { return -1; } usart_dev = usart_dev_index[usart_num]; /* Write send data to send buffer and use interrupt send data. Wait buffer effective when send buffer is full. */ for(i = 0; i < send_count; i++) { while((usart_dev->tx_wr+1) % TX_BUF_SIZE == usart_dev->tx_rd); usart_dev->tx_buf[usart_dev->tx_wr++] = send_buf[i]; usart_dev->tx_wr %= TX_BUF_SIZE; USART_INT_Set(usart_index[usart_num], USART_INT_TBE, ENABLE); } return 0; } /** description : read data from receive buffer param : usart_num - 1, 2 _receive_buf - receive buffer receive_count - number of receive retval : -1 - success other - real read count author : huohongpeng date : 2017-01-26 */ int usart_receive_read(int usart_num, void *_receive_buf, const int receive_count) { struct usart_dev *usart_dev; struct usart_dev *usart_dev_index[] = {0, &usart1_dev, &usart2_dev}; char *receive_buf = (char *)_receive_buf; int i, receive_count_real; if(usart_num < 1 || usart_num > 2) { return -1; } usart_dev = usart_dev_index[usart_num]; /* Read data from receive buffer. The buffer have data that received from usart. */ for(i = 0, receive_count_real = 0; i < receive_count; i++) { if(usart_dev->rx_rd == usart_dev->rx_wr) { return receive_count_real; } else { receive_buf[i] = usart_dev->rx_buf[usart_dev->rx_rd++]; usart_dev->rx_rd %= RX_BUF_SIZE; receive_count_real++; } } return receive_count_real; } /** description : usart receive not empty interrupt hander, call in intterrupt function param : usart_num - 1, 2 retval : None author : huohongpeng date : 2017-01-26 */ void usart_rbne_it(int usart_num) { struct usart_dev *usart_dev; struct usart_dev *usart_dev_index[] = {0, &usart1_dev, &usart2_dev}; USART_TypeDef* usart_index[] = {0, USART1, USART2}; if(usart_num < 1 || usart_num > 2) { return; } usart_dev = usart_dev_index[usart_num]; usart_dev->rx_buf[usart_dev->rx_wr++] = USART_DataReceive(usart_index[usart_num]); usart_dev->rx_wr %= RX_BUF_SIZE; /* overflow handle */ if(usart_dev->rx_wr == usart_dev->rx_rd) { usart_dev->rx_rd++; usart_dev->rx_rd %= RX_BUF_SIZE; } } /** description : usart transport empty interrupt hander, call in intterrupt function param : usart_num - 1, 2 retval : None author : huohongpeng date : 2017-01-26 */ void usart_tbe_it(int usart_num) { struct usart_dev *usart_dev; struct usart_dev *usart_dev_index[] = {0, &usart1_dev, &usart2_dev}; USART_TypeDef* usart_index[] = {0, USART1, USART2}; if(usart_num < 1 || usart_num > 2) { return; } usart_dev = usart_dev_index[usart_num]; if(usart_dev->tx_rd != usart_dev->tx_wr) { USART_DataSend(usart_index[usart_num], usart_dev->tx_buf[usart_dev->tx_rd++]); usart_dev->tx_rd %= TX_BUF_SIZE; } else { USART_INT_Set(usart_index[usart_num], USART_INT_TBE, DISABLE); } }