一:SPI介绍:
全双工,同步的意思是在一个时间周期内,它既接收信息也发送信息,而不是指它在同时发送信息,接收信息。
使用同一个通信结构是指所有设备发送或接收用的是同一条数据线。
二:SPI接线图和各接线的作用:
接线图:
各接线的作用:
三:时序图详解
SPI总线有四种工作方式,其中使用的最为广泛的是模式0和模式3方式。
CPOL(Clock Polarity):时钟极性选择,为0时SPI总线空闲时,时钟线为低电平 ;为1时SPI总线空闲时,时钟线为高电平。
CPHA(Clock Phase):时钟相位选择,为0时在SCLK第一个跳变沿,主机对MISO引脚电平采样( 接收操作);为1时在SCLK第二个跳变沿,主机对MISO引脚电平采样( 接收操作)。
模式0,1,2,3分别代表着CPHA,CPOL两者值为0,0;0,1;1,0;1,1。
这几种模式原理都是一样的,懂一种后反推过去即可。
模式0:CPHA:0,CPOL:0
看SPI时序图最重要的是先确认好GPHA,GPOL的值,在顺着图一步一步的往下走。其它的几种模式的原理都是一样的,怎么去理解模式零的时序图就怎么去理解其他几个的时序图。
四:模拟SPI发送接收函数的示例
void sof_spi(void)
{
/* 打开端口B的硬件时钟(就是对硬件供电),默认状态下,所有时钟都是关闭 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct={0};
//PB3-SCK PB5-MOSI PB14-CS
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_14|GPIO_Pin_5;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed=GPIO_High_Speed;
GPIO_Init(GPIOB,&GPIO_InitStruct);
//PB4-MISO
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4;//miso
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
GPIO_Init(GPIOB,&GPIO_InitStruct);
//模式3 - 空闲状态SCK引脚为高电平
//刚引脚初始化完毕, 总线处于空闲状态
PBout(3)=0;//sck
PBout(14)=1;//cs
}
uint8_t sof_spi_sendrecv(uint8_t data)
{
uint8_t d=0;
int i=0;
for(i=0;i<8;i++)
{
//准备数据 ---- 直到SCK引脚在模式0中产生下降沿,被SPI设备接收后,SPI设备才会读取MOSI引脚输入的电平信号
if(data&(1<<(7-i)))
{
PBout(5)=1;
}
else
{
PBout(5)=0;
}
PBout(3)=0;
delay_us(2);
//产生上升沿, 模式0中的第一个信号边沿,通知SPI设备发送数据
PBout(3)=1;
delay_us(2);
if(PBin(4))
{
d|=1<<(7-i);
}
//产生下降沿, 模式3中的第二个信号边沿,通知SPI设备接收数据
PBout(3)=0;
delay_us(2);
}
return d;
}