通用同步异步收发器(USART)在大部分STM32程序中都会用上,无论是功能需要,要求板子与外部设备通信,还是用于程序的调试,都离不开USART。 既然用的这么广,我们就先看看如何在寄存器模式下使用它。 那首先就是要知道它的寄存器咯 (
有七个寄存器,分别是:状态寄存器(SR),数据寄存器(DR),波特率寄存器(BRR),控制寄存器1(CR1),控制寄存器2(CR2),控制寄存器3(CR3),还有一个保护时间和预分频寄存器(GTPR),它们的作用大家一看就知道了,最后一个寄存器可以暂时不用管,先看看它的控制寄存器 USART1_CR1 位 15 OVER8:过采样模式 (Oversampling mode)
0: 16 倍过采样
1: 8 倍过采样 | 位 13 UE: USART 使能 (USART enable)
该位清零后, USART 预分频器和输出将停止,并会结束当前字节传输以降低功耗。此位由软
件置 1 和清零。
0:禁止 USART 预分频器和输出
1:使能 USART | 位 12 M:字长 (Word length)
该位决定了字长。该位由软件置 1 或清零。
0: 1 起始位, 8 数据位, n 停止位
1: 1 起始位, 9 数据位, n 停止位 | 位 10 PCE:奇偶校验控制使能 (Parity control enable)
该位选择硬件奇偶校验控制(生成和检测)。使能奇偶校验控制时,计算出的奇偶校验位被
插入到 MSB 位置(如果 M=1,则为第 9 位;如果 M=0,则为第 8 位),并对接收到的数据
检查奇偶校验位。此位由软件置 1 和清零。一旦该位置 1, PCE 在当前字节的后面处于活动
状态(在接收和发送时)。
0:禁止奇偶校验控制
1:使能奇偶校验控制 | 位 9 PS:奇偶校验选择 (Parity selection)
该位用于在使能奇偶校验生成/检测(PCE 位置 1)时选择奇校验或偶校验。该位由软件置 1 和
清零。将在当前字节的后面选择奇偶校验。
0:偶校验
1:奇校验
|
位 3 TE:发送器使能 (Transmitter enable)
该位使能发送器。该位由软件置 1 和清零。
0:禁止发送器
1:使能发送器
| 位 2 RE:接收器使能 (Receiver enable)
该位使能接收器。该位由软件置 1 和清零。
0:禁止接收器
1:使能接收器并开始搜索起始位 |
USART_CR2 位 13:12 STOP:停止位 (STOP bit)
这些位用于编程停止位。
00: 1 个停止位
01: 0.5 个停止位
10: 2 个停止位
11: 1.5 个停止位
注意: 0.5 个停止位和 1.5 个停止位不适用于 UART4 和 UART5。 |
USART_CR3 位 11 ONEBIT:一个采样位方法使能 (One sample bit method enable)
该位允许用户选择采样方法。选择一个采样位方法后,将禁止噪声检测标志 (NF)。
0:三个采样位方法
1:一个采样位方法 |
这里并没有列出它的中断使能位,中断放在下一篇进行探讨。 USART_SR 位 7 TXE:发送数据寄存器为空 (Transmit data register empty)
当 TDR 寄存器的内容已传输到移位寄存器时,该位由硬件置 1。如果 USART_CR1 寄存器
中 TXEIE 位 = 1,则会生成中断。通过对 USART_DR 寄存器执行写入操作将该位清零。
0:数据未传输到移位寄存器
1:数据传输到移位寄存器
注意: 单缓冲区发送期间使用该位 | 位 6 TC:发送完成 (Transmission complete)
如果已完成对包含数据的帧的发送并且 TXE 置 1,则该位由硬件置 1。如果 USART_CR1 寄存
器中 TCIE = 1,则会生成中断。该位由软件序列清零(读取 USART_SR 寄存器,然后写入
USART_DR 寄存器)。 TC 位也可以通过向该位写入‘0’来清零。建议仅在多缓冲区通信
时使用此清零序列。
0:传送未完成
1:传送已完成 | 位 5 RXNE:读取数据寄存器不为空 (Read data register not empty)
当 RDR 移 位 寄 存 器 的 内 容 已 传 输 到 USART_DR 寄 存 器 时,该 位 由 硬 件 置 1。如 果
USART_CR1 寄存器中 RXNEIE = 1,则会生成中断。通过对 USART_DR 寄存器执行读入
操作将该位清零。 RXNE 标志也可以通过向该位写入零来清零。建议仅在多缓冲区通信时使
用此清零序列。
0:未接收到数据
1:已准备好读取接收到的数据 |
USART_DR 数据寄存器只有8位有效位,31-9都是保留位。 数据寄存器包含两个寄存器,一个用于发送(TDR),一个用于接收(RDR),但是我们只能看到一个,就是(DR),因此它具有双重功能(读和写),DR具体代表哪一个寄存器取决于所执行的操作是“读取”还是“写入”。 USART是通过GPIO与外部连接的,那对应的引脚就复用了特定的功能。 我们从参考手册中可以找到相应的描述 说了这么多,我们来看看代码(我的板卡只引出了USART6) - void usart_init(uint32_t brr)
- {
- RCC->APB2ENR |= 0x01<<5; //开启USART6的时钟
-
- USART6->CR1 &= ~(0x01<<15|0x01<<13|0x01<<12|0x01<<10|0x01<<3|0x01<<2);
- USART6->CR1 |= (0x01<<13|0x01<<3|0x01<<2);
- USART6->CR2 &= ~(0x03<<12);
- USART6->CR3 &= ~(0x01<<11);
- USART6->BRR = 16000000/brr;
- }
复制代码对应参考手册,我们知道这几行代码将USART6的控制寄存器进行了以下配置: 16倍过采样 使能USART 1 起始位, 8 数据位,n 停止位 禁止奇偶校验控制
使能发送器 使能接收器并开始搜索起始位 1 个停止位
三个采样位方法 最后一个寄存器BRR配置的是USART6的波特率,形参brr就是波特率值,例如9600,115200等值。 往BRR这个寄存器中写入的值是怎么算的呢,参考手册上有一个公式 其中OVER8是过采样模式,我们采用的是16倍过采样(至于什么是16倍过采样,看参考手册吧),所以OVER8为0,fck是APB2总线时钟频率,简化之后便是: 波特率 = fck/(16*USARTDIV) USARTDIV 是一个存放在 USART_BRR 寄存器中的无符号定点数(USARTDIV是个浮点数)。 我们再看看波特率寄存器是什么样子的。 参考手册上说,寄存器的低四位是用来存放USARTDIV的小数部分,15-4是用来存放USARTDIV的整数部分,好像有点懵逼,再说小数怎么存进去,不知道怎么做可以看看别人是怎么做的呀。 正点原子是将小数部分乘以16(转16进制)再加上整数部分左移4位,之后写入BRR寄存器中的,这里好像可以发现点什么,整数左移4位不也相当于乘以16吗?小数乘以16后加上整数乘上16,再加上之前的波特率计算公式,不就相当于: 波特率 = fck/写入BRR中的值 将公式变换一下,就得到: 写入BRR中的值 = fck/波特率 这就尴尬了,绕了这么一圈。 这只是进行了USART6的相关配置,USART是通过GPIO与外部设备连接的,那肯定是要对相应的引脚进行配置了,
从数据手册中我们找到了,能复用为USART6-RX和TX的引脚分别为PG9和PG14,接着便是初始化 这段初始化程序和前面不同的地方在于,它配置了AFR寄存器 AFR寄存器分为AFRL和AFRH(程序中的结构体将其封装为一个具有两个元素的数组),四个位控制一个引脚,共有16种复用功能。从上面的图2和图3了解到复用为USART6是AF8,所以程序便是将相应为上清零,并写入相应数值。 到这,我们只要写好发送和接收函数就可以进行简单的收发了 来张效果图
这篇帖子只是对USART进行简单的配置和应用,但是并没有将USART的问题讲述清楚,还有时钟、中断等问题,后续再更
|