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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章