stm32之SPI通讯协议

[复制链接]
发表于 2026-1-26 08:50:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

前言

提示:本文紧张用作在学习江科大自化协STM32入门教程后做的归纳总结条记,旨在学习记录,如有侵权请接洽作者
本文紧张探究SPI通讯协议。关于SPI通讯的内容我紧张会分为两大块来讲,第一块,就是先容协议规则,然后用软件模拟的情势来实现协议。第二块,就是先容stm32的SPI外设,然后用硬件来实现协议。

一、SPI通讯协议

1.1 SPI简介

SPI(Serial Peripheral Interface)是由 Motorola 公司开辟的一种通用同步串行数据通讯总线。它是一种广泛用于短间隔通讯的标准接口协议,紧张用于微控制器与外设之间的通讯,如传感器、表现屏、存储器模块等。
下图所示依次为Flash存储器,型号为W25Q64、OLED表现屏、2.4G无线通讯模块,芯片型号为NRF24L01以及Micro SD卡,他们都支持SPI通讯协议。

1.2 SPI通讯特点



  • 同步通讯: SPI 使用主装备(Master)产生的时钟信号(SCK)来同步数据传输,确保主从装备的数据通讯在正确的时钟信号下举行。
  • 全双工通讯: SPI 是全双工通讯协议,可以同时举行数据的发送和吸收。数据在两个方向上通过两条独立的线举行传输,使其可以或许实现高速通讯。
  • 一主多从架构: SPI 通讯支持一个主装备(Master)控制多个从装备(Slave)。主装备通过选择特定的从装备来举行通讯,每个从装备都须要一个独立的从装备选择线(SS,Slave Select)来激活或禁用该装备。
1.3 SPI与I2C对比

以下是SPI与I2C通讯特性的一些对比:
特性SPII2C通讯方式全双工半双工通讯线数4 根 (MOSI, MISO, SCK, SS)2 根 (SDA, SCL)通讯速率高速 (通常可达几 Mbps,部分装备可达几十 Mbps)低速至中速 (通常最高1Mbps,部分装备可达3.4Mbps)协议复杂性较低,不须要所在剖析和握手较高,须要处置处罚器协议的握手、应答信号、所在剖析多装备支持支持,但须要为每个从装备单独设置 SS 线支持,通过 7 位或 10 位所在选择装备总线长度较短,得当短间隔高速通讯较长,可支持长间隔通讯同步时钟是,由 SCK 线提供是,由 SCL 线提供硬件开销较高,须要 4 根线,且多个从装备需额外的 SS 线低,只须要 2 根线和上拉电阻功耗较高,高速通讯下功耗会增长较低,得当低功耗应用主从关系固定的单主多从,主装备控制通讯支持多主多从,主从脚色可动态切换可靠性较低,没有应答机制,无法检测从装备错误较高,具有应答机制,检测和处置处罚错误较为简单实现难度较低,协议简单,实现容易较高,协议复杂,实现较为困难典范应用ADC、DAC、表现器、闪存、传感器、高速外围装备温度传感器、EEPROM、RTC、低速外围装备简而言之就是:
I2C 得当多装备通讯,低功耗和长间隔应用场景,如传感器网络、低速外围装备等。其复杂的协议结构使其在多装备通讯时具有上风,但在高速通讯场景下,SPI 更为得当。
SPI 得当须要高速、全双工通讯的应用场景,得当短间隔、高速的数据传输,如存储器模块、表现屏等。固然它须要更多的通讯线和额外的 SS 线来选择从装备,但其简单性和高速性能使其在及时和高吞吐量应用中表现突出。
二、SPI硬件电路


上图所示为一个典范的SPI应用电路,下面我们来看一下这几根通讯线。


  • SCK(Serial Clock): 串行时钟线,由主装备天生的时钟信号,用于同步数据传输。
  • MOSI(Master Output, Slave Input): 主装备输出、从装备输入线,用于主装备向从装备发送数据。
  • MISO(Master Input, Slave Output): 主装备输入、从装备输出线,用于从装备向主装备发送数据。
  • SS(Slave Select): 从装备选择线,由主装备控制,用于选择和激活特定的从装备。通常为低电平有效。
起首,SCK,时钟线。时钟线完全由主机掌控,以是对于主机来说,时钟线为输出,对于全部从机来说,时钟线都为输入,如许主机的同步时钟就能送到各个从机了。然后是MOSI,主机输出从机输入。数据传输方向是,主机通过MOSI输出,全部的从机通过MOSI输入。接着是MISO,主机输入从机输出。数据传输方向是,全部的从机通过MISO输出,主机通过MISO输入。
那到这里,SCK、MOSI、MISO的链接方式我们就清晰了。
为了确定通讯的目的,主机须要别的引出多条SS控制线,分别接到各从机的SS引脚,主机的SS线都是输出,从机的SS线都是输入。SS线是低电平有效,主机想指定谁就把对应的SS线输出置低电平就行了。比如,主机初始化之后全部的SS都输出高电平,如许就是谁也不指定。假设主机须要和从机1举行通讯,那主机直接将SS1线输出置低电平即可。当主机和从机1通讯完成之后再把SS1置回高电平,如许从机1就知道主机竣事了和我的通讯了。
我们再来看一下SPI的引脚设置:输出引脚设置为推挽输出,输入引脚设置为浮空或上拉输入。
对于输出,我们设置为推挽输出。推挽输出,高低电均匀有很强的驱动本领,这将使得SPI引脚信号的上升以及降落沿都非常敏捷。得益于推挽输出的驱动本领使得SPI信号变革得很快,那自然它也就能到达更高的传输速率了。一样平常SPI都能轻松到达MHz的速率级别。
对比于I2C,I2C降落沿非常敏捷,但是上升沿就比力痴钝了。I2C并不是不想使用更快的推挽输出,而是I2C要实现半双工,常常须要切换输入输出,而且I2C又要实现多主机的时钟同步和总线仲裁,这些功能都不答应I2C使用推挽输出,要否则一不鉴戒就电源短路了。因此,I2C既然选择了更多的功能那就自然要放弃更强的性能了。
注意:在SPI协议里有一条规定,当从机的SS引脚为高电平也就是从机未被选中时,从机的MISO引脚必须切换为高阻态,高阻态就相当于引脚断开,不输出任何电平。在从机的SS线为低电平常,MISO才答应变为推挽输出。如许就可以防止一条线上有多个输出而导致电平辩说的标题了。
总结一下就是:
- 全部SPI装备的SCK、MOSI、MISO分别连在一起。
- 主机别的引出多条SS控制线,分别接到各从机的SS引脚。
- 输出引脚设置为推挽输出,输入引脚设置为浮空或上拉输入。
三、SPI通讯原理

在讲时序单元之前我们先来看一下SPI的移位表现图,它是SPI硬件电路筹划的焦点,只要你把这个移位表现图搞懂了,那无论是上面的硬件电路照旧等会要讲到的软件时序明白起来都会更加轻松。

SPI的根本收发电路就是使用了如许一个移位的模子。左边是SPI主机,内里有一个8位的移位寄存器,右边是SPI从机,内里也有一个8位的移位寄存器。移位寄存器这里有一个时钟输入端,由于SPI一样平常都是高位先行的,以是每来一个时钟移位寄存器都会向左举行移位,从机中的移位寄存器也是同理。移位寄存器的时钟源是由主机提供的,这里叫作波特率发生器。它产生的时钟驱动主机的移位寄存器举行移位,同时这个时钟也通过SCK引脚举行输出接到从机的移位寄存器里。
移位寄存器的接法是,主机移位寄存器左边移出去的数据通过MOSI引脚输入到从机移位寄存器的右边,从机移位寄存器左边移出去的数据通过MISO引脚输入到主机移位寄存器的右边,如许构成一个圈。

接下来我们来分析一下这个电路是怎样工作的。
起首,我们规定波特率发生器时钟的上升沿,全部移位寄存器向左移动一位,移出去的位放在引脚上。波特率发生器时钟的降落沿,引脚上的位采样输入到移位寄存器的最低位。现在我们假设主机有个数据10101010要发送到从机,同时,从机也有个数据01010101要发送到主机。

起首,主机驱动时钟产生一个上升沿,这时移位寄存器中全部的位都向左移动一位,然后从最高位移出去的数据就会被放到通讯线上,数据放到通讯线上现实上是放到了输出数据寄存器。

可以看到,此时MOSI的数据是1,以是MOSI的电平就是高电平,MISO的数据是0,以是MISO的电平就是低电平,这就是第一个时钟上升沿实行的效果。

之后,时钟继承运行,上升沿之后下一个边沿就是降落沿。在降落沿时主机和从机内都会举行数据采样输入。即MOSI的1会采样输入到从机移位寄存器的最低位,MISO的0会采样输入到主机移位寄存器的最低位,这就是第一个时钟竣事后的效果。

那下一个时钟继承运行,下一个上升沿同样的操纵,移位输出,随后,降落沿,数据采样输入。云云循环8个时钟即可完成一个字节的数据互换,互换的效果是主机的数据10101010发送到了从机的移位寄存器里,从机的数据01010101发送到了主机的移位寄存器里来,这就实现了主机和从机一个字节数据的互换了。现实上,SPI的运行过程就是如许,SPI的数据收发都是基于字节互换这个根本单元来举行的。

简而言之就是,SPI通讯的底子是互换一个字节,有了互换一个字节就可以实现发送一个字节、吸收一个字节以及发送同时吸收一个字节这三种功能。
四、SPI时序单元

接下来我们来看一下数据传输的根本时序单元,这个根本时序单元就是创建在我们刚刚讲过的移位模子上的。那么这个根本单元什么时间开始移位?是上升沿移位照旧降落沿移位的呢?这些SPI都没有限定死而是给了我们可以设置的选择,如许的话SPI就可以兼容更多的芯片。
SPI有两个可以设置的位,分别叫作 CPOL(Clock Polarity,时钟极性) 和 CPHA(Clock Phase,时钟相位) ,CPOL 和 CPHA 是用于控制SPI总线数据采样和数据发送时序的两个关键设置,这两个参数决定了数据与时钟信号的关系,影响数据的采样和传输机会。
CPOL决定了SPI通讯中空闲状态下时钟信号SCK的电平状态。当时钟信号没有举行数据传输时(空闲状态),SCK可以处于高电平或低电平,这由CPOL来决定。当CPOL = 0时,表现为空闲时SCK保持低电平,当CPOL = 1时,表现为空闲时SCK保持高电平。
CPHA决定了数据采样的机会,控制在时钟的哪个边沿举行数据采样。当CPHA = 0时,表现数据在第一个时钟边沿采样,当CPHA = 1时,表现数据在第二个时钟边沿采样。
如下表所示,CPOL和CPHA的差异组合决定了SPI通讯的4种模式,每种模式界说了时钟和数据的同步方式。
模式CPOLCPHA时钟空闲时SCK电平SCK第一个边沿SCK第二个边沿模式000低电平移入数据移出数据模式101低电平移出数据移入数据模式210高电平移入数据移出数据模式311高电平移出数据移入数据固然模式有四种,但是它们的功能是一样的,在现实使用中模式0的应用是最多的,其他模式到时间用到了再返来查表就行了。ok,废话不多说,让我们先来看一下第一个根本时序单元吧。
4.1 起始和制止条件


起始条件:SS从高电平切换到低电平
制止条件:SS从低电平切换到高电平

简而言之就是SS低电平选中从机,然后SS低电平期间表现正在通讯,SS高电平竣事通讯。
4.2 互换一个字节(模式1)

这个时序的根本功能是互换一个字节,接下来我们详细分析一下这个时序。

CPOL=0:空闲状态时,SCK为低电平。
CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据。

起首是SS,从机选择。在通讯开始前,SS为高电平,在通讯过程中SS始终保持为低电平,通讯竣事SS规复为高电平。
再来看一下MISO,主机输入从机输出。由于有多个从机输出毗连了在一起,假如同时开启输出容易造成辩说。以是我们的办理方案是,在SS未被选中的状态下从机的MISO引脚必须关断输出,即设置输出为高阻状态。那在这里,SS高电平常,MISO用一条中心的线表现为高阻态。SS降落沿之后,从机的MISO被答应开启输出。SS上升沿之后,从机的MISO必须置回高阻态。
接下来我们看一下移位传输的操纵。SCK第一个边沿,也就是上升沿,主机和从机同时移出数据,主机通过MOSI移出最高位,此时MOSI的电平就表现了主机密发送数据的B7。从机通过MISO移出最高位,此时MISO的电平表现从机密发送数据的B7。然后时钟运行产生降落沿,此时主机和从机同时移入数据,也就是举行数据采样,主机移出的B7进入从机移位寄存器的最低位,从机移出的B7进入主机移位寄存器的最低位。
如许,一个时钟脉冲产生完毕,一个数据位也就传输完毕了。接下来就是同样的流程重复8次,如许一个字节的数据互换就完成了。如果主机只想互换一个字节,那这时就可以把SS重新置回高电平竣事通讯了。
4.3 互换一个字节(模式0)


CPOL=0:空闲状态时,SCK为低电平
CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据

模式0和模式1的区别,在时序上来看,模式0的数据移出移入的时机会比模式1提前半个时钟,也就是相位提前了。
模式0在SCK第一个边沿就要移入数据,但数据总得先移出再移入对吧?以是在模式0的设置下,SCK在第一个边沿之前就要提前开始移出数据了。以是趁SCK还没有变革,SS降落沿时,就要立即触发移位输出。以是这里MOSI和MISO的输出是对齐到SS的降落沿的,大概说这里把SS的降落沿也看成时钟的一部分了。那SS降落沿触发了输出,SCK上升沿就可以采样输入数据了,如许B7就传输完毕。之后,SCK降落沿,移出B6,SCK上升沿,移入B6,然后继承,降落沿移出数据,上升沿移入数据,终极在第8个上升沿时B0位移入完毕,整个字节互换完成。
之后,SCK另有一个降落沿,如果主机只须要互换一个字节就竣事的话,那在这个降落沿时MOSI可以置回默认电平大概不去管它。MISO也会变革一次,SS上升沿之后,从机的MISO置回高阻态,这就是SPI互换一个字节模式0。
总结一下就是,模式0和模式1的区别就在于,模式0把这个数据变革的机会给提前了。在现实应用中模式0的应用是最多的,以是我们重点把握模式0即可。
4.4 互换一个字节(模式2和3)

1. 互换一个字节(模式2)

CPOL=1:空闲状态时,SCK为高电平
CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据

2. 互换一个字节(模式3)

CPOL=1:空闲状态时,SCK为高电平
CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据

五、SPI时序

SPI对字节流功能的规定不像I2C那样,I2C的规定一样平常是,有效数据流第一个字节是寄存器所在,之后依次是读写的数据,使用的是读写寄存器的模子,而在SPI中通常接纳的是指令码加读写数据的模子。这个过程就是,SPI起始后第一个互换发送给从机的数据一样平常叫作指令码,在从机中对应的会界说一个指令集,当我们须要发送什么指令时就可以在起始后第一个字节发送指令集内里的数据,如许就能引导从机完成相应的功能了。
差异的指令可以有差异的数据个数,有的指令只须要一个字节的指令码就可以完成,比如W25Q64的写使能、写失能等指令。而有的指令背面就须要再跟读写的数据,比如W25Q64的写数据、读数据等。写数据,指令背面就得跟上写入的所在和数据,读数据,指令背面就得跟上读取的所在,这就是指令码加读写数据的模子。
由于每个芯片对SPI时序字节流功能的界说都不一样,在这里我们就以读写W25Q64存储器为例举行讲授。
5.1 发送指令

这个时序的功能是向SS指定的装备发送指令(0x06)
在这里我们使用的是SPI的模式0,模式0的规定是:
CPOL=0:空闲状态时,SCK为低电平
CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据

在W25Q64内里,0x06表现的是写使能。下图所示,由上至下依次为SS、SCK、MOSI、MISO,赤色竖线用于隔断时序单元,绿色竖线用于标志读取数据的时间。

在空闲状态时,SS为高电平,SCK为低电平,MOSI和MISO的默认电平没有严格规定。
起首,SS产生降落沿,时序开始。 在这个降落沿时间MOSI和MISO就要开始变动数据了。由于MOSI指令码最高位依然是0,以是这里保持低电平稳定。MISO,从机现在没有数据发给主机,引脚电平没有变革(现实上W25Q64不须要回传数据时手册里规定的是MISO仍然是高阻态,从机并没有开启输出,这里由于STM32的MISO是上拉输入,以是这里MISO出现高电平)
然后,SCK第一个上升沿,举行数据采样。 从机采样输入得到0,主机采样输入得到1。接着,SCK第一个降落沿,举行数据输出。 主机输出0,从机输出1。再接着,SCK第二个上升沿,举行数据采样,然后SCK第二个降落沿,举行数据输出 … 云云循环8次,在SCK第八个上升沿时完成一个字节数据互换。
末了,在SCK降落沿之后SS置回高电平,竣事通讯。
本次通讯的效果就是,主机用0x06换来了从机的0xFF。固然现实上从机并没有输出,这个0xFF是默认的高电平,不外这个0xFF没故意义,我们可以不管它,这就是发送单字节指令的时序了。
5.2 指定所在写

这个时序的功能是向SS指定的装备,发送写指令(0x02),随后在指定所在(Address[23:0])下,写入指定命据(Data)
注意:这里的所在是24位3个字节的

指定所在写的时序跟上面我们讲的发送指令实在原理是差不多的。这些时序都是由一个个互换字节的时序单元构成的,差异的只是比如说上面发送指令之后就完事了,而这里是发送完指令之后要一连发送三个字节的所在指定写的位置,然后再发送一个写入的一个字节数据就行了,末了如果不想继承写就直接将SS置回高电平竣事通讯即可。
注意:SPI里也会有跟I2C一样的所在指针,每读写一个字节,所在指针自动加1。如果发送一个字节之后不制止,继承发送的字节就会依次写入到后续的存储空间里,如许就可以实现从指定所在开始写入多个字节了。

终极这条时序实现的功能就是在指定所在0x123456下写入数据0x55。
5.3 指定所在读

向SS指定的装备,发送读指令(0x03),随后在指定所在(Address[23:0])下,读取从机数据(Data)

同样的套路,起始之后主机发送的第一个字节0x33表现要读取数据,之后照旧一样,主机依次互换三个字节所在,分别是0x12、0x34、0x56,组合到一起就是0x123456,代表24位所在。
紧接着,关键点来了,由于我们是要读取数据,指定所在之后显然我们就要开始吸收数据了,我们须要恣意发送一个数据举行互换(固然也不是恣意发的,我们一样平常会发0XFF),然后从机就会把0x123456所在下的一个字节数据互换过来。如下所示,我们用0xFF跟从机互换了0x55,如果我们想要一连读取多个字节也是一样的原理,这里的指针每读取一次就会自动加1,这里我就不再累述了。

末了,如果主机不想继承读取数据了就可以把SS置回高电平,竣事本次通讯。这条时序终极的效果是,主机读取到从机0x123456所在下的数据为0x55。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表