51模擬I2C
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit SCL = P1^0;
sbit SDA = P1^1;
void Delayus(uchar us)
{
while(us--)
{
_nop_();
_nop_();
_nop_();
}
}
void I2CStart() //I2C起始信號
{
SDA=1;
_nop_();
SCL=1; //首先保證SDA SCL都是1;
Delayus(4);
SDA=0;
Delayus(4);
SCL=0; //鉗住I2C總線,準備發送或接受數據;
_nop_();
_nop_();
}
void I2CStop() //I2C終止信號
{
SDA=0; //首先保證SDA SCL都爲0
_nop_();
SCL=1;
Delayus(4);
SDA=1;
Delayus(4);
}
bit I2C_Write_Byte(uchar dat) //I2C寫字節函數 返回從機應答值,爲1時,接受成功,否則失敗;
{
bit ACK; //暫存從機應答值
uchar Mask; //用於探測字節內某一位值的掩碼變量
for(Mask=0x80;Mask!=0;Mask>>=1)
{
if((Mask&dat)==0) SDA=0;
else SDA=1;
_nop_();
SCL=1;
Delayus(4);
SCL=0;
}
_nop_();
_nop_();
SDA = 1;
_nop_();
_nop_();
SCL=1;
Delayus(3);
if(SDA==0)ACK=0;
else ACK=1;
SCL=0;
Delayus(2);
return (~ACK); //0寫入失敗,1寫入成功
}
uchar I2C_Rec_Byte() //I2C讀字節函數;返回讀取的字節;發送應答信號;(若發送非應答信號只要將最後發送的0改爲1即可)
{
uchar Dat=0x00; //定義返回值
uchar Mask; //設置掩碼;
SDA = 1; //首先確保主機釋放SDA
for(Mask=0x80;Mask!=0;Mask>>=1) //從高位到低位依次進行;
{
Delayus(1);
SCL=1; //拉高SCL
if(SDA==0)Dat&=~Mask;
else Dat|=Mask;
Delayus(1);
SCL=0;
}
SDA=0; //應答信號(非應答信號爲1) //這裏的0或1是主機的應答信號;應答0——表示繼續讀取;應答1——表示停止讀取
Delayus(2);;
SCL=1;
Delayus(4);
SCL=0;
return Dat;
}
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit SCL = P1^0;
sbit SDA = P1^1;
void Delayus(uchar us)
{
while(us--)
{
_nop_();
_nop_();
_nop_();
}
}
void I2CStart() //I2C起始信號
{
SDA=1;
_nop_();
SCL=1; //首先保證SDA SCL都是1;
Delayus(4);
SDA=0;
Delayus(4);
SCL=0; //鉗住I2C總線,準備發送或接受數據;
_nop_();
_nop_();
}
void I2CStop() //I2C終止信號
{
SDA=0; //首先保證SDA SCL都爲0
_nop_();
SCL=1;
Delayus(4);
SDA=1;
Delayus(4);
}
bit I2C_Write_Byte(uchar dat) //I2C寫字節函數 返回從機應答值,爲1時,接受成功,否則失敗;
{
bit ACK; //暫存從機應答值
uchar Mask; //用於探測字節內某一位值的掩碼變量
for(Mask=0x80;Mask!=0;Mask>>=1)
{
if((Mask&dat)==0) SDA=0;
else SDA=1;
_nop_();
SCL=1;
Delayus(4);
SCL=0;
}
_nop_();
_nop_();
SDA = 1;
_nop_();
_nop_();
SCL=1;
Delayus(3);
if(SDA==0)ACK=0;
else ACK=1;
SCL=0;
Delayus(2);
return (~ACK); //0寫入失敗,1寫入成功
}
uchar I2C_Rec_Byte() //I2C讀字節函數;返回讀取的字節;發送應答信號;(若發送非應答信號只要將最後發送的0改爲1即可)
{
uchar Dat=0x00; //定義返回值
uchar Mask; //設置掩碼;
SDA = 1; //首先確保主機釋放SDA
for(Mask=0x80;Mask!=0;Mask>>=1) //從高位到低位依次進行;
{
Delayus(1);
SCL=1; //拉高SCL
if(SDA==0)Dat&=~Mask;
else Dat|=Mask;
Delayus(1);
SCL=0;
}
SDA=0; //應答信號(非應答信號爲1) //這裏的0或1是主機的應答信號;應答0——表示繼續讀取;應答1——表示停止讀取
Delayus(2);;
SCL=1;
Delayus(4);
SCL=0;
return Dat;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.