嵌入式系统中串口是非常重要的接口,除了用于与外设通信外,用它打印log和调试是最常用的手段之一。本文介绍gd32vf103芯片串口的最小配置,并实现printf函数,以方便log打印。串口的配置如下所示:

1、使能串口时钟;

2、配置串口使用的引脚为AFIO模式;

3、串口初始化;

4、通过发送接收寄存器收发数据;

我这里以串口0为例,其他的串口都是类似的操作。longan nano的串口0位于板子正面的左边。




Java调用串口信息连接数据库寻卡_图片通过串口发送


1、使能串口时钟

查阅《GD32VF103_User_Manual_CN_V1.2》可以找到gd32vf103器件的系统架构示意图,从图中我们可以看到串口0挂在APB2上。


Java调用串口信息连接数据库寻卡_串口_02


与前面讲GPIO类似,在手册中找到RCU寄存器一章,然后找到APB2使能寄存器(RCU_APB2EN),它的第14位就是串口0的时钟使能。


Java调用串口信息连接数据库寻卡_图片通过串口发送_03


代码如下所示:


Java调用串口信息连接数据库寻卡_图片通过串口发送_04


2、配置串口使用的引脚为AFIO模式

串口0默认用到了GPIOA的9和10引脚(关于gpio的基地址和配置等内容可以查看我的另一篇文章《Longan nano(GD32VF103)之GPIO最小配置》)。也可以使用重映射功能映射到GPIOB6和7上,关于重映射的内容我会专门写文章介绍。

用作串口通信的Rx和Tx引脚要配置正确,Rx是接收,所以要配置成输入,具体模式我都试过,发现三种(模拟、浮空、上下拉)都可以,一般是浮空输入。Tx是发送,所以配置成输出,输出模式必须为AFIO推挽输出或者AFIO开漏输出


Java调用串口信息连接数据库寻卡_图片通过串口发送_05


具体代码如下所示:


Java调用串口信息连接数据库寻卡_串口_06


3、串口初始化

我们平时使用串口感觉它很简单,其实不然,串口完整的内容体系还是有一点复杂的。当然我们先不管那么多,让它能够正常收发就可以了。

串口有几个常用参数:波特率、数据位、校验位、停止位。使用过串口终端或者串口助手的应该很熟悉。这些都在串口相关寄存器中配置。在《GD32VF103 用户手册》中可以找到串口的所有内容,usart寄存器的基地址如下所示:


Java调用串口信息连接数据库寻卡_串口_07


波特率寄存器设置串口通信的波特率,它的地址偏移0x08,寄存器分成了两部分,低四位设置波特率分频器的小数部分,高12位设置波特率分频器的整数部分。


Java调用串口信息连接数据库寻卡_串口_08


这两个值的计算方法在手册中有说明,具体如下:


Java调用串口信息连接数据库寻卡_图片通过串口发送_09


实际代码中不这么计算,而是用下面的公式:


Java调用串口信息连接数据库寻卡_串口_10


这个公式算出的结果可以直接放到波特率寄存器(USART_BAUD)中,它已经包含了移位、小数转换、进位和四舍五入。大家可以自己研究。

数据位和校验位在控制寄存器0(USART_CTL0)中设置,数据位通过bit12设置,校验位通过bit9设置。


Java调用串口信息连接数据库寻卡_串口_11


停止位在控制寄存器1(USART_CTL1)中设置,通过bit[13:12]设置。


Java调用串口信息连接数据库寻卡_图片通过串口发送_12


除了波特率我其他都使用默认值,所以没有设置它们。大家可以参考波特率的设置方法设置其他寄存器。


Java调用串口信息连接数据库寻卡_图片通过串口发送_13


初始化的最后一步就是使能串口和收发了,它们都在控制寄存器 0 (USART_CTL0) 中设置,bit13使能串口,bit3使能发送,bit2使能接收。这里要注意,使能要放到最后,因为使能后波特率寄存器、停止位和其他很多寄存器都不能写了。


Java调用串口信息连接数据库寻卡_图片通过串口发送_14


Java调用串口信息连接数据库寻卡_图片通过串口发送_15


4、通过发送接收寄存器收发数据

初始化完成后就可以通过数据寄存器 (USART_DATA) 读写数据了,它只有低8位有效。


Java调用串口信息连接数据库寻卡_图片通过串口发送_16


发送时系统会将数据寄存器中的值移到发送移位寄存器中发送,接收时数据会通过接收移位寄存器将数据放到数据寄存器中读取。


Java调用串口信息连接数据库寻卡_串口_17


数据的发送需要一定的时间,连续发送的太快会导致数据丢失。为了准确判断发送完成没有,就需要用到状态寄存器 0 (USART_STAT) ,它提供了各种状态和错误标志,通过这些标志就可以知道串口当前的工作状态。bit6是发送完成标志,bit5是读数据缓冲区非空标志。通过它们就可以准确控制数据的收发了。


Java调用串口信息连接数据库寻卡_串口_18


我这里使用了轮询的方法,一直while读取标志,实际中发送可以这样做,读取是不行的,否则干不了其他事了。接收由于时间的不确定性一般都使用中断的方式,我们以后介绍完中断再将这里改了。


Java调用串口信息连接数据库寻卡_图片通过串口发送_19


实现printf函数

学过c语言的都知道用printf函数打印信息非常方便,在嵌入式系统中尤其如此,所以下面说说怎么在我们上面串口0的基础上实现printf。

很多开发平台只需要重定位printf的输出就可以了,但是vscode+platformio这个我不知道怎么重定位,所以就找了一个printf的实现源码,这个源码实现了基本的功能,而且非常小,很适合嵌入式使用。

配置非常简单:

1、把两个文件添加到工程中


Java调用串口信息连接数据库寻卡_串口_20


2、然后include头文件


Java调用串口信息连接数据库寻卡_串口_21


3、实现发送字符的函数


Java调用串口信息连接数据库寻卡_串口_22


4、最后初始化一下就可以使用了


Java调用串口信息连接数据库寻卡_串口_23


我还没有尝试过它的打印极限,也不知道它有没有bug,以后用着慢慢看吧。

目前我们平台的基础已经搭好了,可以控制gpio、可以延时、可以打印log,以后学习其他模块就要方便很多了。