了解SPI通信对于我们了解通信有非常重要的意义。
SPI(Serial Peripheral Interface)是由Motorola公司(摩托罗拉)开发的一种通用数据总线
四根通信线:
SCK(Serial Clock):时钟线;
MOSI(Master Output Slave Input):主机输出从机输入线;
MISO(Master Input Slave Output):主机输入从机输出线;
SS(Slave Select):从机选择线;(代替了I2C的从机寻址机制)
另外由于SPI是单端通信所以SPI还需要另外的共地,GND线。
注意:
1.SPI是全双工,不支持多主机;
输出引脚就是输出,输入就是输入,不需要像I2C还需要输入输出转换,唯一冲突在于SS从机线
2.SPI不存在数据应答机制的设计,只有接收和发送数据。
不同设备名称可能不同,却决于明确该设备身份为从机还是主机。
有时候对于数据线接口有很多不同我们往往有着更多的写法,到底什么意思还是需要自己根据使用芯片是作为主机还是从机。
这里我们拿一个W25QXX一个外挂的Flash存储器为例子,它一般作为从机,所以DO就是从机输出主机输入,DI就是从机输入主机输出。具体还是需要看设备本省需要作为从机还是主机。
当实在不清楚的时候我们可以查看具体的芯片手册。对于STM32来说,STM32常常作为主机,当然也有作为从机(支持身份转换),不过我们往往用做主机比较多。
硬件电路:
所有SPI设备的SCK、MOSI、MISO分别连在一起主机另外引出多条SS控制线,分别接到各从机的SS引脚,代替了 从机寻址的软件操作,但是需要多一根从机选择线的硬件资源。
输出引脚MOSI配置为推挽输出(I2C为开漏输出是需要兼顾于多主机仲裁等等),输入引脚MISO配置为浮空或上拉输入。
同样需要注意的地方,SPI为单端信号(他们的高低电平都是相对于各自GND),需要,要求通信双方共地。
SCLK时钟线为主机绝对掌控,对于主机而言时钟线SCLK为输出,对于从机而言SCLK时钟线为输入。
(如果从机没有供电,还需要引脚引出来,主机引出供电线,给予从机寄生供电)
下面是大概框图:
需要注意:
在平时当中,SS为高电平,当主机需要时候会对相应的SS从机线置低电平,当完成通信以后主机就会将SS拉回高电平代表通信结束。就不需要像I2C需要发送从机位地址进行选择从机(从机寻址)。
输出引脚配置为推挽输出,高低电平均有很强的驱动能力,上升/下降沿速度非常快
(拉高拉低电平就会非常迅速)信号变化的快,就使得通信速度大大能达到MHZ,但是由于I2C是半双工只有两根线经常需要切换输入输出模式,同时需要兼顾多主机的时钟同步和仲裁问题,就使得其只能使用开漏输出,而开漏输出拉低非常迅速,但是拉高就比较慢,所以通信速度没有SPI那么快。
SPI不支持多主机,不要考虑冲突,唯一的冲突点在于,主机的MISO,主机一个输入而从机三个或者多个输出,就会导致冲突,因此SPI协议规定当从机未被选中,从机的MISO引脚必须切换为高阻态(不允许输出)。
软件实现:
主要就是理解一个移位的过程:
SPI一般是高位先行,我们利用时钟,当时钟产生上升沿,主机移出最高位的一个数据放在MOSI线上同时数据整体左移一位,从机移出最高位的数据放到MISO上,并且整体数据左移一位。当时钟产生下降沿,主机从MISO线上把从机放在MISO线上数据移入,放在最低位上,同样的,下降沿的时候,从机从MOSI线上把主机放在线上的高位,移入放在低位。
主机和从机都会进行采样输入直到数据完成交换过程,这就是实际的过程。
SPI时序基本单元:
起始条件:SS从高电平切换到低电平
终止条件:SS从低电平切换到高电平
SS低电平代表:正在通信;
SPI有两种可以配置的位
CPOL(Clock Polarity):时钟极性
CPHA(Clock Phase):时钟相位
综合起来可以有也就是四种模式
如下表:
模式选择 | 时钟极性CPOL | 时钟相位CPHA |
模式0 | 0 | 0 |
模式1 | 0 | 1 |
模式2 | 1 | 0 |
模式3 | 1 | 1 |
注意:
- 时钟极性CPOL的“0”和“1”决定了,空闲状态SCLK的电平是高还是低决定了第一个时钟沿是上升沿还是下降沿。
- 时钟相位CPHA 的“0”和“1”决定了,SCK第一个边沿是移入还是移出数据也可以说是决定了主机是奇数边沿采样还是偶数边沿采样。
模式介绍:
模式0:
交换一个字节(模式0)
CPOL=0:空闲状态时,SCK为低电平;
CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据;
模式0时序图
结合时序图讲解一下
首先SS由高电平变为低电平,代表SPI通信的开始,当SS由低电平变为高电平,代表SPI通信结束。
SCK由于CPOL为0,所以空闲为低电平,所以开始数据交换时候,第一个为上升沿,第二个为下降沿。所以CPOL决定的往往就是SCK,第一个为上升沿还是下降沿。
MOSI:由于CPHA为0,所以在第一个时钟沿进行数据移入操作((实际需要提前移出数据,相位提前一个时期),在第二个时钟沿进行数据移出操作。我们不断地进行操作可以发现,永远是奇数移入操作,偶数移出操作,对于主机数据采集也可以说就是奇数边沿采样。
注意:
- MOSI,MISO两个线交叉代表可能发送地数据是“0”或者“1”;
- MISO前面一个线代表上面说的高阻态,防止主机数据交换地时候有其他从机输出影响主机数据读取。
模式1:
交换一个字节(模式1)
CPOL=0:空闲状态时,SCK为低电平;
CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据;
模式1时序图
结合时序图讲解一下
首先SS由高电平变为低电平,代表SPI通信的开始,当SS由低电平变为高电平,代表SPI通信结束。
SCK由于CPOL为0,所以空闲为低电平,所以开始数据交换时候,第一个为上升沿,第二个为下降沿。所以CPOL决定的往往就是SCK,第一个为上升沿还是下降沿。
MOSI:由于CPHA为1,所以在第一个时钟沿进行数据移出操作,在第二个时钟沿进行数据移入操作。所以要求我们要提前将数据移入到线上才能保证在第一个时钟沿保证进行的是数据移出的操作,我们不断地进行操作可以发现,永远是奇数移出操作,偶数移入操作对于主机数据采集也可以说就是偶数边沿采样。
模式2:
交换一个字节(模式2)
CPOL=1:空闲状态时,SCK为高电平;
CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据;
模式2时序图
首先SS由高电平变为低电平,代表着SPI通信的开始,当SS由低电平变为高电平,代表着SPI通信的结束。
SCK:由于时钟极性CPOL为1,所以SCLK在空闲状态为高电平,所以在通信时,第一个时钟沿为下降沿,第二个为上升沿。
MOSI:由于CPHA为0,所以在第一个时钟沿进行数据移入的操作,在第二个时钟沿进行数据移出的操作。重复操作可以发现,主机为奇数边沿采样。
模式3:
交换一个字节(模式3)
CPOL=1:空闲状态时,SCK为高电平;
CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据;
模式3时序图
首先SS由高电平变为低电平,代表着SPI通信的开始,SS由低电平变为高电平代表着SPI通信的结束。
SCK:由于CPOL为1,所以SCLK空闲状态为高电平,所以SPI第一个时钟沿为下降沿,第二个为上升沿;
MOSI:由于CPHA为1,所以主机在第一个时钟沿进行数据移出的操作,在第二个边沿进行数据移入的操作,我们不断重复操作就可以发现,主机永远是在偶数时钟边沿进行数据采样。
以上就是对SPI模式的讲解,在实际使用过程当中,往往模式0使用较多。