电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
GD32VF103之串口uart最小配置
分 享
扫描二维码分享
GD32VF103之串口uart最小配置
UART
串口
gcrisis
关注
发布时间: 2020-09-24
丨
阅读: 1725
嵌入式系统中串口是非常重要的接口,除了用于与外设通信外,用它打印log和调试是最常用的手段之一。本文介绍gd32vf103芯片串口的最小配置,并实现printf函数,以方便log打印。串口的配置如下所示: **1、使能串口时钟;** **2、配置串口使用的引脚为AFIO模式;** **3、串口初始化;** **4、通过发送接收寄存器收发数据;** 我这里以串口0为例,其他的串口都是类似的操作。longan nano的串口0位于板子正面的左边。 ![](https://cf05.ickimg.com/bbsimages/202009/c51c1c425a8b293a29eb1ab623864993.png) ##1、使能串口时钟 查阅《GD32VF103_User_Manual_CN_V1.2》可以找到gd32vf103器件的系统架构示意图,从图中我们可以看到串口0挂在APB2上。 ![](https://cf05.ickimg.com/bbsimages/202009/8da797f717e8ce647554d0877471b10f.png) 与前面讲GPIO类似,在手册中找到RCU寄存器一章,然后找到APB2使能寄存器(RCU_APB2EN),它的第14位就是串口0的时钟使能。 ![](https://cf05.ickimg.com/bbsimages/202009/4c87c8435871722e8dc8c960788cbe46.png) 代码如下所示: ![](https://cf05.ickimg.com/bbsimages/202009/4a27f34d48fde9dd5be861695fa627d9.png) ##2、配置串口使用的引脚为AFIO模式 串口0默认用到了GPIOA的9和10引脚(关于gpio的基地址和配置等内容可以查看我的另一篇文章《[Longan nano(GD32VF103)之GPIO最小配置](https://www.icxbk.com/article/detail/1753.html "Longan nano(GD32VF103)之GPIO最小配置")》)。也可以使用重映射功能映射到GPIOB6和7上,关于重映射的内容我会专门写文章介绍。 用作串口通信的Rx和Tx引脚要配置正确,Rx是接收,所以要配置成输入,具体模式我都试过,发现三种(**模拟、浮空、上\下拉**)都可以,一般是**浮空输入**。Tx是发送,所以配置成输出,输出模式必须为**AFIO推挽输出**或者**AFIO开漏输出**。 ![](https://cf05.ickimg.com/bbsimages/202009/404f0d841c5d8302751ce040da388bd0.png) 具体代码如下所示: ![](https://cf05.ickimg.com/bbsimages/202009/377206ca3a0c9f4635087dccb8695a34.png) ##3、串口初始化 我们平时使用串口感觉它很简单,其实不然,串口完整的内容体系还是有一点复杂的。当然我们先不管那么多,让它能够正常收发就可以了。 串口有几个常用参数:**波特率、数据位、校验位、停止位**。使用过串口终端或者串口助手的应该很熟悉。这些都在串口相关寄存器中配置。在《GD32VF103 用户手册》中可以找到串口的所有内容,usart寄存器的基地址如下所示: ![](https://cf05.ickimg.com/bbsimages/202009/38cde3c4001ab3b3cb43ea51de2d46df.png) **波特率寄存器**设置串口通信的波特率,它的地址偏移0x08,寄存器分成了两部分,低四位设置波特率分频器的小数部分,高12位设置波特率分频器的整数部分。 ![](https://cf05.ickimg.com/bbsimages/202009/eaed9df063cf2305a10d68d966cf1c93.png) 这两个值的计算方法在手册中有说明,具体如下: ![](https://cf05.ickimg.com/bbsimages/202009/3207827d8443fd778bec14d0f3fb6a1d.png) 实际代码中不这么计算,而是用下面的公式: ![](https://cf05.ickimg.com/bbsimages/202009/d8ebf06851dd6f48dee869a440309179.png) 这个公式算出的结果可以直接放到波特率寄存器(USART_BAUD)中,它已经包含了移位、小数转换、进位和四舍五入。大家可以自己研究。 数据位和校验位在**控制寄存器0(USART_CTL0)**中设置,数据位通过**bit12**设置,校验位通过**bit9**设置。 ![](https://cf05.ickimg.com/bbsimages/202009/c0980b12270a9d79d1092d4c5b56e5a0.png) 停止位在**控制寄存器1(USART_CTL1)**中设置,通过**bit[13:12]**设置。 ![](https://cf05.ickimg.com/bbsimages/202009/f8025e4a2c8be3c4da1a1a7f5d8391a6.png) 除了波特率我其他都使用默认值,所以没有设置它们。大家可以参考波特率的设置方法设置其他寄存器。 ![](https://cf05.ickimg.com/bbsimages/202009/60f4416d73b7f02ac7ecca3ee17d1ba8.png) 初始化的最后一步就是使能串口和收发了,它们都在**控制寄存器 0 (USART_CTL0)** 中设置,**bit13**使能串口,**bit3**使能发送,**bit2**使能接收。这里要注意,使能要放到最后,因为使能后波特率寄存器、停止位和其他很多寄存器都不能写了。 ![](https://cf05.ickimg.com/bbsimages/202009/bee8fe0934e3bb95ddbab3a5daf1e7f6.png) ![](https://cf05.ickimg.com/bbsimages/202009/9f2a6b1a3c02d4c80cc89ddf21f052a5.png) ##4、通过发送接收寄存器收发数据 初始化完成后就可以通过数据寄存器 (USART_DATA) 读写数据了,它只有低8位有效。 ![](https://cf05.ickimg.com/bbsimages/202009/6fab243298cc2e9954b78913f69280ba.png) 发送时系统会将数据寄存器中的值移到发送移位寄存器中发送,接收时数据会通过接收移位寄存器将数据放到数据寄存器中读取。 ![](https://cf05.ickimg.com/bbsimages/202009/b4c6693f17439a3a8e2345a68b9a155e.png) 数据的发送需要一定的时间,连续发送的太快会导致数据丢失。为了准确判断发送完成没有,就需要用到**状态寄存器 0 (USART_STAT)** ,它提供了各种状态和错误标志,通过这些标志就可以知道串口当前的工作状态。**bit6**是发送完成标志,**bit5**是读数据缓冲区非空标志。通过它们就可以准确控制数据的收发了。 ![](https://cf05.ickimg.com/bbsimages/202009/3d0d845ae4e7627a502e0da2d46b5a1b.png) 我这里使用了轮询的方法,一直while读取标志,实际中发送可以这样做,读取是不行的,否则干不了其他事了。接收由于时间的不确定性一般都使用中断的方式,我们以后介绍完中断再将这里改了。 ![](https://cf05.ickimg.com/bbsimages/202009/40188d0f098607684e5ff55045350994.png) ##实现printf函数 学过c语言的都知道用printf函数打印信息非常方便,在嵌入式系统中尤其如此,所以下面说说怎么在我们上面串口0的基础上实现printf。 很多开发平台只需要重定位printf的输出就可以了,但是vscode+platformio这个我不知道怎么重定位,所以就找了一个printf的实现源码,这个源码实现了基本的功能,而且非常小,很适合嵌入式使用。 配置非常简单: **1、把两个文件添加到工程中** ![](https://cf05.ickimg.com/bbsimages/202009/65ef8ef0d3f179c847c54acd3429eefb.png) **2、然后include头文件** ![](https://cf05.ickimg.com/bbsimages/202009/aa0c2dca9e96a7fc231cef6770407720.png) **3、实现发送字符的函数** ![](https://cf05.ickimg.com/bbsimages/202009/1e3802d6ddfd1c3e88ebd8558579f42e.png) **4、最后初始化一下就可以使用了** ![](https://cf05.ickimg.com/bbsimages/202009/a49aa8e7c202d01c96f5d208f20ad46a.png) 我还没有尝试过它的打印极限,也不知道它有没有bug,以后用着慢慢看吧。 目前我们平台的基础已经搭好了,可以控制gpio、可以延时、可以打印log,以后学习其他模块就要方便很多了。 ![](https://cf05.ickimg.com/bbsimages/202009/c62bceb5541476bbe9182748e76f396b.jpg) ##bilibili同名哟
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
gcrisis
关注
评论
(1)
登录后可评论,请
登录
或
注册
wybliw
200
天前...
感谢分享,赚个积分。
0
回复
发布
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交