• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 手機與無線通信 > 設計應用 > I2C串行總線組成及其工作原理

    I2C串行總線組成及其工作原理

    作者: 時間:2017-01-10 來源:網絡 收藏

      采用串行總線技術可以使系統的硬件設計大大簡化,系統的體積減小,可靠性提高,同時系統更容易更改和擴充

    本文引用地址:http://www.czjhyjcfj.com/article/201701/342706.htm

      常用的串行擴展總線有:總線,單總線,總線,以及microwire、Plus等等

      總線只有兩根雙向信號線,一根是數據線SDA,另一根是時鐘線SCL

        

     

      總線通過上拉電阻接正電源。因此I2C總線的設備都要接上拉電阻

      當總線閑置的時候,兩根線均為高電平,連接到總線上的任何一個器件輸出的低電平,都將使得總線得到信號變低,及各個器件的SDA和SCL都是線與的關系

      每個接入到I2C總線都有唯一的地址,主機與其他器件間的數據傳送可以是由主機發送數據到其他器件,這時主機即是發送器,由總線上接收數據的器件稱為是接收器。

      在多主機系統中,可能同時由幾個主機企圖啟動總線傳送數據,為了避免混亂,I2C總線要通過總線仲裁,已決定由哪臺主機控制總線

      數據位的有效性

      I2C總線進行數據傳送時,時鐘信號為高電平期間,數據線上的數據必須保持穩定,只有時鐘線上的信號為低電平期間,數據線上的高電平和低電平狀態才允許變化

        

     

      起始信號和終止信號

      SCL線為高電平期間,SDA線由高電平向低電平的變化表示起始信號,SCL線為高電平期間,SDA線由低電平向高電平變化表示終止信號

        

     

      數據傳送的格式

      (1)字節傳送與應答

      每一個字節必須保證是8位長度,數據傳送時,先傳送的是最高位(MSB),每一個被傳送的字節后面都必須跟隨一位應答位,即(一幀共有9位),應答信號由從機發送給主機

        

     

      每次數據傳送總是由主機產生的終止信號結束,但是若主機希望繼續占用總線進行新的數據傳送,則可以不產生終止信號,馬上再次發出起始信號對另一個從機進行尋址

      在總線的一個數據傳上過程中,可以有一下幾種傳送方式的組合方式

      a,主機向從機發送數據,數據傳送的方向在整個傳送過程中不變

        

     

      A表示應答,A非表示非應答,s表示其實信號,p表示終止信號

      主機發送地址時,總線上的每一個從機都將這7位地址碼與自己的地址進行比較,如果相同,則認為自己正在被主機尋址,根據R/T位將自己確定為發送器或接收器

      從機地址由固定部分和可編程部分組成,可編程的部分決定了可接入總線該器件的最大數目。

        

     

      由操作時序可知要進行必要的延時

      起始操作示例代碼:

      void T2CStart(void)

      {

      SDA = 1;

      SomeNop();//大于微秒級別

      SCL = 1;

      SomeNop();

      SDA = 0;

      SomeNop();

      }

      終止指令:

      void I2CStop(void)

      {

      SDA = 0;//data由0變到1為終止指令

      SomeNop();

      SCL = 1;

      SomeNop();

      SDA = 1;

      SomeNop();

      }

      I2C總線擴展  

     

      串行E2PROM的擴展

      (2)寫入過程:AT24CEEPROM的固定地址為1010,A2,A1A0引腳接入高低電平可以得到確定的3位編碼,形成的7位編碼即為該器件的地址碼

      單片機進行寫操作的時候,首先

      發送該器件的7位地址嗎和寫方向的方向碼0,發送完以后釋放SDA線并在SCL線上產生第九個時鐘信號,被選中的存儲器再確認自己的地址后,在SDA上產生一個應答信號作為響應

      ,單片機接收到信號就可以傳送數據了

      傳送數據時,單片機首先發送一個字節的被寫入器件的存儲區的首地址,收到存儲器器件的應答后,單片機就逐個發送各個數據的字節,但是每次發送一個字節后都要等待應答

      收到每個字節的地址后,芯片上的地址會自動加一

      寫入n個字節的數據格式

        

     

      讀出過程

      單片機首先發送該器件的7位地址碼和寫方向位0(偽寫),發送完后釋放SDA線并在SCL線上產生9個時鐘信號,被選中的存儲器器件在確認自己的地址之后,在SDA上產生一個應答信號作為回應

      然后在發送一個字節的要讀出存儲去的首地址,收到應答,單片機要重復一次起始信號并發出器件地址的讀方向位(1),收到器件應答就可以讀出字節,每次讀出一個字節,單片機都要回復一個應答信號,但最后讀出一個字節,單片機應返回非應答信號(高電平)并發出終止信號以結束讀出操作

        

     

      示例代碼:

      #include

      #define uchar unsigned char

      #define uint unsigned int

      sbit sda = P2^3;

      sbit scl = P2^2;

      sbit wp = P2^1;

      void delay()//微妙級別的延時函數

      {;;}

      void start()//開始信號

      {

      sda = 1;

      delay();

      scl = 1;

      delay();

      sda = 0;

      delay();

      }

      void stop()//停止信號

      {

      sda = 0;

      delay();

      scl = 1;

      delay();

      sda = 1;

      delay();

      }

      void respons()//應答信號

      {

      uchar i;

      scl = 1;

      delay();

      while((sda ==1)&&(i<250))//等到第九個時鐘周期的時候,還沒有變為0,

      //那么scl將自動的變為0,表示收到信號

      {

      i++;

      }

      scl = 0;

      }

      void init()

      {

      sda = 1;

      scl = 1;//把線全部釋放

      }

      void write_byte(uchar date)

      {

      uchar i,temp;

      temp = date;

      scl = 0;

      delay();

      for(i = 0;i<8;i++)//寫8次

      {

      temp = temp<<1;//表示將temp左移1位,將最高位移入psw寄存器中的cy位,

      //然后將最高位賦值給sda,送走數據

      scl = 1;//數據穩定了

      delay();

      sda = CY;

      delay();

      scl = 0;//讀走數據

      delay();

      }

      sda = 1;//注意養成釋放總線的習慣

      delay();

      }

      uchar read_byte()

      {

      uchar i,j,k;

      scl = 0;

      delay();

      sda = 1;//釋放數據總線

      delay();

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

      {

      scl = 1;

      delay();

      j = sda ;//讀取數據

      k =(k<<1)"j;

      scl = 0;

      delay();

      }

      return k;

      }

      uchar read_add(uchar address)

      {

      uchar date;

      start();

      write_byte(0xa0);//表示寫入器件的地址

      respons();

      write_byte(address);

      respons();

      start();

      write_byte(0xa1);

      respons();

      date=read_byte();

      stop();

      return date;

      }

      void write_add(uchar address,uchar date)

      {

      init();//初始化信號總線和地址總線

      start();//啟動信號

      write_byte(0xa0);//表示寫入器件的地址

      respons();

      write_byte(address);//表示往這個器件內部的第三個地址處寫入地址

      respons();

      write_byte(date);//表示器件內部的數據

      respons();

      stop();

      }

      void delay1(uint z)

      {

      uint x,y;

      for(x= z;x>0;x--)

      for(y=110;y>0;y--);

      }

      void main()

      {

      init();

      write_add(23,125);

      delay1(100);

      P1=read_add(23);

      while(1);

      }



    關鍵詞: I2c SPI

    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 九江市| 齐齐哈尔市| 中方县| 景谷| 德格县| 三门县| 陇西县| 富平县| 饶阳县| 香港| 镇宁| 宜都市| 会泽县| 楚雄市| 美姑县| 合水县| 北宁市| 彝良县| 铁力市| 绥江县| 鹤峰县| 晴隆县| 湘西| 甘肃省| 黔南| 改则县| 山阳县| 民丰县| 泽州县| 阿勒泰市| 昭苏县| 宁南县| 杭锦后旗| 沈阳市| 汤原县| 兴义市| 大石桥市| 十堰市| 肃南| 凌源市| 松滋市|