趣味SPI总线解析(二)
CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据采样是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在上升沿,数据发送是在下降沿。
CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据发送是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。
CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据采集是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。
CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据发送是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。
如果要实现连接通讯,确定单片机(Master MCU1)为主模式,单片机(Slave MCU1)为从模式。各自也配置好了SLCK,MOSI,MISO和SCK的io引脚。选择了默认的SPI0模式。原理图如下:
按图连接好后,Master MCU1单片机发送1—10的数字给Slave MCU1单片机;Slave MCU1收到后,用流水灯作为回应。程序如下:
①:数据发送程序(主机仅发送)
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//---------------------------
#include
#include
//---------------------------
sbit SPICLK = P1^0; //时钟信号
sbit MOSI = P1^1; //主器件数据输出,从器件数据输入
sbit MISO = P1^2; //主器件数据输入,从器件数据输出
sbit SS = P1^3; //从器件使能信号
void Dat_Transmit(uchar dat) //发送数据程序
{
uchar i,datbuf; //主机数据暂存寄存器
datbuf=dat;
SS=1;
while(SS){;}
for(i=0;i<8;i++) //
{
while(SPICLK){;}
if(datbuf&0x80)
MISO=1;
else
MISO=0;
datbuf=(datbuf<<1);
while(~SPICLK){;}
}
}
void main(void)
{
uchar i;
while(1)
{
for(i=0;i<10;i++)
{
Dat_Transmit(i);
}
}
}
②:数据接收程序(从机仅接收)
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//---------------------------
#include
#include
//---------------------------
sbit SPICLK = P1^0; //时钟信号
sbit MOSI = P1^1; //主器件数据输出,从器件数据输入
sbit MISO = P1^2; //主器件数据输入,从器件数据输出
sbit SS = P1^3; //从器件使能信号
//---------------------------
void Nop(void)
{
;
}
void Delay(uchar t)
{
while(t--){;}
}
uchar Data_Receive(void) //数据接收程序
{
uchar i,dat=0,temp;
bit bt;
SPICLK=1;
MISO=1;
SS=0; //选中器件
Nop();
Nop();
for(i=0;i<8;i++)
{
SPICLK=1;
Nop();
Nop();
Nop();
SPICLK=0;
Nop();
Nop();
bt=MISO;
if(bt)
temp=0x01;
else temp=0x00;
dat=(dat<<1);
dat=(dat|temp);
}
SS=1;
SPICLK=1;
return dat;
}
void main(void)
{
uchar exdat;
uchar i=0;
uchar code table[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F};
P2=0;
while(1)
{
exdat=Data_Receive();
P0=table[exdat];
for(i=0;i<200;i++)
Delay(200);
}
}
SPI总线注意点
1. Master配置SPI接口时钟的时候一定要考虑从设备的操作时序要求,因为Master这边的时钟极性和相位都是以Slave为基准的。因此在时钟极性的配置上一定要确定Slave是在SCK的下降沿还是上升沿输出数据,是在SCK的上升沿还是下降沿接收数据。
2. 当Slave时钟频率小于Master时钟频率时,如果Master的SCK的速率太快,会出现Slave接收到的数据不正确,而SPI接口又没有应答机制确认Slave是否接收到数据从而导致通信传输数据错误。
3. SPI总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。除了MCU,还有FLASHRAM、网络控制器、LCD显示驱动器和A/D转换器等外围设置。
4. 上面的代码所用指令是STC 89C51单片机所用如需用其它芯片请另行更改。