本篇文章将与大家探讨USART波特率 vs SPI速率。这里提出一个问题,为什么USART的波特率是内核时钟的1/8或者1/16,而SPI最快的频率可以是内核时钟的1/2。
请大家带着这个问题来阅读本文。
串口和SPI内部时钟
在回答上面问题之前,需要先了解STM32内部时钟的概念,尤其是串口和SPI的内部时钟。
STM32里包含有系统时钟、AHB时钟和APB时钟。APB时钟来源于AHB,AHB时钟来源于系统时钟。
从上图中可以看出,时钟就像流水一样,从时钟源汇聚到系统时钟上,再从系统时钟继续分频或者说是继续分发到AHB、APB。
通常我们谈论的MCU能跑到多少M、主频多少M,其实所指的就是系统时钟。
这些时钟在不同的STM32系列中是不一样的,我们以STM32F401为例,手册上说它的APB1的最高时钟是42MHz,APB2的最高时钟是84MHz,不同的外设因为挂在不同的总线上,所以速度就不太相同了。
比如USART1挂在APB2上,所以它的时钟最高就是84MHz, USART2是挂在APB1上,它的总线时钟最快就是42MHz。
当我们配置串口的时候会发现,USART2的 baudrate 最高是2.625Mbit/s,但是同样配置的USART1却可以达到5.25Mbit/s,这就是因为所在的总线时钟的不同而不同。
那我们怎么知道使用的USART1、USART2到底挂在哪条总线上呢?去从数据手册里寻找,直接在手册里搜索关键词APB1或者APB2就可以快速找到列表。
串口的过采样技术规范
比如说做数据的接收,我们可以看到串口是通过过采样技术来实现对数据的接收,因为它没有时钟线,只能通过高于波特率的16倍或者8倍对总线上的数据一个一个地进行采集,根据最后采集到的情况来判断信号的状态。
举个例子,当我们采集START信号的时候,实际上它要求采集到1110 x0x0x0 000这样固定的序列的时候才认为是一个起始信号。
START信号在串口里是一个bit的低电平信号,我们用16倍的速率进行采样,首先它在前面会做一个下降沿检测,这个检测是要在前面的4个bit能检测到1110,硬件会对总线上的数据根据采样点一直进行检测,这里的采样点就是APB的时钟,串口挂在不同的APB上用的时钟不一样。
采样的时候采集到1110就知道是一个下降沿,后面的x意思是任意的,后面的几个位中至少需要检测到三个0,而最后边的三个位需要是连续的三个0,这样才能被判定是一个起始位。其实只是判断了3、5、7、8、9、10这六个点,只要是0,就可以确认了。这里我们是以START信号为例,其他信号也是这样的。
可能有人会有疑问,x是任意的,不去检测,如果0不满足要求应该怎么办呢?
如果3、5、7、8、9、10这六个点都是0,那就可以认为这是一个起始信号;如果在3、5、7和8、9、10这两个阶段都满足至少有两个bit是0的话,那就可以确认它是起始信号,确认的意思是说它里面的接收缓冲区非空,标志位就已经置上了,承认这个信号,但是还要给一个NE的标志位,因为虽然承认了这个信号,但里面是存在噪声的。
我们看串口的中断标志位的时候就可以看到,在它的错误事件里就有一个NOISE FLAG,这个位就表示当串口在接收的时候,在总线上检测到的电平并不是一个标准的、完整的高电平或者低电平,会有错误但不影响整个数据的接收,如果在接收的时候开启了EIE位,错误可以产生一个中断,让MCU对总线上的情况有一个了解。
如果前三个bit满足条件,而后三个bit没有满足的话,那就说明这个数据是错误的,就不会置标志位了,只要在3、5、7和8、9、10这两个阶段中有一个阶段不满足条件,就不会置位,并且还会有噪声的说明。
当然了,这些都是在检测下降沿没有问题的情况下来说的,如果说在检测下降沿1110都不完整或者是错误的,直接就会回到ideal状态,重新等待下一个数据发送过来。
SPI的速度为什么这么快?
我们可以看一下SPI的时序图,图中上面两根线是CLOCK线,它根据配置的不同而不同,在CPHA=0时,即在第一个时钟沿进行采样,CPOL表示的是时钟的默认电平是高电平(CPOL=1)还是低电平(CPOL=0),这里看到的每个时钟都可以传输一个bit。
SPI速率是不是应该和系统时钟一样?
其实不是,因为系统需要时间去获取采集到的数据,所以SPI的时钟分频系数最小是二分之一的分频,那么就是说SPI的速度是系统时钟的一半了。
有人觉得同步传输明显优于异步传输,因为有时钟线,传输速率会更高。
但其实这种说法并不是完全正确的,因为每一种传输方式都有自己的优势。比如串口有自动波特率的功能,就是说在接收的时候并不知道主机是按照什么样的波特率进行传输的,那就只能等主机发一个特定字节的数据过来并且检测数据的状态,然后自己硬件去设置波特率的寄存器,这样就可以在下一次传输的时候和主机使用相同的波特率。
其次,在不同的温度范围内,内部的RC振荡器是有温漂的并且很大,最标准的校准方法是给它一个时钟沿,但是很多时候并没有这个时钟沿,那我们就可以用自动波特率。
每次通讯的时候都采用自动波特率,就是每次都先接收,接收之后BRR寄存器里面的值就会随着温度的变化发生改变,MCU就可以根据BRR的值来调节HSITRIM。这个方法的好处是不需要提供一个非常标准的时钟,通过串口通讯这种异步的方式就可以把时钟信息传给单片机内部。
学习视频资料
(stm32 USART串口应用)http://www.makeru.com.cn/live/1392_1164.html?s=45051
PWM脉宽调制技术http://www.makeru.com.cn/live/4034_2146.html?s=45051
基于STM32讲解串口操作http://www.makeru.com.cn/live/1758_490.html?s=45051
通过Z-stack协议栈实现串口透传http://www.makeru.com.cn/live/1758_330.html?s=45051
(stm32直流电机驱动)http://www.makeru.com.cn/live/1392_1218.html?s=45051
通信协议 - UART串口协议http://www.makeru.com.cn/live/3576_1437.html?s=45051
stm32之SPI通信http://www.makeru.com.cn/live/3523_1795.html?s=45051
SPI通信协议驱动norFlashhttp://www.makeru.com.cn/live/4034_2151.html?s=45051
学习资料群:830802928
网友评论