|
用兩個(gè)C51單片機(jī)模擬SPI全雙工通信,
//SPI主機(jī)代碼
void SPI_PRO_INIT()
{
SET_SFR_PAGE1;
_SPI_NSS_OUTPUT;
_SPI_NSS_PULLUPON;//上拉,關(guān)片選,
_SPI_SCK_OUTPUT;
_SPI_SCK_PULLDOWNON;//下拉 ,關(guān)時(shí)鐘
_SPI_MOSI_OUTPUT;
_SPI_MOSI_PULLDOWNON;//下拉 ,關(guān)數(shù)據(jù)輸出
_SPI_MISO_INPUT;
_SPI_MISO_PULLDOWNON;//下拉開啟,拉低輸入
R_data=0;
W_data=0;
SET_SFR_PAGE0;
}
uint8 SPI_Read_Byte()
{
uint8 i;
uint8 SPI1_dat=0;
_SPI_NSS_ON;//片選
for(i=0;i<8;i++)
{
_SPI_SCK_OFF;
Delay_3us();
SPI1_dat<<=1;//SPI1_dat=(SPI1_dat<<1),第一個(gè)上升沿讀取數(shù)據(jù)
if(_SPI_MISO )//從機(jī)發(fā)來的信號(hào),如果是高電平
{
SPI1_dat|=0x01;//0000 0001,左移后,補(bǔ)1;與(SPI_dat&0x80)//1000 0000相互呼應(yīng)
}
// else
//{
//SPI1_dat&=0xfe;//1111 1110,左移后,補(bǔ)0;
//}
_SPI_SCK_ON;
Delay_3us();
}
// _SPI_SCK_OFF;
_SPI_NSS_OFF; //關(guān)片選
return SPI1_dat;
}
uint8 SPI_Write_Byte(uint8 SPI_dat)
{
uint8 i;
_SPI_NSS_ON;//片選
for(i=0;i<8;i++)
{
_SPI_SCK_OFF;
Delay_3us();
if(SPI_dat&0x80)//1000 0000,要發(fā)送的數(shù)據(jù)的第8位是1
{
_SPI_MOSI_ON;
}
else
{
_SPI_MOSI_OFF;
}
SPI_dat=(SPI_dat<<1);//左移,移動(dòng)數(shù)據(jù)傳送
_SPI_SCK_ON;
Delay_3us();
}
// _SPI_SCK_OFF;
_SPI_NSS_OFF; //關(guān)片選
}
void SPI_PRO()
{
W_data = SPI_Write_Byte(0x55 );//
R_data = SPI_Read_Byte();
if(R_data==0xAA)
{
_LED1_OFF;
}
}
//從機(jī)代碼
void SPI_PRO_INIT()
{
SET_SFR_PAGE1;
_SPI_NSS_INPUT;
_SPI_NSS_PULLUPON;
_SPI_SCK_INPUT;
_SPI_SCK_PULLDOWNON;
_SPI_MOSI_INPUT;
_SPI_MOSI_PULLDOWNON;
_SPI_MISO_OUTPUT;
_SPI_MISO_PULLDOWNON;
SET_SFR_PAGE0;
W_data=0;
R_data=0;
}
/******************************************************************************
* Function : Slave_SPI_Read_Byte
* Description: 從SPI讀出一個(gè)8位字節(jié)
* Input : SPI1_dat:要發(fā)送的數(shù)據(jù)
*******************************************************************************/
uint8 SPI_Read_Byte()
{
uint8 i;
uint8 SPI1_dat=0;
uint8 SPI1_flag=0;
if(!(_SPI_NSS ))//片選后,執(zhí)行if(!(_SPI_NSS ))里面的函數(shù)
{
for(i=0;i<8;i++)
{
SPI1_flag=1;
while(!( _SPI_SCK ));//等待時(shí)鐘拉低,開始讀數(shù)據(jù)
SPI1_dat<<=1;//SPI1_dat=(SPI1_dat<<1)開始
if(_SPI_MOSI )
{
SPI1_dat|=0x01;//讀取后,第一位補(bǔ)1;//與SPI_dat&0x80相呼應(yīng)
}
while(_SPI_SCK );//等待讀取結(jié)束
}
while(!(_SPI_NSS ));//等待關(guān)片選
}
if(SPI1_flag==1)
{
return SPI1_dat;
}
else
{
return 0;
}
}
/******************************************************************************
* Function : Slave_SPI_Write
* Description: 向SPI寫入一個(gè)8位字節(jié)
* Input : SPI_dat:要發(fā)送的數(shù)據(jù)
*******************************************************************************/
uint8 SPI_Write_Byte(uint8 SPI_dat)
{
uint8 i;
if(!(_SPI_NSS ))//片選后,執(zhí)行if(!(_SPI_NSS ))里面的函數(shù)
{
for(i=0;i<8;i++)
{
while(_SPI_SCK);//_SPI_SCK低時(shí),執(zhí)行后面的函數(shù)
if(SPI_dat&0x80)//1000 0000 是高電平,有數(shù)據(jù)
{
_SPI_MISO_ON;
}
else
{
_SPI_MISO_OFF;
}
while(!(_SPI_SCK));//等待讀取完成
SPI_dat<<=1;//向SPI寫數(shù)據(jù)
}
while(!(_SPI_NSS ));//等待關(guān)片選
}
}
void SPI_PRO()
{
W_data= SPI_Write_Byte(0xAA );//
R_data= SPI_Read_Byte();
if(R_data==0x55)
{
_LED2_OFF;
}
}
|
|