新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 關于IIC協議及代碼實現

        關于IIC協議及代碼實現

        作者: 時間:2016-11-22 來源:網絡 收藏
        最近學了下IIC協議,這里想把模擬IIC接口和標準IIC接口總結一下。(這里只介紹一主一從的情況)

        IIC數據通信是通過兩根線實現通信的,即SDA和SCL,SDA是數據線,SCL是時鐘線,SCL控制SDA的工作時鐘,也就是說當SCL為高電平時SDA上面的數據才有效。

        本文引用地址:http://www.104case.com/article/201611/319919.htm

        模擬IIC接口設置:

        主要是選擇兩條I/O分別作為SCL和SDA線,在進行數據傳輸是確定其輸入輸出功能(配置IOxDIR寄存器)。

        標準IIC接口設置:

        LPC2148為例

        第一步:設置管腳功能選擇寄存器,選擇I/O為SCL,SDA功能

        例如:PINSEL0 = (PINSEL0 & (~0xF0)) | 0x50; //p0.2,p0.3 iic

        第二步:設置IIC工作頻率,即SCL的時鐘

        例如:

        if(Mode == I2C_SPEED_400)
        {
        //--- I2C Timing for 58 MHz (t = 16.954 ns) ---
        I2C0SCLH = 47; //-- more then 0.6 us - 0.8
        I2C0SCLL = 93; //-- more then 1.3 us - 1.4
        }
        else //Slow
        {
        I2C0SCLH = 47*4;
        I2C0SCLL = 93*4;
        }

        第三步:清除所有標志位

        I2C0CONCLR = 0xFF;

        第四步:設置主從模式,這里為主模式

        I2C0CONSET = 0x40;

        第五步:始能IIC接口(enable IIC)

        I2C0CONSET |= I2C_FLAG_I2EN;

        下面列出IIC進行數據通信時滿足的幾個條件:

        1)起始條件:當SCL和SDA都為高電平時,如果SDA由高電平變低電平時就認為是起始條件。

        IIC_Start()

        {

        SDA = 1;

        delay(2);//這個時間有自己設定

        SCL = 1;

        delay(2);

        SDA = 0;

        delay(2);

        SCL = 0;

        }

        這樣就可以開始進行數據通信了,PS:SCL高電平時SDA的數據才有效.

        2)停止條件:當SCL為高電平時,如果SDA由低電平變為高電平,可認為是一個停止條件,即停止數據傳輸,一般主發送機來控制。

        IIC_Stop()

        {

        SCL = 0;

        delay(2);

        SDA = 0;

        delay(2);

        SCL = 1;

        delay(2);

        SDA = 1;

        }

        這樣就產生一個停止條件。

        2)響應

        當主設備發送完一字節數據時,從設備會產生一個響應ACK(一位,低電平),此時主設備釋放SDA線高,如果主設備接收到一位低電平,表示從設備產生了一個響應位,因此可以繼續向從設備發送數據,反之則停止發送。

        bit IIC_RecevAck()

        {

        CY = SDA;//單片機為例

        delay(2);

        SCL = 1;

        delay(2);

        SCL = 0;

        delay(2);

        return CY;

        }

        //------當主設備接收從設備的一字節數據時,主設備可以發送ACK也可以不發送ACK,如果不發送ACK表示停止讀取從設備數據,反之則可以繼續接收數據。

        IIC_SendAck(char ack)//ack=0有響應,ack=1表示不發送響應,停止接收。

        {

        if(ack == 0)

        {

        SDA = 0;

        }

        else

        {

        SDA = 1;

        }

        SCL = 1;

        delay(2);

        SCL = 0;

        }

        下面舉例說明IIC進行一字節數據的傳輸

        IIC_SendOneByte(unsigned char data)//主設備向從設備發送一字節數據

        {

        unsigned char i;

        for (i = 0; i < 8; i++)

        {

        if (data & 0x80)

        {

        SDA = 1;

        }

        else

        {

        SDA = 0;

        }

        delay(2);

        SCL = 1;

        delay(2);

        SCL = 0;

        delay(2);

        data <<= 1;

        }

        SDA = 0;//可以把SDA拉低,等待響應位,也可以通過IIC_RecvAck()來拉低

        }

        //--------------------------------------------------------

        BYTE IIC_ReadOneByte()//一般由主設備先發送一字節給從設備,讓從設備發送數據給主設備

        {

        BYTEj,data = 0;

        SDA = 1; //單片機當管腳作輸入時,寫入1,默認為輸出功能。

        for(j = 0; j < 8; j++)

        {

        data <<= 1;

        SCL = 1;

        delay(2);

        data = SDA;

        SCL = 0;

        delay(2);

        }

        return data;

        }



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 汾阳市| 汶上县| 资兴市| 营山县| 姚安县| 洛宁县| 基隆市| 抚松县| 寿光市| 德江县| 晋宁县| 大厂| 西和县| 淮南市| 南丰县| 长汀县| 颍上县| 临安市| 高安市| 山东省| 盘山县| 乌苏市| 色达县| 寿宁县| 轮台县| 炎陵县| 中方县| 清水河县| 长治县| 定陶县| 浦东新区| 兴海县| 宁都县| 兴仁县| 柳河县| 清涧县| 海晏县| 绥芬河市| 淄博市| 泌阳县| 永川市|