有需要官方SPI协议文档的,可以直接到下面链接下载:
https://download.csdn.net/download/LH_SMD/36749162
1.简介
spi是一种全双工同步串口外设接口(serial peripheral interface),由摩托罗拉公司推出的一种接口技术。
2.优缺点
全双工、简单、通讯速度快,但是没有应答机制,无法确认接收到的数据是否正确或者是否接收到数据。这一点和IIC形成鲜明对比,当然,这个也是SPI速度相对IIC快的重要因素之一。
3.通信协议
(1)主从方式工作
通常可以一主多从,一般需要四根线,当单向传输时,三根线也是可以的。所有的SPI设置都至少有以下四根线:
①SDI/MISO 主设备数据输入,从设备数据输出
②SDO/MOSI 主设备数据输出,从设备数据输入
③SCLK 时钟线,由主设备产生
④CS/SS 片选,当有多个从设备时,由这个引脚选择和主设备通讯的从设备,一般低电平有效
(2)工作模式
SPI有四种工作模式,一般从设备从出厂时就固定了某一种或者多种工作模式,主设备需要和从设备需要在同一种工作模式下才能进行通讯。
工作模式由CPOL(时钟极性)和CPHA(时钟相位)来决定,具体如下:
①Mode0: CPOL=0,CPHA=0
②Mode1: CPOL=0,CPHA=1
③Mode2: CPOL=1,CPHA=0
④Mode3: CPOL=1,CPHA=1
先来看看官方文档时序图1:(SPI Mode0和Mode2)
从上面时序可以知道:
当CPHA=0时,有:
①CPOL=0时,SCLK=0,数据线处于空闲状态,SCLK上升沿时采样数据
②CPOL=1时,SCLK=1,数据线处于空闲状态,SCLK下降沿时采样数据
举个例子:
某SPI从设备规定工作模式为模式0:即CPOL = 0,CPHA = 0。
根据上面说明和时序,在SPI模式0时:
来分析下向SPI从设备写数据:
unsigned char i = 0;
for(i = 0;i < 8;i++)
{
sclk = 0; //sclk=0,数据线空闲,先将数据准备好
if(send_data & 0x80)
mosi = 1;
else mosi = 0;
sclk = 1; //sclk 0--->1上升沿,发送数据
delay; //延时一段时间,等待数据发送完毕
}
那么对于主设备读取从设备发过来的数据,时序也是一样的:
unsigned char i = 0;
for(i = 0;i < 8;i++)
{
sclk = 0;
if(miso)
recv_data|=0x01;
else recv_data&=0xfe;
sclk = 1;
recv_data<<=1;
delay;
}
再来看看CPHA=1时:(SPI Mode1和Mode3)
从上面时序可以知道:
当CPHA=1时,有:
①CPOL=0时,SCLK=0,数据线处于空闲状态,SCLK下降沿时采样数据(工作模式1)
②CPOL=1时,SCLK=1,数据线处于空闲状态,SCLK上升沿时采样数据(工作模式3)
一样的,我们来举个例子:
某SPI从设备规定工作模式为模式1:即CPOL = 0,CPHA = 1。
根据上面说明和时序图,在SPI模式1时:
来分析下向SPI从设备写数据:
unsigned char i = 0;
for(i = 0;i < 8;i++)
{
sclk = 1; //sclk=0,数据线空闲,先将数据准备好
if(send_data & 0x80)
mosi = 1;
else mosi = 0;
sclk = 0; //sclk 0--->1上升沿,发送数据
delay; //延时一段时间,等待数据发送完毕
}
那么对于主设备读取从设备发过来的数据,时序也是一样的:
unsigned char i = 0;
for(i = 0;i < 8;i++)
{
sclk = 1;
if(miso)
recv_data|=0x01;
else recv_data&=0xfe;
sclk = 0;
recv_data<<=1;
delay;
}
值得注意的是:
我们的主设备能够控制时钟,因为我们的SPI通信并不像UART或者IIC通信那样有专门的通信周期,有专门的通信起始信号,有专门的通信结束信号,SPI官方协议文档中对这些并没有做规定,所以我们的SPI协议能够通过控制时钟信号线,当没有数据交流的时候我们的时钟线要么是保持高电平,要么是保持低电平。