GD32 USART 高级编程 让你的串口不在阻塞发送
typedef struct {uint32_t usart_periph;uint8_t *tx_buf;uint16_t tx_buf_size;uint16_t tx_rd;uint16_t tx_wr;uint8_t *rx_buf;uint16_t rx_buf_size;uint16_t rx_rd;uint16_t rx_wr;void (*config)(void);void (*deconfig)(void);} usart_context_t;void usart_config_init(usart_context_t *pusart_context, uint32_t baud_rate);void usart_config_deinit(usart_context_t *pusart_context);void usart_send_it(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count);void usart_wait_sned_finished(usart_context_t *pusart_context);void usart_it(usart_context_t *pusart_context);int usart_receive_read(usart_context_t *pusart_context, void *_receive_buf, const int receive_count);void usart_printf(usart_context_t *pusart_context, char *arg, ...);void u_tm_log(char *arg, ...);void u_log(char *arg, ...);extern usart_context_t usart0_context;extern usart_context_t usart1_context;extern usart_context_t usart3_context;extern usart_context_t usart4_context;
/** Copyright (C) 2017, 2020 huohongpeng* Author: huohongpeng <1045338804@qq.com>** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** Change logs:* Date Author Notes* 2017-02-29 huohongpeng First add* 2020-09-19 huohongpeng add u_tm_log()*/static uint8_t usart0_tx_buf[1024];static uint8_t usart0_rx_buf[16];static uint8_t usart1_tx_buf[128];static uint8_t usart1_rx_buf[128];static uint8_t usart3_tx_buf[128];static uint8_t usart3_rx_buf[128];static uint8_t usart4_tx_buf[128];static uint8_t usart4_rx_buf[128];static void usart0_config(void){nvic_irq_enable(USART0_IRQn, 0, 1);rcu_periph_clock_enable(RCU_GPIOA);rcu_periph_clock_enable(RCU_USART0);/* connect port to USARTx_Tx */gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);/* connect port to USARTx_Rx */gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);}static void usart1_config(void){nvic_irq_enable(USART1_IRQn, 1, 1);rcu_periph_clock_enable(RCU_GPIOD);rcu_periph_clock_enable(RCU_USART1);rcu_periph_clock_enable(RCU_AF);gpio_pin_remap_config(GPIO_USART1_REMAP, ENABLE);/* connect port to USARTx_Tx */gpio_init(GPIOD, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);/* connect port to USARTx_Rx */gpio_init(GPIOD, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6);}static void usart3_config(void){nvic_irq_enable(UART3_IRQn, 1, 1);rcu_periph_clock_enable(RCU_GPIOC);rcu_periph_clock_enable(RCU_UART3);/* connect port to USARTx_Tx */gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);/* connect port to USARTx_Rx */gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);}static void usart4_config(void){nvic_irq_enable(UART4_IRQn, 1, 1);rcu_periph_clock_enable(RCU_GPIOC);rcu_periph_clock_enable(RCU_GPIOD);rcu_periph_clock_enable(RCU_UART4);/* connect port to USARTx_Tx */gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);/* connect port to USARTx_Rx */gpio_init(GPIOD, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_2);}static void usart0_deconfig(void){gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_9);nvic_irq_disable(USART0_IRQn);rcu_periph_clock_disable(RCU_GPIOA);rcu_periph_clock_disable(RCU_USART0);}static void usart1_deconfig(void){}static void usart3_deconfig(void){}static void usart4_deconfig(void){}usart_context_t usart0_context = {USART0,usart0_tx_buf,sizeof(usart0_tx_buf),0,0,usart0_rx_buf,sizeof(usart0_rx_buf),0,0,usart0_config,usart0_deconfig};usart_context_t usart1_context = {USART1,usart1_tx_buf,sizeof(usart1_tx_buf),0,0,usart1_rx_buf,sizeof(usart1_rx_buf),0,0,usart1_config,usart1_deconfig,};usart_context_t usart3_context = {UART3,usart3_tx_buf,sizeof(usart3_tx_buf),0,0,usart3_rx_buf,sizeof(usart3_rx_buf),0,0,usart3_config,usart3_deconfig,};usart_context_t usart4_context = {UART4,usart4_tx_buf,sizeof(usart4_tx_buf),0,0,usart4_rx_buf,sizeof(usart4_rx_buf),0,0,usart4_config,usart4_deconfig,};void usart_config_init(usart_context_t *pusart_context, uint32_t baud_rate){pusart_context->config();/* USART configure */usart_deinit(pusart_context->usart_periph);usart_baudrate_set(pusart_context->usart_periph, baud_rate);usart_receive_config(pusart_context->usart_periph, USART_RECEIVE_ENABLE);usart_transmit_config(pusart_context->usart_periph, USART_TRANSMIT_ENABLE);usart_word_length_set(pusart_context->usart_periph, USART_WL_8BIT);usart_stop_bit_set(pusart_context->usart_periph, USART_STB_1BIT);usart_enable(pusart_context->usart_periph);usart_interrupt_enable(pusart_context->usart_periph, USART_INT_RBNE);}void usart_config_deinit(usart_context_t *pusart_context){usart_disable(pusart_context->usart_periph);usart_deinit(pusart_context->usart_periph);pusart_context->deconfig();}/** Rewrite fputc for printf* NOTE: IAR options->C/C++ compiler->preprocessor add symbal _DLIB_FILE_DESCRIPTOR*/int fputc(int ch, FILE *f){usart_send_it(&usart0_context, &ch, 1);return ch;}void usart_send(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count){const uint8_t *send_buf = (const uint8_t *)_send_buf;uint16_t i;for(i = 0; i < send_count; i++) {while(RESET == usart_flag_get(pusart_context->usart_periph, USART_FLAG_TBE));usart_data_transmit(pusart_context->usart_periph, (uint8_t)send_buf[i]);}while(RESET == usart_flag_get(pusart_context->usart_periph, USART_FLAG_TC));}/** Usart send base on usart send interrupt*/void usart_send_it(usart_context_t *pusart_context, const void *_send_buf, const uint16_t send_count){const uint8_t *send_buf = (const uint8_t *)_send_buf;uint16_t i;/** 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((pusart_context->tx_wr+1) % pusart_context->tx_buf_size == pusart_context->tx_rd);pusart_context->tx_buf[pusart_context->tx_wr++] = send_buf[i];pusart_context->tx_wr %= pusart_context->tx_buf_size;usart_interrupt_enable(pusart_context->usart_periph, USART_INT_TBE);}}void usart_wait_sned_finished(usart_context_t *pusart_context){while(pusart_context->tx_wr != pusart_context->tx_rd);while(RESET == usart_flag_get(pusart_context->usart_periph, USART_FLAG_TC));}/** read data from receive buffer*/int usart_receive_read(usart_context_t *pusart_context, void *_receive_buf, const int receive_count){uint8_t *receive_buf = (uint8_t *)_receive_buf;int i, receive_count_real;/** 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(pusart_context->rx_rd == pusart_context->rx_wr) {return receive_count_real;} else {receive_buf[i] = pusart_context->rx_buf[pusart_context->rx_rd++];pusart_context->rx_rd %= pusart_context->rx_buf_size;receive_count_real++;}}return receive_count_real;}static void usart_rbne_it(usart_context_t *pusart_context){pusart_context->rx_buf[pusart_context->rx_wr++] = usart_data_receive(pusart_context->usart_periph);pusart_context->rx_wr %= pusart_context->rx_buf_size;/** overflow handle*/if(pusart_context->rx_wr == pusart_context->rx_rd) {pusart_context->rx_rd++;pusart_context->rx_rd %= pusart_context->rx_buf_size;}}static void usart_tbe_it(usart_context_t *pusart_context){if(pusart_context->tx_rd != pusart_context->tx_wr) {usart_data_transmit(pusart_context->usart_periph, pusart_context->tx_buf[pusart_context->tx_rd++]);pusart_context->tx_rd %= pusart_context->tx_buf_size;} else {usart_interrupt_disable(pusart_context->usart_periph, USART_INT_TBE);}}void usart_it(usart_context_t *pusart_context){if(usart_interrupt_flag_get(pusart_context->usart_periph, USART_INT_FLAG_RBNE) == SET) {usart_interrupt_flag_clear(pusart_context->usart_periph, USART_INT_FLAG_RBNE);usart_rbne_it(pusart_context);}if(usart_interrupt_flag_get(pusart_context->usart_periph, USART_INT_FLAG_TBE) == SET) {usart_interrupt_flag_clear(pusart_context->usart_periph, USART_INT_FLAG_TBE);usart_tbe_it(pusart_context);}if(usart_interrupt_flag_get(pusart_context->usart_periph, USART_INT_FLAG_ERR_ORERR) == SET) {usart_interrupt_flag_clear(pusart_context->usart_periph, USART_INT_FLAG_ERR_ORERR);}}void USART0_IRQHandler(void){usart_it(&usart0_context);}void USART1_IRQHandler(void){usart_it(&usart1_context);}void UART3_IRQHandler(void){usart_it(&usart3_context);}void UART4_IRQHandler(void){usart_it(&usart4_context);}/** usart printf function*/void usart_printf(usart_context_t *pusart_context, char *arg, ...){char buf[256], len;va_list vl;__va_start(vl, arg);len = vsprintf(buf, arg, vl);__va_end(vl);usart_send_it(pusart_context, buf, len);}void u_tm_log(char *arg, ...){char buf[512];uint32_t s, ms, len , n;uint32_t tm = get_systick_ms();s = tm / 1000;ms = tm % 1000;n = sprintf(buf, "[%d.%03d] ", s, ms);va_list vl;__va_start(vl, arg);len = vsprintf(buf+n, arg, vl);__va_end(vl);len = len+n;usart_send_it(&usart0_context, buf, len);}void u_log(char *arg, ...){char buf[512];uint32_t len;va_list vl;__va_start(vl, arg);len = vsprintf(buf, arg, vl);__va_end(vl);usart_send_it(&usart0_context, buf, len);}
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
关注我的微信公众号,回复“加群”按规则加入技术交流群。
点击下面图片,有星球具体介绍,新用户有新人优惠券,老用户半价优惠,期待大家一起学习一起进步。
点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。
评论
