串口模板V1.0

源码

  1. #ifndef __USART0_H__
  2. #define __USART0_H__
  3. #include "gd32f4xx.h"
  4. #include <stdio.h>
  5. #define USART0_RX_ENABLE 1
  6. void Usart0_init();
  7. void Usart0_send_byte(uint8_t data);
  8. void Usart0_send_string(char* data);
  9. #if USART0_RX_ENABLE
  10. extern void Usart0_recv(uint8_t* data, uint32_t len);
  11. #endif
  12. #endif
  1. #include "Usart0.h"
  2. #if USART0_RX_ENABLE
  3. #define USART_RECEIVE_LENGTH 1024
  4. //串口接收缓冲区大小
  5. uint8_t g_recv_buff[USART_RECEIVE_LENGTH]; // 接收缓冲区
  6. //接收到字符存放的位置
  7. uint32_t g_recv_length = 0;
  8. #endif
  9. //1. 初始化
  10. void Usart0_init() {
  11. // 哪个串口
  12. uint32_t usartx = USART0;
  13. uint32_t usartx_rcu = RCU_USART0;
  14. uint32_t usartx_irq = USART0_IRQn;
  15. // 波特率
  16. uint32_t usartx_p_baudrate = 115200;
  17. // tx和rx,用了哪个引脚
  18. uint32_t usartx_tx_port_rcu = RCU_GPIOA;
  19. uint32_t usartx_tx_port = GPIOA;
  20. uint32_t usartx_tx_pin = GPIO_PIN_9;
  21. // 复用功能编号
  22. uint32_t usartx_tx_af = GPIO_AF_7;
  23. // tx和rx,用了哪个引脚
  24. uint32_t usartx_rx_port_rcu = RCU_GPIOA;
  25. uint32_t usartx_rx_port = GPIOA;
  26. uint32_t usartx_rx_pin = GPIO_PIN_10;
  27. // 复用功能编号
  28. uint32_t usartx_rx_af = GPIO_AF_7;
  29. /*************** gpio *****************/
  30. // TX
  31. // 配置时钟
  32. rcu_periph_clock_enable(usartx_tx_port_rcu);
  33. // 配置模式: 复用功能
  34. gpio_mode_set(usartx_tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_tx_pin);
  35. // 配置复用功能
  36. gpio_af_set(usartx_tx_port, usartx_tx_af, usartx_tx_pin);
  37. gpio_output_options_set(usartx_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_tx_pin);
  38. // RX
  39. // 配置时钟
  40. rcu_periph_clock_enable(usartx_rx_port_rcu);
  41. gpio_mode_set(usartx_rx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_rx_pin);
  42. gpio_af_set(usartx_rx_port, usartx_rx_af, usartx_rx_pin);
  43. // 配置输出参数
  44. gpio_output_options_set(usartx_rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_rx_pin);
  45. /*************** usart ****************/
  46. // 串口时钟
  47. rcu_periph_clock_enable(usartx_rcu);
  48. // USART复位
  49. usart_deinit(usartx);
  50. // 波特率
  51. usart_baudrate_set(usartx, usartx_p_baudrate);
  52. // 校验位
  53. usart_parity_config(usartx, USART_PM_NONE);
  54. // 数据位数
  55. usart_word_length_set(usartx, USART_WL_8BIT);
  56. // 停止位
  57. usart_stop_bit_set(usartx, USART_STB_1BIT);
  58. // 先发送高位还是低位
  59. usart_data_first_config(usartx, USART_MSBF_LSB);
  60. // 发送功能配置
  61. usart_transmit_config(usartx, USART_TRANSMIT_ENABLE);
  62. #if USART0_RX_ENABLE
  63. // 接收功能配置
  64. usart_receive_config(usartx, USART_RECEIVE_ENABLE);
  65. // 接收中断配置
  66. nvic_irq_enable(usartx_irq, 2, 2);
  67. // usart int rbne
  68. usart_interrupt_enable(usartx, USART_INT_RBNE);
  69. usart_interrupt_enable(usartx, USART_INT_IDLE);
  70. #endif
  71. // 使能串口
  72. usart_enable(usartx);
  73. }
  74. //2. 发送
  75. void Usart0_send_byte(uint8_t data) {
  76. //通过USART发送
  77. usart_data_transmit(USART0, data);
  78. //判断缓冲区是否已经空了
  79. //FlagStatus state = usart_flag_get(USART_NUM,USART_FLAG_TBE);
  80. while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
  81. }
  82. void Usart0_send_string(char* data) {
  83. while(data && *data) {
  84. Usart0_send_byte((uint8_t)(*data));
  85. data++;
  86. }
  87. }
  88. // printf打印功能
  89. int fputc(int ch, FILE *f){
  90. Usart0_send_byte((uint8_t)ch);
  91. return ch;
  92. }
  93. #if USART0_RX_ENABLE
  94. // 名称不能随意改,串口0的中断,就是这个名字
  95. void USART0_IRQHandler(void) {
  96. if ((usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) == SET) {
  97. uint16_t value = usart_data_receive(USART0);
  98. g_recv_buff[g_recv_length] = value;
  99. g_recv_length++;
  100. }
  101. if (usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE) == SET) {
  102. //读取缓冲区,清空缓冲区
  103. usart_data_receive(USART0);
  104. g_recv_buff[g_recv_length] = '\0';
  105. // TODO: g_recv_buff为接收的数据,g_recv_length为接收的长度
  106. // printf("recv: %s\r\n", g_recv_buff);
  107. Usart0_recv(g_recv_buff, g_recv_length);
  108. g_recv_length = 0;
  109. }
  110. }
  111. #endif

使用

  1. Usart0_init();
  1. Usart0_send_byte(0x00);
  1. Usart0_send_string("");

串口底层

初始化

  1. // 哪个串口
  2. uint32_t usartx = USART0;
  3. uint32_t usartx_rcu = RCU_USART0;
  4. uint32_t usartx_irq = USART0_IRQn;
  5. // 波特率
  6. uint32_t usartx_p_baudrate = 115200;
  7. // tx和rx,用了哪个引脚
  8. uint32_t usartx_tx_port_rcu = RCU_GPIOA;
  9. uint32_t usartx_tx_port = GPIOA;
  10. uint32_t usartx_tx_pin = GPIO_PIN_9;
  11. // 复用功能编号
  12. uint32_t usartx_tx_af = GPIO_AF_7;
  13. // tx和rx,用了哪个引脚
  14. uint32_t usartx_rx_port_rcu = RCU_GPIOA;
  15. uint32_t usartx_rx_port = GPIOA;
  16. uint32_t usartx_rx_pin = GPIO_PIN_10;
  17. // 复用功能编号
  18. uint32_t usartx_rx_af = GPIO_AF_7;
  19. /*************** gpio *****************/
  20. // TX
  21. // 配置时钟
  22. rcu_periph_clock_enable(usartx_tx_port_rcu);
  23. // 配置模式: 复用功能
  24. gpio_mode_set(usartx_tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_tx_pin);
  25. // 配置复用功能
  26. gpio_af_set(usartx_tx_port, usartx_tx_af, usartx_tx_pin);
  27. gpio_output_options_set(usartx_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_tx_pin);
  28. // RX
  29. // 配置时钟
  30. rcu_periph_clock_enable(usartx_rx_port_rcu);
  31. gpio_mode_set(usartx_rx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_rx_pin);
  32. gpio_af_set(usartx_rx_port, usartx_rx_af, usartx_rx_pin);
  33. // 配置输出参数
  34. gpio_output_options_set(usartx_rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_rx_pin);
  35. /*************** usart ****************/
  36. // 串口时钟
  37. rcu_periph_clock_enable(usartx_rcu);
  38. // USART复位
  39. usart_deinit(usartx);
  40. // 波特率
  41. usart_baudrate_set(usartx, usartx_p_baudrate);
  42. // 校验位
  43. usart_parity_config(usartx, USART_PM_NONE);
  44. // 数据位数
  45. usart_word_length_set(usartx, USART_WL_8BIT);
  46. // 停止位
  47. usart_stop_bit_set(usartx, USART_STB_1BIT);
  48. // 先发送高位还是低位
  49. usart_data_first_config(usartx, USART_MSBF_LSB);
  50. // 发送功能配置
  51. usart_transmit_config(usartx, USART_TRANSMIT_ENABLE);
  52. // 接收功能配置
  53. usart_receive_config(usartx, USART_RECEIVE_ENABLE);
  54. // 接收中断配置
  55. nvic_irq_enable(usartx_irq, 2, 2);
  56. // usart int rbne
  57. usart_interrupt_enable(usartx, USART_INT_RBNE);
  58. usart_interrupt_enable(usartx, USART_INT_IDLE);
  59. // 使能串口
  60. usart_enable(usartx);

发送字节

  1. static void send_byte(uint8_t data) {
  2. //通过USART发送
  3. usart_data_transmit(USART0, data);
  4. //判断缓冲区是否已经空了
  5. //FlagStatus state = usart_flag_get(USART_NUM,USART_FLAG_TBE);
  6. while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
  7. }

发送字符串

  1. static void send_string(char* data) {
  2. while(data && *data){
  3. send_byte((uint8_t)(*data));
  4. data++;
  5. }
  6. }

配置Printf

  1. int fputc(int ch, FILE *f){
  2. send_byte((uint8_t)ch);
  3. return ch;
  4. }

中断接收

  1. void USART0_IRQHandler(void) {
  2. if ((usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) == SET) {
  3. uint16_t value = usart_data_receive(USART0);
  4. g_recv_buff[g_recv_length] = value;
  5. g_recv_length++;
  6. }
  7. if (usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE) == SET) {
  8. //读取缓冲区,清空缓冲区
  9. usart_data_receive(USART0);
  10. g_recv_buff[g_recv_length] = '\0';
  11. // TODO: g_recv_buff为接收的数据,g_recv_length为接收的长度
  12. printf("recv: %s\r\n", g_recv_buff);
  13. g_recv_length = 0;
  14. }
  15. }