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

共 10104字,需浏览 21分钟

 ·

2022-04-11 12:45

    关注、星标公众号,直达精彩内容

来源:网络素材

 #ifndef __PLATFORM_USART_H__#define __PLATFORM_USART_H__ #include "stdio.h" #include  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;#endif
/* * 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() */#include #include "platform_usart.h"  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);}  #include #include  /* * 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);}   #include  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  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

关注我的微信公众号,回复“加群”按规则加入技术交流群。

点击下面图片,有星球具体介绍,新用户有新人优惠券,老用户半价优惠,期待大家一起学习一起进步。


点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。

浏览 45
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报