1024手机基地看电影,午夜福利视频导航,国产精品福利在线一区,亚洲欧美日韩另类成人,在线观看午夜日本理论片,成年超爽免费网站,国产精品成人免费,精品动作一级毛片,成人免费观看网站,97精品伊人久久大香蕉

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5435|回復: 2
打印 上一主題 下一主題
收起左側

單片機IIC通信時序的詳細解釋

[復制鏈接]
跳轉到指定樓層
樓主
ID:135253 發表于 2018-8-16 17:09 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
/*---------------------------------------------------------------------
                         IIC.C文件  
  作者:xzf586                                創建日期:2018.8.16   
----------------------------------------------------------------------*/

#include <reg52.h>
#include <intrins.h>
#include"IIC.H"

#define NOP4  {_nop_();_nop_();_nop_();_nop_();_nop_();}

/***********************************************************************
                                                IIC起始信號
時 序:     1        SDA SCL高電平期間,持續時間>4.7us(實際上是總線空閑)
                2        SDA下降沿后,持續時間>4us(線與,總線占用)
************************************************************************/
void I2CStart()
{
    I2C_SDA = 1;         //首先確保SDA、SCL都是高電平,總線空閑
    I2C_SCL = 1;
    NOP4
    I2C_SDA = 0;         //先拉低SDA
    NOP4                        //起始信號結束
        
    I2C_SCL = 0;         //再拉低SCL,為后續SDA數據變化做準備
}
/***********************************************************************
                                                IIC結束通信信號
時 序:     1        SCL高電平期間,持續時間>4.7us
                2        SDA上升沿后,持續時間>4.7us(總線釋放)
************************************************************************/
void I2CStop()
{
    I2C_SDA = 0;
    I2C_SCL = 1; //先拉高SCL
    NOP4
    I2C_SDA = 1; //再拉高SDA,釋放總線
    NOP4
}

/***********************************************************************
                                        IIC主機向從機寫一個字節
時  序:    1        SCL=0;上面起始信號已準備好
                2        SDA=待傳輸位的值0或1
                3        等待一段時間,數據穩定
                4        SCL=1,此時SDA上數據不可以變化,因為從機要讀取這個SDA值
                5         等待一段時間,從機讀取這個SDA值
                6        SCL=0,進行下一次SDA數據變化,再傳輸出去
返回值        從機應答位的值
************************************************************************/
bit I2CWrite(unsigned char dat)
{
    bit ack;                                  //用于暫存應答位的值
    unsigned char temp;          //用于探測字節內某一位值的掩碼變量

    for (temp=0x80; temp!=0; temp>>=1) //從高位到低位依次進行
    {
        if ((temp&dat) == 0) //該位的值輸出到SDA上
            I2C_SDA = 0;
        else
            I2C_SDA = 1;
        NOP4
        I2C_SCL = 1;          //拉高SCL
        NOP4
        I2C_SCL = 0;         //再拉低SCL,完成一個位周期
    }                                                //8位數據發送完畢,
        
    I2C_SDA = 1;   //8位數據發送完后,主機釋放SDA,以檢測從機應答
    NOP4
    I2C_SCL = 1;   //拉高SCL,目的讓主機讀取應答值
    ack = I2C_SDA; //讀取此時的SDA值,即為從機的應答值
    NOP4
    I2C_SCL = 0;   //再拉低SCL完成應答位,并保持住總線

    return (~ack); //應答值取反以符合通常的邏輯:
                   //0=不存在或忙或寫入失敗,1=存在且空閑或寫入成功,注意ack取反
}

/***********************************************************************
                                主機從從機讀取最后一個字節,發送非應答信號
時 序:    1        SDA=1;余下SDA信號由從機控制
                2        SCL=1;拉高SCL,此時SDA上已由從機寫上一位0或1,主機開始讀取
                3        等待一段時間,讀取完畢
                4        SCL=0,拉低SCL,以使從機發送出下一位到SDA上
************************************************************************/
unsigned char I2CReadNAK()
{
    unsigned char temp;
    unsigned char dat;

    I2C_SDA = 1;  //首先確保主機釋放SDA,即將SDA控制權交由從機
    for (temp=0x80; temp!=0; temp>>=1) //從高位到低位依次進行
    {
        NOP4
        I2C_SCL = 1;      //拉高SCL
        if(I2C_SDA == 0)  //讀取SDA的值,此時SDA已由從機寫上一位0或1,
            dat &= ~temp; //為0時,dat中對應位清零
        else
            dat |= temp;  //為1時,dat中對應位置1
        NOP4
        I2C_SCL = 0;      //再拉低SCL,以使從機發送出下一位
    }
        
    I2C_SDA = 1;   //從機8位數據發送完后,主機拉高SDA,發送非應答信號,這樣從機將SDA控制權轉交主機
    NOP4
    I2C_SCL = 1;   //拉高SCL,讓從機讀到這個1,知道停止向主機發送數據
    NOP4
    I2C_SCL = 0;   //再拉低SCL完成非應答位,并保持住總線,因為停止信號還沒有發出,所以要保持總線

    return dat;
}

/***********************************************************************
                        主機從從機讀取一個字節(非最后一個字節),發送應答信號
時 序:     1        SDA=1;余下SDA信號由從機控制
                2        SCL=1;拉高SCL,此時SDA上已由從機寫上一位0或1,主機開始讀取
                3        等待一段時間,讀取完畢
                4        SCL=0,拉低SCL,以使從機發送出下一位到SDA上
************************************************************************/
unsigned char I2CReadACK()
{
    unsigned char temp;
    unsigned char dat;

    I2C_SDA = 1;                                                  //首先確保主機釋放SDA
    for (temp=0x80; temp!=0; temp>>=1) //從高位到低位依次進行
    {
        NOP4
        I2C_SCL = 1;                                      //拉高SCL
        if(I2C_SDA == 0)                                  //讀取SDA的值
            dat &= ~temp;                                 //為0時,dat中對應位清零
        else
            dat |= temp;                                  //為1時,dat中對應位置1
        NOP4
        I2C_SCL = 0;                                      //再拉低SCL,以使從機發送出下一位
    }
        
    I2C_SDA = 0;   //從機8位數據發送完后,主機拉低SDA,發送應答信號,SDA控制權仍然在從機手里
    NOP4
    I2C_SCL = 1;   //拉高SCL,讓從機讀到這個0,繼續向主機發送數據
    NOP4
    I2C_SCL = 0;   //再拉低SCL完成應答位,并保持住總線,SDA由從機確定

    return dat;
}

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:58110 發表于 2018-8-17 06:21 | 只看該作者
謝謝分享!
后面若是有應用示例就更好了
回復

使用道具 舉報

板凳
ID:414573 發表于 2020-11-3 07:33 | 只看該作者
從編程上看,是宋師傅的忠實粉絲,一起學了。有應用實例嗎
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表