您的当前位置:首页SPI接口扫盲SPI定义SPI时序(CPHACPOL)

SPI接口扫盲SPI定义SPI时序(CPHACPOL)

来源:小侦探旅游网
SPI接⼝扫盲SPI定义SPI时序(CPHACPOL)

SPI接⼝扫盲

douqingl@gmail.com

为何要写这篇⽂档?

百度上找出来的SPI接⼝中⽂描述都说的太过简略,没有⼀篇⽂档能够详尽的将SPI介绍清楚的。wikipedia英⽂版[注释1]中,SPI接⼝介绍的很好,但是毕竟是英⽂版,读起来终究不如母语舒服,所以我结合⾃⼰的⼯作经验,对其进⾏了汉化、整理。个⼈SPI接⼝相关经验:

1. 参与过国产某芯⽚SPI接⼝样品验证、SPI接⼝服务DEMO开发(C语⾔)。2. 使⽤国产某芯⽚GPIO接⼝模拟SPI接⼝(C语⾔)。3. 使⽤STM32芯⽚的SPI MASTER/SLAVE(C语⾔)。

SPI接⼝是什么?

SPI ( Serial Peripheral Interface,串⾏外设接⼝)是⼀种同步、串⾏通讯接⼝规格,常⽤于短距离通讯,主要是在嵌⼊式系统中。此接⼝由Mototola公司推出,已成为⼀种事实标准(没有统⼀的协议规范,但是基于其⼴泛的使⽤,根据实际使⽤中⼤家通⽤的习惯形成了⼀个类似⾏规的标准)。

SPI典型的应⽤场景包括SD卡(SD接⼝中包含SPI接⼝)和液晶显⽰。

SPI是⼀种⾼速的,全双⼯,同步的通信总线。分为主(master)、从(slave)两种模式,⼀个SPI通讯系统需要包含⼀个(且只能是⼀个)maser(主设备),⼀个或多个slave(从设备)。

SPI接⼝的读写操作,都是由master发起。当存在多个从设备时,通过各⾃的⽚选(slave select)信号进⾏管理。

硬件开发⼈员设计、提供的SPI接⼝,其实只是⼀个数据读写通道 ,具体读写数据所代表的意义需要在应⽤中定义。不像SD接⼝那样,对于命令有着明确详细的定义。

SPI接⼝都包含哪些IO线?

除了供电、接地两个模拟连接以外,SPI总线定义四组数字信号:

- 接⼝时钟SCLK(Serial Clock,也叫SCK、CLK),master输出⾄slave的通讯时钟。

- MOSI( Master Output Slave Input,也叫SIMO、MTSR、DI、DIN、SI)⾃master输出⾄slave的数据线。

- MISO (Master Input Slave Output,也叫SOMI、MRST、DO、DOUT、SO)⾃slave输出⾄master的数据线。

- SS(Slave select,也叫nSS、CS、CSB、CSN、EN、nSS、STE、SYNC)master对slave的⽚选信号,⾃master输出⾄slave,低有效。注释:

- 两条数据线与SCLK的时序关系详见下⽂。

- SPI接⼝的⽚选信号⼀般都是低有效的,尽管有的地⽅命名为SS/CS⽽有的地⽅命名为nSS/nCS。(当然了,对于⼀个合格的硬件开发者,低电平有效的信号都应该在命名时加上个_n)

SPI接⼝如何连接?

在master/slave上,都能找到SCLK/MISO/MOSI/SS四个接⼝。

当只有⼀个maser、⼀个slave时,将master与slave上名字相同的4对接⼝两两互联,即可完成了接⼝的互联。如下图所⽰:

注释:

- 某些芯⽚产品上,对SPI两条数据线的命名为SDO/SDI。此时需要将master的SDO连接到slave的SDI,将master的SDI连接到slave的SDO。

- 当系统中只有⼀个SLAVE时,且SLAVE的SS是低电平有效时,Slave的SS接⼝直接接地也不影响通讯。当然了,实际应⽤中,如果要考虑到功耗等因素,处理起来或许就不那么简单了,具体问题具体分析。

- 有的芯⽚SPI接⼝的SS信号,对电平敏感,通讯前确保SS是低电平就好;⽽有的SPI芯⽚的SS信号是下降沿敏感的。⽐如MaximMAX1242 ADC,开始通讯前,需要SS信号有⼀个⾼→低的翻转。

- 多数SLAVE的MISO接⼝有三态输出(⾼电平、低电平、⾼阻),当SS⽆效时,它们的MISO信号输出⾼阻态(啥都没接的状态)。若SLAVE的MISO接⼝不⽀持⾼阻输出,则⽆法应⽤于多SLAVE的SPI系统。

当存在⼀个master、多个slave时(注意,当master上有n个SS时,对应可以连接n个slave),连接⽅式如下图所⽰,注意SCLK/MOSI/MISO三个接⼝采取复⽤模式连接,不同SS单独连接对应的slave,SS信号绝不可复⽤:

SPI接⼝如何进⾏数据传输?

SPI接⼝是⼀种典型的全双⼯接⼝,通过同步时钟SCLK的脉冲将数据⼀位位地传送。所以在开始通讯前,master⾸先要配置接⼝时钟(确定其通讯频率是SLAVE可以⽀持的,通常为数兆赫兹)。

当MASTER⽚选⼀个SLAVE时,每向SLAVE发送⼀个周期的SCLK信号,都会有1bit的数据从MOSI发送⾄slave,与此同时,slave每收到⼀个周期的SCLK信号,都会从MISO向master发送1bit的数据。这种全双⼯通讯,是由硬件保证的(MASTER与HOST中各有⼀个移位寄存器作为收发数据的缓存)。

SPI是⼀个很开放的接⼝,指令解析、帧⼤⼩、LSB/MSB(Least Significant Bit/Most Significant Bit)等规则并没有⼀个完善的定义,不同的SPI设备在这些⽅⾯的定义会有不同:

不同于SD等接⼝的严谨的command定义,SPI接⼝的master与slave之间的命令、数据解析都可以⾃定义,只要保证master与slave之间采⽤相同的规则就好。

不同SPI芯⽚,每次连续传输的数据量的⼤⼩(取决于MASTER、SLAVE中缓存最⼩的那个)常常不同。当⼀次连续通讯的的数据量超过帧的⼤⼩时,会出现数据丢失的现象。所以,每完成1帧的传输后,MASTER会停⽌接⼝时钟输出,master、slave读取、处理收到的数据,然后进⾏下⼀帧的传输。

在SPI接⼝协议中,并没有中断的定义,但是实际应⽤中,我们可以使⽤接⼝中断提⾼接⼝通讯速度。⽐如SLAVE是负责数据数据加解密的,MASTER下发⼀组明⽂给SLAVE加密,如果此时有个SLAVE输出到MASTER的中断信号,那么MASTER可以清楚的知道何时SLAVE完成了数据处理并读出处理结果,不必通过查询⼀遍遍的等待结束。

SPI接⼝的变形

以上我们讲的SPI接⼝,⼀个时钟周期可以进⾏全双⼯的1bit数据通讯。实际应⽤中,如果对于全双⼯的需求不⾼,⽽且期望提⾼通讯速度的话,SPI有两种常见变形可供选⽤:⼀、 两线模式的SPI

CLK与SS信号保持不变,MOSI与MISO则变形为DATA_0与DATA_1。

DATA_0与DATA_1是输⼊输出状态由MASTER配置的数据管脚:当MASTER打算向SLAVE中写数据时,处于输出状态;当MASTER打算从SLAVE读数据时,处于输⼊状态。

⼆、 四线模式的SPI

CLK与SS信号保持不变,MOSI与MISO删除,新增四条数据线DATA0~3。

DATA0_~3是输⼊输出状态由MASTER配置的数据管脚:当MASTER打算向SLAVE中写数据时,处于输出状态;当MASTER打算从SLAVE读数据时,处于输⼊状态。

这样⼀来,⼤⼤提⾼了单⽅向上数据传输的速度,但是增加了接⼝资源的开销。

SPI接⼝时序配置

此部分参考crifan的博客。

SPI的接⼝时序配置由两个参数决定:

1、 CPOL,clock polarity,译作时钟极性。2、 CPHA,clock phase,译作时钟相位。CPOL具体说明:

CPOL⽤于定义时钟信号在空闲状态下处于⾼电平还是低电平,为1代表⾼电平,0为低电平。知道这些就好,很简单的⼀个概念 。如果存在疑问,结合下⾯的时序图理解就好。CPHA具体说明:

⾸先,在同步接⼝中,肯定存在⼀个接⼝时钟,⽤来同步采样接⼝上数据的。

CPHA就是⽤来定义数据采样在第⼏个边沿的。为1代表第⼆个边沿采样,为0代表第⼀个边沿采样。以上两个参数,总共有四种组合:

MODE 0: CPOL=0, CPHA=0 ,CLK限制状态为低电平,第⼀个边沿采样,所以是上升沿采样。MODE 1: CPOL=0, CPHA=1,CLK限制状态为低电平,第⼆个边沿采样,所以是下降沿采样。MODE 2: CPOL=1, CPHA=0 ,CLK限制状态为⾼电平,第⼀个边沿采样,所以是下降沿采样。MODE 3: CPOL=1, CPHA=1 ,CLK限制状态为⾼电平,第⼆个边沿采样,所以是上升沿采样。具体见下图。

注意,假设是上升沿采样,那么MISO/MOSI就应该上升沿翻转,这样错开半个时钟周期以保证建⽴时间保持时间。忘了这个的建议去翻翻数电。

由于SPI缺乏⼀个统⼀的规范,所以在时序描述上存在⼀定的差异性。CPOL与CPHA的定义,有些芯⽚DATASHEET中描述与通⽤的规则是相反的,所以选型时候⼀定要以DATASHEET中的时序图为准。

另外,某些芯⽚上,关于SPI接⼝时序不使⽤CPOL/CPHA进⾏定义,⽽是使⽤CKP和CKE进⾏定义,在此不再详细解释这两个概念的意义(⽐较绕,这些参数看多了特容易混淆),建议直接参考时序图。

关于SPI时序的说明,之前我参考了crifan的博客,其中还有个问题待解决:

对于CPOL和CPHA这四种模式,不同的模式之间,相对来说有何优缺点,⽐如是否哪种模式更稳定,数据更不容易出错等等,还是不清楚。

我这⾥给出我的思考结果:

⾸先是CPOL的选择,我们从芯⽚设计⾓度开始谈这个问题。⾸先,如果寄存器赋值时没有特殊要求必须是下降沿触发赋值时,我们会选择上升沿触发,且时钟关闭时固定为低电平。这样⼀来,保证了时钟关闭时漏电最⼩(低电平下没有电压差,减⼩了漏电流IDDQ,同时上升沿触发也保证了来了时钟能够⽴刻采样信号,快速响应)。当然了,如果要求寄存器下降沿采样,那么时钟关闭时固定为⾼电平了。借⽤此思想,对于CPOL的选择,如果配置可以选择的话,我建议参考MASTER与SLAVE接⼝IO的配置参数。如果两边都是上拉,那么建议选择CPOL为1,这样⼀来,当我们配置CPOL时,不会在接⼝上制造出⼀个下降沿(单SLAVE的应⽤场景下,SLAVE的⽚选有时会直接连接GND,⽽此时MASTER本不想通讯但是传⼊了⼀个下降沿,SLAVE那边区分不出来这是不是有效通讯);⽽且这样在IO上的漏电也能有效控制(没有电势差,没有电流)。如果⼀边上拉⼀边下拉,如果从功耗的⾓度考虑,建议选择下拉电阻更⼩(漏电流更⼤)的IO的上下拉配置进⾏CPOL赋值。

关于CPHA的选择,我个⼈更倾向于使⽤CPHA配置为1的状态。此配置下,第⼀个时钟沿驱动数据数据输出,第⼆个时钟沿驱动数据采样,⽐较符合硬件上的使⽤习惯。

当然了,这都是纸上谈兵,很多时候时序类型的选择还要结合芯⽚硬件条件、功能实现需求等问题考虑。

因篇幅问题不能全部显示,请点此查看更多更全内容