javarxtx串口接收时数据会分成好几段_GD32VF103之串口uart最小配置

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

1、使能串口时钟;

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

3、串口初始化;

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

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

e6381647c2fceceaf019a6b5ac2db783.png

1、使能串口时钟

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

3a6a1bc42ed5e41b463a2e1d2d0431e0.png


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

3c8f74b52023ee30943b17c5180c8252.png


代码如下所示:

1d26b4c8492d152d4b660800ee812437.png

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

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

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

5ad17e44b08aee88a2eae2340b5c24e0.png

具体代码如下所示:

31897b493678266631aefb874506a6e5.png

3、串口初始化

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

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

b8687c29a8dbb50ffbf39e675a6358f0.png

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

f809a9cdc330fb998de72c572c5e2319.png

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

0abf2a4673b043a2af2bd1736c384980.png

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

8f4408f8ee5a0d926bfd740bcc112d34.png

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

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

9c27d8b9472ecc83857b2fe939fcdf52.png

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

101dffc95c6874b3dc3414feb166e078.png

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

d524583807f064efee8322f94da5f83a.png

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

dec8c498f3db5dc595a3fc68df5fa22b.png
f298912830fc66f96bcd0727aa0409a0.png

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

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

b3cb633ad2d92cebdd772cdd63de4368.png

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

eb1a2befaa287ece864df7f9c2f42956.png

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

2d0e419fe961022d5d141e4fbf3f22a2.png

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

3150dba3b4a3f40dfb47cd432019e32c.png

实现printf函数

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

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

配置非常简单:

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

e907ef818794d30c4690be679b4c3c70.png

2、然后include头文件

65928fe4a50a3517b64f727604a843fc.png

3、实现发送字符的函数

e831045fb0d96305c2037045ba3836fe.png

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

4faf655eb3cbd2a8b693f986b07d2c1a.png

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值