新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > C51單片機模擬I2C總線驅動程序設計(1)

        C51單片機模擬I2C總線驅動程序設計(1)

        作者: 時間:2016-11-26 來源:網絡 收藏
        /********************************** I2C 總線驅動 ******************************
        模塊名:I2C 總線驅動 型號:I2C
        功能描述:
        此模塊包括發送數據及接收數據,應答位發送,并提供了幾個直接面對器件的操作函數,能
        很方便的與用戶程序進行連接并擴展。需要注意的是,函數是采用延時方法產生 SCL 脈沖,
        對高晶振頻率要做一定的修改!!在寫 E2PROM 的時候一定要延時!!!
        說明:
        1us機器周期,晶振頻率要小于12MHz
        返回1:則操作成功,返回0:則操作失敗。
        sla為器件從地址,suba為器件子地址。
        *******************************************************************************
        #i nclude "AT89X52.h"
        #i nclude
        #define SomeNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();} //定義空指令
        sbit SDA = P1^3; //模擬 I2C 數據傳輸位
        sbit SCL = P1^2; //模擬 I2C 時鐘控制位
        bit bdata I2C_Ack; //應答標志位
        /************************************ I2C_Start *******************************
        函數名:void I2C_Start()
        入口:
        出口:
        功能描述:啟動 I2C 總線,即發送 I2C 初始條件
        解釋: 在 I2C 總線協議中規定的起始位格式是:在 SCL 高電平期間,SDA 發生從高到低的電平
        跳變.它與其它數據格式的區別在于,協議中規定有效的數據必須在 SCL 的高電平期間保持
        不變,只有在 SCL 的低電平期間才能發生跳變.所以這一有別與其它格式的數據才能做為起
        始位.
        調用函數:
        全局變量
        *******************************************************************************
        void I2C_Start()
        {
        SDA = 1; //發送起始條件的數據信號
        _Nop();
        SCL = 1;
        SomeNOP(); //起始條件建立時間大于 4.7us,延時
        SDA = 0; //發送起始信號
        SomeNOP(); //起始條件建立時間大于 4us,延時
        SCL = 0; //鉗住 I2C 總線準備發送或接收數據
        //解釋:I2C 總線在空閑狀態下都是被上拉為高電平的,所以當它們處于低電平時就表示忙的狀態.
        _nop_();
        _nop_();
        }
        /************************************ I2C_Stop ********************************
        函數名:void I2C_Stop()
        入口:
        出口:
        功能描述:結束 I2C 總線,即發送 I2C 結束條件
        解釋:同起始條件的格式類似,結束條件的格式是在 SCL 高電平期間,SDA 由低電平向高電平
        跳變.
        調用函數:
        全局變量:
        *******************************************************************************
        void I2C_Stop()
        {
        SDA = 0; //發送結束條件的數據信號
        _Nop();
        SCL = 1; //發送結束條件的時鐘信號
        SomeNOP();//結束條件建立時間大于 4us,延時
        SDA = 1; //發送 I2C 總線結束信號
        SomeNOP();
        }
        /************************************ I2C_CheckAck ****************************
        函數名:bit I2C_CheckAck(void)
        入口:
        出口:0(無應答),1(有應答)
        功能描述:
        檢驗 I2C 總線應答信號,有應答則返回 1,否則返回 0,超時值取 255.
        解釋:I2C 總線協議中規定傳輸的每個字節之后必須跟一個應答位,所以從器件在接收到每
        個字節之后必須反饋一個應答信號給主控制器,而主控制器就需要檢測從器件回傳的應答信
        號,根據其信息做出相應的處理.另外,主從之別是相對的,接收數據的即為從,發送數據的及
        為主.
        再看看應答信號的格式:在由發送器產生的時鐘響應周期里,發送器先釋放 SDA(置高),然后
        由接受器將 SDA 拉低,并在這個時鐘脈沖周期的高電平期間保持穩定的低電平.即表示從器
        件做出了應答.
        調用函數:void I2C_Stop()
        全局變量:
        *******************************************************************************
        bit I2C_CheckAck(void)
        {
        uchar errtime = 255; // 因故障接收方無 Ack,超時值為 255
        SDA = 1; //發送器先釋放 SDA
        SomeNOP();
        SCL = 1;
        SomeNOP(); //時鐘電平周期大于 4 us
        while(SDA) //判斷 SDA 是否被拉低
        {
        errtime--;
        if(errtime==0)
        {
        I2C_Stop();
        return(0);
        }
        }
        SCL = 0;
        _nop_();
        return(1);
        }
        /************************************ I2C_SendB *******************************
        函數名:void I2C_SendB(uchar c)
        入口:uchar 型數據
        出口:
        功能描述:
        字節數據傳送函數,將數據 c 發送出去,可以是地址,也可以是數據,發完后等待應答,
        并對
        此狀態位進行操作
        注意:在傳送數據時,數據(SDA)的改變只能發生在SCL的低電平期間,在SCL的高電平期間保
        持不變
        調用函數:bit I2C_CheckAck()
        全局變量:I2C_Ack
        *******************************************************************************
        void I2C_SendB(uchar c)
        {
        uchar BitCnt;
        for (BitCnt=0; BitCnt<8; BitCnt++) //要傳送的數據長度為 8 位
        {
        if((c<
        {
        SDA = 1;
        }
        else
        {
        SDA = 0;
        }
        _nop_();
        _nop_();
        SCL = 1; //置時鐘線為高通知被控器開始接收數據位
        SomeNOP(); //保證時鐘高電平周期大于 4us
        SCL = 0;
        }
        _nop_();
        _nop_();
        I2C_Ack = I2C_CheckAck();//檢驗應答信號,作為發送方,所以要檢測接收器反饋的應答信號.
        _nop_();
        _nop_();
        }




        評論


        技術專區

        關閉
        主站蜘蛛池模板: 石泉县| 湘西| 临安市| 大方县| 仙居县| 杂多县| 如东县| 沂南县| 息烽县| 青河县| 积石山| 台东县| 西乌| 永善县| 来凤县| 鸡西市| 黑山县| 梓潼县| 长汀县| 石家庄市| 施秉县| 睢宁县| 崇左市| 沁源县| 蓝山县| 嘉定区| 班戈县| 无极县| 三门县| 桦南县| 新龙县| 麟游县| 长治县| 南安市| 宜都市| 义马市| 上杭县| 古田县| 黄浦区| 潮州市| 桂平市|