本篇文章将与大家探讨USART波特率 vs SPI速率。这里提出一个问题,为什么USART的波特率是内核时钟的1/8或者1/16,而SPI最快的频率可以是内核时钟的1/2。 请大家带着这个问题来阅读本文。 3 R6 h1 q8 b G7 z! V( m 8 f+ e) m' o8 ]7 S% e/ `; U# L B( m: w * s) j4 U0 g; Q 8 k; {% k2 D' K( A 在回答上面问题之前,需要先了解STM32内部时钟的概念,尤其是串口和SPI的内部时钟。1 b% l4 f, v9 L! K; ?4 U" d c
. e5 ~# ?& H6 \* P& c! J; d 从上图中可以看出,时钟就像流水一样,从时钟源汇聚到系统时钟上,再从系统时钟继续分频或者说是继续分发到AHB、APB。0 S+ L9 E8 [& E$ l% u3 n: [ 通常我们谈论的MCU能跑到多少M、主频多少M,其实所指的就是系统时钟。" ^6 c8 J6 p! |( ]7 m( ~! }$ k7 x. q i' b* h) G 这些时钟在不同的STM32系列中是不一样的,我们以STM32F401为例,手册上说它的APB1的最高时钟是42MHz,APB2的最高时钟是84MHz,不同的外设因为挂在不同的总线上,所以速度就不太相同了。比如USART1挂在APB2上,所以它的时钟最高就是84MHz, USART2是挂在APB1上,它的总线时钟最快就是42MHz。当我们配置串口的时候会发现,USART2的 baudrate 最高是2.625Mbit/s,但是同样配置的USART1却可以达到5.25Mbit/s,这就是因为所在的总线时钟的不同而不同。$ ]* |, ]: s; x9 b串口的过采样技术规范 比如说做数据的接收,我们可以看到串口是通过过采样技术来实现对数据的接收,因为它没有时钟线,只能通过高于波特率的16倍或者8倍对总线上的数据一个一个地进行采集,根据最后采集到的情况来判断信号的状态。 : g% G- Q3 t. b' J9 q 如果3、5、7、8、9、10这六个点都是0,那就可以认为这是一个起始信号;如果在3、5、7和8、9、10这两个阶段都满足至少有两个bit是0的话,那就可以确认它是起始信号,确认的意思是说它里面的接收缓冲区非空,标志位就已经置上了,承认这个信号,但是还要给一个NE的标志位,因为虽然承认了这个信号,但里面是存在噪声的。我们看串口的中断标志位的时候就可以看到,在它的错误事件里就有一个NOISE FLAG,这个位就表示当串口在接收的时候,在总线上检测到的电平并不是一个标准的、完整的高电平或者低电平,会有错误但不影响整个数据的接收,如果在接收的时候开启了EIE位,错误可以产生一个中断,让MCU对总线上的情况有一个了解。我们可以看一下SPI的时序图,图中上面两根线是CLOCK线,它根据配置的不同而不同,在CPHA=0时,即在第一个时钟沿进行采样,CPOL表示的是时钟的默认电平是高电平(CPOL=1)还是低电平(CPOL=0),这里看到的每个时钟都可以传输一个bit。 ' j d _# P2 u7 s) v+ R% q$ H : d" w4 g( O* f" @& h SPI速率是不是应该和系统时钟一样?4 N* ]' P: s( {$ x+ O0 f0 x7 o$ Y, o 其实不是,因为系统需要时间去获取采集到的数据,所以SPI的时钟分频系数最小是二分之一的分频,那么就是说SPI的速度是系统时钟的一半了。5 H' M; S4 D- k7 j- { 有人觉得同步传输明显优于异步传输,因为有时钟线,传输速率会更高。2 O1 A2 Q# Z! d0 `. ] }6 o2 Z |