外观
八、串口调试实验
串口介绍
串口是指外设和处理器之间通过数据信号线、地线和控制线等,按位进行传输数据的一种通讯方式。尽管传输速度比并行传输低。但串口可以在使用一根线发送数据的同时用另一根线接收数据。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验位,这些参数在两个通信端口之间必须一致。
串口通信参数介绍
- 波特率: 衡量通信速度的参数,它表示每秒钟传送的bit的个数;
- 数据位: 衡量通信中实际数据位的参数,表示一个信息包里包含的数据位的个数;
- 停止位: 用于表示单个信息包的最后位,典型值为1、1.5和2位。由于数据是在传输线上传输的,每个设备都有自己的时钟,很有可能在通信过程中出现不同步,停止位不仅仅表示传输的结束,还能提供校正时钟同步的机会。停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率也越慢;
- 奇偶检验位: 表示一种简单的检查错误的方式。
串口工作模式
串口可以工作在单工、半双工和全双工模式下。
- 单工:在通信的任意时刻,信息只能由A传到B。
- 半双工:在通信的任意时刻,信息即可由A传到B,又能由B传到A,但同时只能有一个方向上的传输存在。
- 全双工:在通信的任意时刻,通信线路上存在A到B和B到A的双向信号传输。
串口通信协议
串口在进行通信的时候会按照数据包的形式进行发送,帧格式如下所示。
串口通信是一位一位地传输,每传输一个字符总是以起始位开始,以停止位结束,字符之间没有固定的时间间隔要求。每一个字符的前面都有一位起始位(低电平),后面由7位数据位组成,接着是一位校验位,最后是停止位。停止位后面是不定长的空闲位,停止位和空闲位都规定为高电平。串口接口原理图
在开发板上默认使用的串口是串口0,有两根数据线,也就是USART0_TX和USART0_RX。串口引脚和下载引脚连接在Type-C,插上Type-C就可以进行串口调试。关于串口原理图如下所示。
串口打印信息
项目分析
本次项目实现串口发送“Hello World”到电脑,通过电脑串口助手进行显示查看。
通过前面的知识,我们已经知道了串口通信的原理与连接的引脚;
- USART0_TX--->PA9
- USART0_RX--->PA10
配置流程
一般我们使用串口,都需要有以下几个步骤;
- 开启时钟(包括串口时钟和GPIO时钟);
- 配置GPIO复用模式;
- 配置GPIO的模式;
- 配置GPIO的输出;
- 配置串口(配置串口参数);
- 使能串口(串口使能和发送使能)。
开启时钟
串口0使用的是PA9,PA10引脚,首先需要开启GPIOA时钟,同时需要把串口外设时钟打开。
时钟库函数在gd32e23x_rcu.h头文件中,也可通过附件资料中的GD32固件库使用指南查看该函数的详细说明。
C
//使能时钟
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_USART0);
1
2
3
2
3
配置GPIO复用模式
GPIO引脚默认是作为普通IO使用,当需要使用外设功能时,需要打开对应的复用模式,在gd32e23x_gpio.h中可以查找到设置复用功能的函数。也可通过附件资料中的《GD32固件库使用指南》与《GD32E230数据手册》查看该函数与复用功能的详细说明。
该函数有三个参数:
- 第一个参数是配置引脚端口;
- 第二个参数是复用功能,此处选择选择复用功能1,对应是串口0的USART0_TX,USART0_RX;
- 第三个参数是实际的引脚号.
C
//复用功能设置
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_9);
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_10);
1
2
3
2
3
配置GPIO的模式
GPIO模式配置函数在前两节已经详细介绍过了,这里就不在赘述了。与前面两节不同的是,这里模式配置参数需要设置为复用功能而不是输入或输出,第三个参数为上拉。
C
//端口模式设置
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9);
//端口模式设置
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
1
2
3
4
2
3
4
配置GPIO的输出
配置GPIO输出函数也已经在前两节详细介绍过了,这里与前面的配置一样,修改引脚即可直接复用。
速度此处设置为10Mhz,也可以设置为50Mhz,并不影响,串口实际发送速度受波特率影响,这里只是决定波特率上限,一般情况下波特率不建议设置超过921600。
配置串口
和之前库函数点灯不同的是,使用串口还需要进行串口的配置。前面只是对GPIO的引脚做了配置,然后就可以操作GPIO进行输入输出,但是要使用串口,还需要设置串口的一些参数,后面使用其它的外设资源也是如此。 在使用一个外设之前,可以先复位一下,防止一些不必要的事情发生。在对应的外设库文件中一般都会有这个函数。在gd32e23x_uart.h头文件中有这个函数的声明,也可以通过《GD32库函数指南》查看详细说明。
C
//串口复位函数,参数是对应的串口接口
void usart_deinit(uint32_t usart_periph);
1
2
2
根据上述串口通信参数介绍,依次来对参数进行配置。以下配置函数均可在附件资料中的《GD32固件库使用指南》中找到对应的函数说明。
除了对串口通信参数进行配置,如果需要串口发送数据,则需要使能发送功能,这里我们不做数据接收,接收使能就无需配置。
最后是串口的总开关,我们需要使能串口才可打开串口功能。简单理解串口的发送与接收是功能开关,使能哪个就是打开哪个功能,串口使能是总开关,只有总开关打开才能使用串口功能。
C
usart_word_length_set(USART0, USART_WL_8BIT); //8位数据位宽
usart_stop_bit_set(USART0, USART_STB_1BIT); //1位停止位
usart_parity_config(USART0, USART_PM_NONE); //无校验位
usart_baudrate_set(USART0, bound); //波特率
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); //发送使能
//使能串口0
usart_enable(USART0);
1
2
3
4
5
6
7
2
3
4
5
6
7
上述串口通信参数的配置与电脑的串口调试助手参数需保持一致,否则无法正常通信。该串口助手读者可自行前往微软应用商店进行下载。
至此,串口配置参数完成。串口发送数据
配置好串口参数后,下一步操作就是要发送数据。
发送数据的流程分三步走:
- 第一步:调用串口发送函数;
- 第二步:等待串口发送完成;
- 第三步:清除串口发送标志位;
C
void USART0_SendData(char sendData)
{
//串口发送函数,发送一个字节数据
usart_data_transmit(USART0, (uint8_t)sendData);
//等待串口发送完成
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
//清除串口发送标志位
usart_flag_clear(USART0,USART_FLAG_TC);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
打开电脑串口调试助手,当我们调用该发送函数时,
C
USART0_SendData('h');
USART0_SendData('e');
USART0_SendData('l');
USART0_SendData('l');
USART0_SendData('o');
1
2
3
4
5
2
3
4
5
将会在串口助手上打印"hello"
这样每发送一个字节就需调用依次函数,非常麻烦,这里对发送函数就行修改,使用C语音指针的功能,实现串口发送字符串函数。C
void USART0_SendString(char *SendString)
{
//清除串口发送标志位
usart_flag_clear(USART0,USART_FLAG_TC);
//判断字符串是否到末尾
while(*SendString != '\0')
{
//串口发送函数,发送一个字节数据
usart_data_transmit(USART0, (uint8_t)*SendString);
//等待串口发送完成
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
//清除串口发送标志位
usart_flag_clear(USART0,USART_FLAG_TC);
//字符串向后移一位
SendString++;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
c
USART0_SendString("hello world");
1
现在通过调用一个函数即可发送“hello world”;
串口重定向
上面封装的发送字符串的方式打印信息看似方便,但如果我们想要打印数字,小数,该怎么打印呢?大家在学习C语言时已经习惯了使用了printf这个函数来进行打印,可以通过%d,%f打印整形和小数,这一小节就教大家怎么把串口重定向到printf函数中。
串口重定向介绍
C语言中的printf函数默认输出设备是显示器,如果要在串口显示,必须重新定义标准库函数里调用的与输出设备相关的函数。需要注意的是,在keil中使用printf一定要勾选“MicroLIB”选项。
printf重定向
在C语言通用编辑器中,printf函数是通过调用fputc函数来向标准输出流输出数据,这里我们是需要printf函数来向串口输出数据,所以需要重写fputc函数,将其中的内容改为向串口发送数据。 重写函数需要与原函数的名称、参数、返回值保持一致,这里大家不可修改。重写好之后就可以通过printf函数输出信息了。
C
int fputc(int ch, FILE *f)
{
usart_data_transmit(USART0, (uint8_t) ch);
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
return ch;
}
1
2
3
4
5
6
2
3
4
5
6
资料下载
工程代码可前往gitee下载资料包,简易数字示波器资料包
注意事项
无法打开串口
串口连接是在GD32E230小板上的TYPEC接口处,底板TYPE-C接口仅支持供电。想要使用串口功能,需将TYPE-C线连接到核心板的接口上;
每个人连接到电脑上的COM端口都不会完成一致,不需要完全按照图片的COM端口来。