用兩個C51單片機模擬SPI全雙工通信,
//SPI主機代碼
void SPI_PRO_INIT()
{
SET_SFR_PAGE1;
_SPI_NSS_OUTPUT;
_SPI_NSS_PULLUPON;//上拉,關片選,
_SPI_SCK_OUTPUT;
_SPI_SCK_PULLDOWNON;//下拉 ,關時鐘
_SPI_MOSI_OUTPUT;
_SPI_MOSI_PULLDOWNON;//下拉 ,關數據輸出
_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),第一個上升沿讀取數據
if(_SPI_MISO )//從機發來的信號,如果是高電平
{
SPI1_dat|=0x01;//0000 0001,左移后,補1;與(SPI_dat&0x80)//1000 0000相互呼應
}
// else
//{
//SPI1_dat&=0xfe;//1111 1110,左移后,補0;
//}
_SPI_SCK_ON;
Delay_3us();
}
// _SPI_SCK_OFF;
_SPI_NSS_OFF; //關片選
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,要發送的數據的第8位是1
{
_SPI_MOSI_ON;
}
else
{
_SPI_MOSI_OFF;
}
SPI_dat=(SPI_dat<<1);//左移,移動數據傳送
_SPI_SCK_ON;
Delay_3us();
}
// _SPI_SCK_OFF;
_SPI_NSS_OFF; //關片選
}
void SPI_PRO()
{
W_data = SPI_Write_Byte(0x55 );//
R_data = SPI_Read_Byte();
if(R_data==0xAA)
{
_LED1_OFF;
}
}
//從機代碼
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讀出一個8位字節
* Input : SPI1_dat:要發送的數據
*******************************************************************************/
uint8 SPI_Read_Byte()
{
uint8 i;
uint8 SPI1_dat=0;
uint8 SPI1_flag=0;
if(!(_SPI_NSS ))//片選后,執行if(!(_SPI_NSS ))里面的函數
{
for(i=0;i<8;i++)
{
SPI1_flag=1;
while(!( _SPI_SCK ));//等待時鐘拉低,開始讀數據
SPI1_dat<<=1;//SPI1_dat=(SPI1_dat<<1)開始
if(_SPI_MOSI )
{
SPI1_dat|=0x01;//讀取后,第一位補1;//與SPI_dat&0x80相呼應
}
while(_SPI_SCK );//等待讀取結束
}
while(!(_SPI_NSS ));//等待關片選
}
if(SPI1_flag==1)
{
return SPI1_dat;
}
else
{
return 0;
}
}
/******************************************************************************
* Function : Slave_SPI_Write
* Description: 向SPI寫入一個8位字節
* Input : SPI_dat:要發送的數據
*******************************************************************************/
uint8 SPI_Write_Byte(uint8 SPI_dat)
{
uint8 i;
if(!(_SPI_NSS ))//片選后,執行if(!(_SPI_NSS ))里面的函數
{
for(i=0;i<8;i++)
{
while(_SPI_SCK);//_SPI_SCK低時,執行后面的函數
if(SPI_dat&0x80)//1000 0000 是高電平,有數據
{
_SPI_MISO_ON;
}
else
{
_SPI_MISO_OFF;
}
while(!(_SPI_SCK));//等待讀取完成
SPI_dat<<=1;//向SPI寫數據
}
while(!(_SPI_NSS ));//等待關片選
}
}
void SPI_PRO()
{
W_data= SPI_Write_Byte(0xAA );//
R_data= SPI_Read_Byte();
if(R_data==0x55)
{
_LED2_OFF;
}
}
|