串口最基本的设置,就是波特率的设置。 STM32F4 的串口使用起来还是蛮简单的,只要你开启了串口时钟,并设置相应 IO 口的模式,然后配置一下波特率,数据位长度,奇偶校验位
等信息,就可以使用了 。
1,串口时钟使能。串口作为 STM32F4 的一个外设,其时钟由外设时钟使能寄存器控制,这里我们使用的串口 1 是在 APB2ENR 寄存器的第 4 位。 APB2ENR 寄存器在之前已经介绍过
了,这里不再介绍。只是说明一点,就是除了串口 1 和串口 6 的时钟使能在 APB2ENR 寄存器,其他串口的时钟使能位都在 APB1ENR 寄存器。
2,串口波特率设置。 每个串口都有一个自己独立的波特率寄存器 USART_BRR,通过设置该寄存器就可以达到配置不同波特率的目的。其各位描述如图 5.3.2.1 所示:
STM32F4 的分数波特率概念,其实就是在这个寄存器(USART_BRR) 里面体现的。 USART_BRR 的最低 4 位(位[3:0],当 OVER8=0 时) 用来存放小数部分 DIV_Fraction,
紧接着的 12 位(位[15: 4]) 用来存放整数部分 DIV_Mantissa,最高 16 位未使用。
这里,我们简单介绍一下波特率的计算, STM32F4 的串口波特率计算公式(OVER8=0)如下:
上式中, f是给串口的时钟(PCLK1 用于 USART2~5, PCLK2 用于 USART1 和USART6); USARTDIV 是一个无符号定点数。我们只要得到 USARTDIV 的值,就可以得到串
口波特率寄存器 USART1->BRR 的值,反过来,我们得到 USART1->BRR 的值,也可以推导出USARTDIV 的值。但我们更关心的是如何从 USARTDIV 的值得到 USART_BRR 的值,因为一
般我们知道的是波特率,和 PCLKx 的时钟,要求的就是 USART_BRR 的值。
下面我们来介绍如何通过 USARTDIV 得到串口 USART_BRR 寄存器的值。 假设我们的串口 1 要设置为 115200 的波特率,而 PCLK2 的时钟(即 APB2 总线时钟频率) 为 84M。这样,
我们根据上面的公式有:
USARTDIV=84000000/(115200*16)=45.572
那么得到:
DIV_Fraction=16*0.572=9=0X09;
DIV_Mantissa=45=0X2D;
这样,我们就得到了 USART1->BRR 的值为 0X2D9。只要设置串口 1 的 BRR 寄存器值为0X2D9 就可以得到 115200 的波特率。
3,串口控制。 STM32F4 的每个串口都有 3 个控制寄存器 USART_CR1~3,串口的很多配置都是通过这 3 个寄存器来设置的。这里我们只要用到 USART_CR1 就可以实现我们的功能了,
该寄存器的各位描述如图 9.1.1 所示:
STM32F4 多了一个接收器过采样设置位: OVER8 位,该位在USART_CR1 寄存器里面设置,当 OVER8=0 的时候,采用 16 倍过采样,可以增加接收器对时
钟的容差。当 OVER8=1 的时候,可以获得更高的速度。简单说,就是 OVER8=0 时精度高,容错性好, OVER8=1 的时候,容错差,但是速度快。 这里我们一般设置 OVER8=0,以得到更
好的容错性,以下皆以 OVER8=0 进行介绍。关于 OVER8 的详细介绍,请看《STM32F4xx 中文参考手册》第 26.3.3 节。
该寄存器的高16位没有用到,低16位用于串口的功能设置。OVER8为过采样模式设置位,我们一般设置位 0,即 16 倍过采样已获得更好的容错性; UE 为串口使能位,通过该位置 1,
以使能串口; M 为字长选择位,当该位为 0 的时候设置串口为 8 个字长外加 n 个停止位,停止位的个数(n)是根据 USART_CR2 的[13:12]位设置来决定的,默认为 0; PCE 为校验使能位,
设置为 0,则禁止校验,否则使能校验; PS 为校验位选择位,设置为 0 则为偶校验,否则为奇校验; TXIE 为发送缓冲区空中断使能位,设置该位为 1,当 USART_SR 中的 TXE 位为 1 时,
将产生串口中断; TCIE 为发送完成中断使能位,设置该位为 1,当 USART_SR 中的 TC 位为 1时,将产生串口中断; RXNEIE 为接收缓冲区非空中断使能,设置该位为 1,当 USART_SR 中
的 ORE 或者 RXNE 位为 1 时,将产生串口中断; TE 为发送使能位,设置为 1,将开启串口的发送功能; RE 为接收使能位,用法同 TE。
其他位的设置,这里就不一一列出来了,大家可以参考《STM32F4XX 中文参考手册》第714 页有详细介绍,在这里我们就不列出来了。
4,数据发送与接收。 STM32F4 的发送与接收是通过数据寄存器 USART_DR 来实现的,这 是一个双寄存器,包含了 TDR 和 RDR。当向 DR 寄存器写数据的时候,实际是写入 TDR,串
口就会自动发送数据; 当收到数据, 读 DR 寄存器的时候,实际读取的是 RDR。 TDR 和 RDR对外是不可见的,所以我们操作的就只有 DR 寄存器, 该寄存器的各位描述如图 9.1.2 所示:
可以看出,虽然是一个 32 位寄存器,但是只用了低 9 位(DR[8:0]),其他都是保留。DR[8:0]为串口数据,包含了发送或接收的数据。由于它是由两个寄存器(TDR 和 RDR)组
成的,一个给发送用(TDR),一个给接收用(RDR),该寄存器兼具读和写的功能。 TDR 寄存器提供了内部总线和输出移位寄存器之间的并行接口。 RDR 寄存器提供了输入移位寄存器和内部
总线之间的并行接口。
当使能校验位(USART_CR1 中 PCE 位被置位)进行发送时,写到 MSB 的值(根据数据的长度不同, MSB 是第 7 位或者第 8 位)会被后来的校验位取代。当使能校验位进行接收时,读到
的 MSB 位是接收到的校验位。
5,串口状态。串口的状态可以通过状态寄存器 USART_SR 读取。 USART_SR 的各位描述如图 9.1.3 所示:
这里我们关注一下两个位,第 5、 6 位 RXNE 和 TC。
RXNE(读数据寄存器非空),当该位被置 1 的时候,就是提示已经有数据被接收到了,并且可以读出来了。这时候我们要做的就是尽快去读取 USART_DR,通过读 USART_DR 可以将
该位清零,也可以向该位写 0,直接清除。TC(发送完成),当该位被置位的时候,表示 USART_DR 内的数据已经被发送完成了。如
果设置了这个位的中断,则会产生中断。该位也有两种清零方式: 1)读 USART_SR,写USART_DR。 2)直接向该位写 0。
通过以上一些寄存器的操作外加一下 IO 口的配置,我们就可以达到串口最基本的配置了,关于串口更详细的介绍,请参考《STM32F4XX 中文参考手册》第 676 页至 720 页,通用同步。