【GD32】串口
🛠️ GD32 串口 (USART) 配置与使用指南
GD32 的串口 (USART) 是单片机与外部设备(如电脑、其他单片机、模块等)进行数据交换的重要接口,具有成本低、线路简单、可靠性高的特点。USART 支持全双工异步通信,是最常用的一种通信模式。
1 串口基础概念
串口通信通常涉及以下基本概念和参数:
概念 | 说明 | 常见设置 |
---|---|---|
波特率 | 数据传输的速率,表示每秒传输的符号数 | 9600, 115200等 |
数据位 | 一帧数据中包含的数据位数 | 8位 |
停止位 | 用于标志一帧数据的结束,长度可以是0.5、1、1.5或2个时间单位 | 1位 |
校验位 | 用于简单的错误检测,如奇校验、偶校验或无校验 | 无校验 |
流控制 | 通过RTS/CTS信号控制数据流,防止数据丢失,但在简单应用中常不用 | 无 |
工作模式 | 全双工(可同时收发的模式最为常用 | 全双工异步 |
2 GD32 USART 功能概述
GD32 的串口外设功能强大,支持多种模式:
- 全双工异步通信:最常用的模式,只需TX和RX两根线。
- 半双工单线通信:节省引脚,但不能同时收发。
- 同步通信:带时钟线(SCLK),USART0/1/2支持,UART3/4不支持(这也是USART和UART名称上的区别,中间的’S’代表Synchronous同步)。
- 多处理器通信:支持LIN总线、智能卡模式等。
- 硬件流控制:支持RTS和CTS,用于高速通信防丢失。
- 红外通信:支持IrDA SIR ENDEC功能。
3 GD32 USART 引脚分配
GD32 不同串口外设的默认引脚分配如下(以特定系列为例,具体请查阅对应型号的数据手册):
串口 | TX引脚 | RX引脚 |
---|---|---|
USART0 | PA9 | PA10 |
USART1 | PA2 | PA3 |
USART2 | PB10 | PB11 |
UART3 | 依型号而定 | 依型号而定 |
UART4 | 依型号而定 | 依型号而定 |
4 USART 配置步骤(以全双工异步模式为例)
4.1 GPIO 初始化
串口引脚需要配置为复用功能模式。
// 使能GPIOA时钟
rcu_periph_clock_enable(RCU_GPIOA);
// 配置PA9为复用推挽输出(TX)
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
// 配置PA10为下拉输入(RX)
gpio_init(GPIOA, GPIO_MODE_IPD, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
4.2 USART 初始化
使能USART时钟,并配置波特率、数据位、停止位、校验位等基本参数。
// 使能USART0时钟
rcu_periph_clock_enable(RCU_USART0);
// 设置波特率为115200
usart_baudrate_set(USART0, 115200);
// 无校验位
usart_parity_config(USART0, USART_PM_NONE);
// 8位数据位
usart_word_length_set(USART0, USART_WL_8BIT);
// 1位停止位
usart_stop_bit_set(USART0, USART_STB_1BIT);
// 使能发送器
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
// 使能接收器
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
// 最后使能USART
usart_enable(USART0);
4.3 重定向 printf 和 scanf (可选但非常实用)
为了方便使用printf
和scanf
等标准库函数进行输入输出,可以重定向fputc
和fgetc
函数。
#include <stdio.h>// 重定向printf到串口
int fputc(int ch, FILE *f)
{usart_data_transmit(USART0, (uint8_t)ch);while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET); // 等待发送完成return ch;
}// 重定向scanf到串口
int fgetc(FILE *f)
{while (usart_flag_get(USART0, USART_FLAG_RBNE) == RESET); // 等待接收到数据return (int)usart_data_receive(USART0);
}
注意:使用此方法重定向后,默认只能固定使用一个串口(本例为USART0)。若项目中使用多个串口,建议直接使用硬件相关的发送接收函数。
5 关键标志位和发送接收流程
5.1 发送数据
- 查询TBE (Transmit Buffer Empty) 标志位,判断发送缓冲区是否为空。
- 向USART_DATA寄存器写入要发送的数据。
- 如果需要确认一帧数据是否完全发送完毕(例如在改变波特率等操作前),可以查询TC (Transmission Complete) 标志位。
5.2 接收数据
- 查询RBNE (Read Buffer Not Empty) 标志位,判断接收缓冲区是否非空(即有数据到来)。
- 从USART_DATA寄存器读取接收到的数据。
- 读取USART_DATA寄存器会自动清除RBNE标志位。
6 实例代码
6.1 发送字符串 “Hello World”
#include "gd32fxxx.h"
#include "stdio.h"int main(void)
{systick_config(); // 配置系统滴答定时器USART_Config(); // 调用前面写的串口初始化函数while(1) {printf("Hello World!\n");delay_ms(1000); // 延时1秒}
}
6.2 接收回显(Echo)实验
单片机将接收到的数据原样发送回去。
#include "gd32fxxx.h"
#include "stdio.h"int main(void)
{systick_config();USART_Config();char buf[20] = {0};while(1) {memset(buf, 0x00, sizeof(buf)); // 清空缓冲区scanf("%s", buf); // 从串口接收字符串printf("received: %s\n", buf); // 将接收到的字符串打印回去}
}
7 总结与注意事项
- 时钟使能:务必记得使能USART外设和对应GPIO的时钟。
- 引脚复用:USART的TX和RX引脚需要配置为复用功能模式。
- 波特率计算:GD32提供了波特率寄存器(USART_BAUD),使用库函数
usart_baudrate_set
可以方便地设置波特率。 - 标志位查询:发送前检查TBE,接收前检查RBNE,避免数据覆盖或丢失。
- 中断使用:对于数据量较大或需要及时响应的应用,建议使用中断或DMA方式处理数据收发,以释放CPU资源。使能接收中断(RBNEIE)后,当接收到数据时会产生中断。
- 硬件流控制:在高速通信或特殊场合,如果发现数据丢失,可以考虑启用RTS/CTS硬件流控制。
- 电气电平:GD32的串口是TTL电平(0V表示0,3.3V表示1)。如果需要与电脑标准的RS232电平(负电压表示1,正电压表示0)通信,需要加装电平转换芯片(如MAX232)。