今晚學了一些SPI的資料,但玩單片機畢竟不能只看而不實踐,于是寫了個利用兩片AT89C51的GPIO接口軟件模擬SPI實現(xiàn)雙MCU通信的程序。
實現(xiàn)目標:
兩片AT89C51均通過軟件模擬SPI的方式建立通信,主機循環(huán)發(fā)送數(shù)值0~9,從機將接收到的數(shù)值顯示在數(shù)碼管上且將該數(shù)值返回給主機,主機也將從機返回的數(shù)值顯示在數(shù)碼管上。
主機源碼:
#include<reg51.h>
#include<intrins.h>
sbit SCLK=P1^0;
sbit MOSI=P1^1;
sbit MISO=P1^2;
sbit SS=P1^3;
void Delay_ms() //延時一段時間
{
unsigned char i,j,k;
_nop_();
i=4;
j=129;
k=119;
do
{
do
{
while(--k);
}
while(--j);
}
while(--i);
}
void Delay1ms()
{
unsigned char i,j;
_nop_();
i=2;
j=199;
do
{
while(--j);
}
while(--i);
}
void SPI_M_Write(unsigned char dat) //主機發(fā)送數(shù)據(jù)
{
unsigned char i;
SS=0;
for(i=0;i<8;i++)
{
if(dat&0x80)
{
MOSI=1;
}
else
{
MOSI=0;
}
dat<<=1;
SCLK=1;
_nop_();
_nop_();
SCLK=0;
_nop_();
_nop_();
}
SS=1;
Delay1ms();
}
unsigned char SPI_M_Read() //主機接收數(shù)據(jù)
{
unsigned char i;
unsigned char dat=0;
SS=0;
for(i=0;i<8;i++)
{
dat<<=1;
dat|=MISO;
SCLK=1;
_nop_();
_nop_();
SCLK=0;
_nop_();
_nop_();
}
SS=1;
return dat;
}
void main()
{
unsigned char LEDS[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char i,temp;
SCLK=0;
P2=0x00;
while(1)
{
for(i=0;i<10;i++)
{
SPI_M_Write(i);
Delay_ms();
temp=SPI_M_Read();
P2=LEDS[temp];
Delay_ms();
}
}
}
從機源碼:
#include<reg51.h>
#include<intrins.h>
sbit SCLK=P1^0;
sbit MOSI=P1^1;
sbit MISO=P1^2;
sbit SS=P1^3;
void Delay_ms() //延時一段時間
{
unsigned char i,j,k;
_nop_();
i=4;
j=129;
k=119;
do
{
do
{
while(--k);
}
while(--j);
}
while(--i);
}
void SPI_S_Write(unsigned char dat) //從機發(fā)送數(shù)據(jù)
{
unsigned char i;
while(SS==1);
for(i=0;i<8;i++)
{
while(SCLK==0);
while(SCLK==1);
dat<<=1;
if(dat&0x80)
{
MISO=1;
}
else
{
MISO=0;
}
}
while(SS==0);
}
unsigned char SPI_S_Read() //從機接收數(shù)據(jù)
{
unsigned char i;
unsigned char dat=0;
while(SS==1);
for(i=0;i<8;i++)
{
while(SCLK==0);
while(SCLK==1);
dat<<=1;
dat|=MOSI;
}
while(SS==0);
return dat;
}
void main()
{
unsigned char LEDS[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char i,temp;
P2=0x00;
while(1)
{
for(i=0;i<10;i++)
{
temp=SPI_S_Read();
P2=LEDS[temp];
Delay_ms();
SPI_S_Write(i);
Delay_ms();
}
}
}
原理圖如下:
|