一、关于SPI
相比于I2C,SPI的直观感受就是占用的硬件资源(线)更多,对于一般支持SPI通信的模块,都至少存在四根线:
~SS(slave select):从机选择,主机可以通过这根线直接指定要和哪个从机通信(置0)
~SCK(Serial Clock):类似于I2C中的时钟线SCL
~MOSI(master output):主机输出线(通信线),给从机发送数据,接从机MOSI
~MISO(master input):主机输入线(通信线),接收从机数据,接从机MISO
其实从上面的四根线我们就可以大致猜测出SPI通信的大致形式和特点:
1、多从机通信:主机“和谁通信”是由SS线进行直接指定(置为0)输入的,指谁是谁;
2、同步,全双工:主机引出两个通信线,输入输出不需要纠结在一根线上;
3、无应答:相比于I2C不存在应答位
二、硬件电路
上面是SPI的主机和从机接线的大致情况
1、可以看到SS线是由主机引出来单独连接每一个从机的;
2、SCK和I2C一样,由一根总线引出多个支线接入相应的从机;
3、通信线也分别接入从机的相应位置;
4、补充:若从机没有电,则需要主机引出线来供电;
关于通信线
对于I2C中的SDA线,采用的是开漏输出,其目的是为了防止在进行多从机通信时造成从机之间的短路,而SPI对这个问题则需要对两根通信线单独讨论:
对于MOSI:高低电平来自主机,故不存在从机短路的问题,所以采用的是推挽输出
对于MISO:高低电平来自从机,一般采用上拉或者浮空输入,如果没有SS的指定,那么从机就会切换为“高阻态”,避免短路。
对于上述通信线的特点,传输数据时其速度理论上是远远大于I2C的,因为我们可以通过推挽输出快速变化信号。
三、如何通信(移位)
如上图所示,我们可以直观的看到,主机和从机的数据传输是一个交换的过程,根据波特率发生器的频率,
主机从高到低一个个bit移出,接收来自从机从高到低传来一个个bit
从机也是如此
对于数据的读取和接收,我们只需要指定对应的“数据寄存器”,如果我们只要发送,就通过寄存器把数据放上去,而不读取从机传过来的数据;如果只需要读,则直接读取从机传过来的数据,同时给从机“随便发一个过去”;如果不读,那寄存器就不操作。
四、时序部分
1、起始和终止
相对直观,开始:SS线置低(0);终止:SS线置高(1);
2、时序
关于数据的读取,传输其实大致和上面的移位部分一样,读取数据主要是看SCK的“脸色”,对于SCK,我们在什么时候读取数据是可以自行配置的。关于配置传输的形式,这里引出了两个可以配置的位置,CPOL和CPHA,这两位一共可以表示4种(0,1,2,3)模式。
虽说区分为了4种模式,但是模式与模式之间大同小异,“区分”来自CPOL和CPHA的排列组合。
0 | 1 | |
CPOL | SCK空闲为0 | SCK空闲为1 |
CPHA | 第一个边沿移入(寄存器读取数据),第二个边沿移出(通信线传递数据) | 第一个边沿移出,第二个边沿移入 |
(1)模式0----CPOL=0;CPHA=0;
时序图就是这样,其中从机的MISO两端处于中间位置的横线表示从机的“高阻态”
此时SCK上升沿,MOSI不变,表示读取数据
SCK下降沿,MOSI变化,表示主从机移位数据。
理解了模式0,根据上面的表格,其他3种模式的时序图应该不难理解了。
(2)模式1-------CPOL=0;CPHA=1;
(3)模式2----CPOL=1;CPHA=0;
(4)模式2----CPOL=1;CPHA=1;