一、SPI简介(serial Peripheral Interface(串行 外设 接口))
1、电路模式(采用一主多从的模式)、同步,全双工
1 所有SPI设备的SCK、MOSI、MISO分别连在一起
2 主机另外引出多条SS控制线,分别接到各从机的SS引脚
3 输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入
4 推挽输出:高低电平都有很强的驱动能力,使得SPI引脚信号的下降沿和上升沿非常迅速
5 (IIC因为要实现半双工,经常切换输出输入,IIC又要实现多主机的时钟同步和总线仲裁,若使用推挽输出任意电源短路)
6 SPI的MISO可能有冲突,一位内主机是输入,三个从机都是输出,若三个从机始终是推挽输出,势必会导致冲突。
故SPI有个规定:
当从机的SS引脚为高电平时,即从机未被选中,其MISO引脚必须切换成高阻态,高阻态相当于引脚断开,不输出任何电平,这样可以防止一条线有多个输出,导致电平冲突问题
SS为低电平时,MISO才允许变为推挽输出(切换在从机中,不需要关注)
2、4条信号线
1 SS(片选信号线(理解为从机选择线)、Slave Select):单片机通过给片选信号线高低电平来确定哪一个从机通讯,一般当这根线为低电平时,片选才有效
2 SCK(时钟信号线、Serial Clock):主设备产生
3 MOSI(发送信号线、Master Output Slave Input):主设备从MOSI输出数据,而从设备通过MOSI接收数据
4 MISO(接收信号线、Master Input Slave Output):主设备通过这根线接收数据
3、通信过程
同步,肯定有时钟,因此,SCK引脚就是用来提供时钟信号的。数据位的输出和输入都是SCK的上升沿和下降沿进行的。这样数据位的收发时刻就可以明确的确定。
全双工:数据发送和数据接收单独各占一条线。MOSI和MISO就是分别用于发送和接收的两条线路。MOSI是主机输出从机输入,主机向从机发送数据的线路。MISO就是主机从从机接收数据的线路。
SPI:仅支持一主多从,不支持多主机。I2C太麻烦,直接开辟一条通讯线,专门用来指定我要跟哪个从机进行通信,即SS从机选择线。
I2C:实现一主多从的方式是在其实条件下,主机必须先发送一个字节进行寻址,用来指定我要跟哪个从机进行通信。所以I2C要涉及分配地址和寻址的问题。
4、SPI的硬件规定、SPI的软件规定
主机:stm32
从机:存储器、显示屏、通信模块、传感器等
SPI所有通信线都是单端信号,它们的高低电平都是相对GND的电压差,所以单端信号,所有设备还需要共地。
如果从机没有独立供电,主机需要额外引出电源正极VCC给从机供电。
SCK:时钟线完全由主机掌控,所以对于主机来说,时钟线为输出,对于所有从机来说,时钟线为输入。这样主机的同步时钟,就能送到各个从机
MOSI:主机输出,从机输入
MISO:主机输入,从机输出
SS:低电平有效,主机想指定谁,就把对应的SS输出线置低电平。比如,主机初始化,所有SS线都置高电平(谁也不指定)
输出引脚:推挽输出,高低电平均有很强的驱动能力,这将使得SPI引脚信号的下降沿和上升沿非常迅速,不像I2C下降沿非常迅速,但是下降沿就非常缓慢。SPI信号变化快,自然它就能达到更高的传输速度。一般SPI信号都能轻松达到MHz的速度级别。I2C并不是不想使用更快的推挽输出,而是I2C要实现半双工,经常要切换输入输出,而且I2C又要实现多主机的时钟同步和总线仲裁,这些功能都不允许I2C使用推挽输出。(否则容易导致电源短路,I2C选择更多的功能,自然放弃更强的性能)
输入引脚:浮空或上拉输入
SPI有个缺点:如果三个从机始终都是推挽输出,主机一个是输入,势必会导致冲突。规定:当从机的SS引脚为高电平时,也就是从机未被选中,它的MISO引脚必须切换为高阻态,高阻态就相当于引脚断开,不输出任何电平。这样就可以防止一条线有多个输出,而导致的电平冲突的问题。在SS为低电平时,MISO才允许变为推挽输出。
5、I2C和SPI的比较
(1)I2C
1、I2C在硬件和软件电路设计都比较复杂,但可在消耗最低硬件资源的情况下,实现最多的功能
2、由于I2C开漏外加上拉电阻的电路结构,使得通信线高电平的驱动能力比较弱,这会导致通信线由低电平变到高电平的时候,上升沿耗时比较长,限制了IIC的最大通信速度
3、故IIC的标准模式只有100kHz的时钟频率,快速模式只有400kHz
(2)SPI
1、SPI传输更快,没有严格规定最大传输速度,最大传输速度取决于芯片厂商的设计需求,即看手册
2、SPI的设计比较简单粗暴,实现的功能没IIC多,硬件开销比较大,通行线的个数比较多哈,并且通行过程中,经常会有资源浪费的现象
3、SPI的风格:最简单最快速的完成任务,没有应答机制
6、移位示意图(SPI核心)
左边是SPI主机,里面有一个8位的移位寄存器,右边是SPI从机,里面也有一个8位的移位寄存器。移位寄存器有一个时钟输入端,因为SPI一般是高位先行,因此,每来一个时钟,移位寄存器都会向左进行移位。移位寄存器的时钟源是由主机提供的(这里叫做波特率发生器),它产生的时钟驱动主机的移位寄存器进行移位。同时这个时钟也通过SCK引脚进行输出,接到从机的移位寄存器里。
组成一个圈
主机移位寄存器左边移出去的数据,通过MOSI引脚输入到从机移位寄存器的右边。
从机移位寄存器左边移出去的数据,通过MISO引脚输入到主机移位寄存器的右边。
(1)SPI的基础是交换一个字节
SPI通信的基础是交换一个字节,从而可以实现①发送一个字节,②接收一个字节和③发送同时接收一个字节三种功能。
(2)SPI时序基本单元
交换一个字节(模式0)(应用最多)
CPOL=0(时间极性):空闲状态时,SCK为低电平
CPHA=0(时钟相位):SCK第一个边沿移入数据,第二个边沿移出数据
四个模式
模式0:CPOL=0:空闲SCK为0,CPHA=0:SCK第一个边沿移入数据,第二个边沿移出
模式1:CPOL=0:空闲SCK为0,CPHA=1:SCK第一个边沿移出数据,第二个边沿移入
模式2:CPOL=0:空闲SCK为1,CPHA=0:SCK第一个边沿移入数据,第二个边沿移出
模式3:CPOL=0:空闲SCK为1,CPHA=1:SCK第一个边沿移出数据,第二个边沿移入
上述MOSI、MISO为两条线表示发送的既有可能是高电平又有可能是低电平
7、SPI完整的时序波形(基于W25Q64)
I2C中,有效数据流第一个字节是寄存器地址,之后依次是读写的数据,使用的是读写寄存器的模型。
SPI中,通常采用的是指令码加读写数据的模型。
SPI起始后,第一个交换发送给从机的数据,一般叫做指令码,在从机中,对应会定义一个指令集,当我们需要发送什么时,就可以在起始后第一个字节发送指令集里面的数据。
在W25Q64里,0X06代表的是写使能,在这里使用SPI模式0,在空闲状态,SS为高电平,SCK为低电平,MOSI和MISO电平没有严格规定。然后,SS产生下降沿,时序开始,在这个下降沿时刻,MOSI和MISO就要开始变换数据。
SCK低电平是数据变化的时期,高电平是读取数据的时期
以下:主机用0x06换来从机0xFF,但是实际上从机并没有输出,0XFF是默认高电平。 那整个时序的功能就是发送指令,指令码是0x06,从机比对后事先定义好的指令集,发现0x06是写使能的指令,那从机就会控制硬件进行写使能。这样一个指令从发送到执行就完成了。
1、发送指令(实现向从机的0x123456的地址上发送0x55)
(1)主机向SS指定的设备发送指令码0x06(写使能的指令)
(2)发送指令0x02,表示要写入
(3)指定地址0x123456:发送0x12(高位地址)、0x34、0x56(低位地址)
(4)发送指定数据0x55
2、指定地址读数
(1)主机向SS指定的设备发送指令码0x06(写使能的指令)
(2)发送指令0x03,表示要读取
(3)指定地址0x123456:发送0x12(高位地址)、0x34、0x56(低位地址)
(4)主机为高电平,从机发送数据
二、W25Q64简介