关注公众号

关注公众号

手机扫码查看

手机查看

喜欢作者

打赏方式

微信支付微信支付
支付宝支付支付宝支付
×

趣味SPI总线解析(二)

2020.10.05

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模式。原理图如下:

wx_article_20181109183526_AEXn4R.jpg

按图连接好后,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单片机所用如需用其它芯片请另行更改。


推荐
关闭