特点:全双工,单主机多从机,数据格式为8bit,数据传输高位在前,低位在后
SPI一共四根引脚,分别为
(1)CS:片选信号,固定使用的话可以硬件上直接拉低
(2)SCK:时钟信号,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据,也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制
(3)MOSI:Master Out Slave In / Serial Data Output(SDO)/ Tx,向从设备发送数据
(4)MISO:Master In Slave Out / Serial Data Input(SDI)/ Rx,接收设备发来的数据
CPOL:Clock Polarity 时钟极性,为1时,SCK空闲时为高电平,为0时,空闲时为低电平
CPHA:Clock Phase 时钟相位,为0时,第一个时钟沿采样;为1时,每个周期的第二个时钟沿采样
当CPOL = 0,CPHA = 0时,因为主机的采样是在时钟前沿采样的,所以从器件输出信号要在第一个时钟信号前,所以从器件可以在SSEL信号有效后,立即输出bit1(此时SCK信号还未生效)
SPI主模块和与之通信的外设备时钟相位和极性应该一致。在主设备这边配置SPI接口时钟的时候一定要弄清楚从设备的时钟要求,因为主设备这边的时钟极性和相位都是以从设备为基准的
下图为四种情况下,采样的时刻,其中,CPHA=0时,数据要在第一个跳变沿之前准备好
以下为单片机模拟SPI通信的示例
//首先定义好I/O口
sbit SDO=P1^0;
sbit SDI=P1^1;
sbit SCK=P1^ 2;
sbit SCS=P1^3;
sbit ACC_7= ACC^7;
unsigned int SpiRead(unsigned char add)
{
unsigned char i;
unsigned int datal6;
add&=0x3f;/*6位地址*/
add |=0x80;/*读操作码l0*/
SDO=1;/*发送1为起始位*/
SCK=0;
SCK=1;
for(i=0;<8;i++)/*发送操作码和地址*/
{
if(add&0x80==1)
SDO=1;
else
SDO=0;
SCK=0;/*从设备上升沿接收数据*/
SCK=1;
add<<= 1;
}
SCK=1;/*从设备时钟线下降沿后发送数据,空读1位数据*/
SCK=0;
datal6<<= 1;/*读16位数据*/
for(i=0;<16;i++)
{
SCK= 1;
_nop_();
if(SDI==1)
datal6|=0x01;
SCK =0;
datal6< < =1;
}
return datal6;
}
下面列举一下,SPI的一个应用
下图ST7701S的 三根线的 写功能,一个数据为9bit,多了一个Data/Command的位,下图的数据在上升沿采样,下降沿输出数据
以下是4线的形式,用多一根D/CX线,该位在bit0处采样
以下为读功能
-
三线的读功能实现(8bit数据)
-
三线的读功能实现(24bit数据)
注意:读数据时,多了一个时钟周期要忽略数据 -
四线的读功能实现(24bit数据)
-
十六位地址写数据
-
十六位地址读数据