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單片機所用如需用其它芯片請另行更改。