新聞中心

        EEPW首頁 > 手機(jī)與無線通信 > 設(shè)計(jì)應(yīng)用 > I2C串行總線組成及其工作原理

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

        作者: 時(shí)間:2017-01-10 來源:網(wǎng)絡(luò) 收藏

          采用串行總線技術(shù)可以使系統(tǒng)的硬件設(shè)計(jì)大大簡(jiǎn)化,系統(tǒng)的體積減小,可靠性提高,同時(shí)系統(tǒng)更容易更改和擴(kuò)充

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

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

          總線只有兩根雙向信號(hào)線,一根是數(shù)據(jù)線SDA,另一根是時(shí)鐘線SCL

            

         

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

          當(dāng)總線閑置的時(shí)候,兩根線均為高電平,連接到總線上的任何一個(gè)器件輸出的低電平,都將使得總線得到信號(hào)變低,及各個(gè)器件的SDA和SCL都是線與的關(guān)系

          每個(gè)接入到I2C總線都有唯一的地址,主機(jī)與其他器件間的數(shù)據(jù)傳送可以是由主機(jī)發(fā)送數(shù)據(jù)到其他器件,這時(shí)主機(jī)即是發(fā)送器,由總線上接收數(shù)據(jù)的器件稱為是接收器。

          在多主機(jī)系統(tǒng)中,可能同時(shí)由幾個(gè)主機(jī)企圖啟動(dòng)總線傳送數(shù)據(jù),為了避免混亂,I2C總線要通過總線仲裁,已決定由哪臺(tái)主機(jī)控制總線

          數(shù)據(jù)位的有效性

          I2C總線進(jìn)行數(shù)據(jù)傳送時(shí),時(shí)鐘信號(hào)為高電平期間,數(shù)據(jù)線上的數(shù)據(jù)必須保持穩(wěn)定,只有時(shí)鐘線上的信號(hào)為低電平期間,數(shù)據(jù)線上的高電平和低電平狀態(tài)才允許變化

            

         

          起始信號(hào)和終止信號(hào)

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

            

         

          數(shù)據(jù)傳送的格式

          (1)字節(jié)傳送與應(yīng)答

          每一個(gè)字節(jié)必須保證是8位長(zhǎng)度,數(shù)據(jù)傳送時(shí),先傳送的是最高位(MSB),每一個(gè)被傳送的字節(jié)后面都必須跟隨一位應(yīng)答位,即(一幀共有9位),應(yīng)答信號(hào)由從機(jī)發(fā)送給主機(jī)

            

         

          每次數(shù)據(jù)傳送總是由主機(jī)產(chǎn)生的終止信號(hào)結(jié)束,但是若主機(jī)希望繼續(xù)占用總線進(jìn)行新的數(shù)據(jù)傳送,則可以不產(chǎn)生終止信號(hào),馬上再次發(fā)出起始信號(hào)對(duì)另一個(gè)從機(jī)進(jìn)行尋址

          在總線的一個(gè)數(shù)據(jù)傳上過程中,可以有一下幾種傳送方式的組合方式

          a,主機(jī)向從機(jī)發(fā)送數(shù)據(jù),數(shù)據(jù)傳送的方向在整個(gè)傳送過程中不變

            

         

          A表示應(yīng)答,A非表示非應(yīng)答,s表示其實(shí)信號(hào),p表示終止信號(hào)

          主機(jī)發(fā)送地址時(shí),總線上的每一個(gè)從機(jī)都將這7位地址碼與自己的地址進(jìn)行比較,如果相同,則認(rèn)為自己正在被主機(jī)尋址,根據(jù)R/T位將自己確定為發(fā)送器或接收器

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

            

         

          由操作時(shí)序可知要進(jìn)行必要的延時(shí)

          起始操作示例代碼:

          void T2CStart(void)

          {

          SDA = 1;

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

          SCL = 1;

          SomeNop();

          SDA = 0;

          SomeNop();

          }

          終止指令:

          void I2CStop(void)

          {

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

          SomeNop();

          SCL = 1;

          SomeNop();

          SDA = 1;

          SomeNop();

          }

          I2C總線擴(kuò)展  

         

          串行E2PROM的擴(kuò)展

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

          單片機(jī)進(jìn)行寫操作的時(shí)候,首先

          發(fā)送該器件的7位地址嗎和寫方向的方向碼0,發(fā)送完以后釋放SDA線并在SCL線上產(chǎn)生第九個(gè)時(shí)鐘信號(hào),被選中的存儲(chǔ)器再確認(rèn)自己的地址后,在SDA上產(chǎn)生一個(gè)應(yīng)答信號(hào)作為響應(yīng)

          ,單片機(jī)接收到信號(hào)就可以傳送數(shù)據(jù)了

          傳送數(shù)據(jù)時(shí),單片機(jī)首先發(fā)送一個(gè)字節(jié)的被寫入器件的存儲(chǔ)區(qū)的首地址,收到存儲(chǔ)器器件的應(yīng)答后,單片機(jī)就逐個(gè)發(fā)送各個(gè)數(shù)據(jù)的字節(jié),但是每次發(fā)送一個(gè)字節(jié)后都要等待應(yīng)答

          收到每個(gè)字節(jié)的地址后,芯片上的地址會(huì)自動(dòng)加一

          寫入n個(gè)字節(jié)的數(shù)據(jù)格式

            

         

          讀出過程

          單片機(jī)首先發(fā)送該器件的7位地址碼和寫方向位0(偽寫),發(fā)送完后釋放SDA線并在SCL線上產(chǎn)生9個(gè)時(shí)鐘信號(hào),被選中的存儲(chǔ)器器件在確認(rèn)自己的地址之后,在SDA上產(chǎn)生一個(gè)應(yīng)答信號(hào)作為回應(yīng)

          然后在發(fā)送一個(gè)字節(jié)的要讀出存儲(chǔ)去的首地址,收到應(yīng)答,單片機(jī)要重復(fù)一次起始信號(hào)并發(fā)出器件地址的讀方向位(1),收到器件應(yīng)答就可以讀出字節(jié),每次讀出一個(gè)字節(jié),單片機(jī)都要回復(fù)一個(gè)應(yīng)答信號(hào),但最后讀出一個(gè)字節(jié),單片機(jī)應(yīng)返回非應(yīng)答信號(hào)(高電平)并發(fā)出終止信號(hào)以結(jié)束讀出操作

            

         

          示例代碼:

          #include

          #define uchar unsigned char

          #define uint unsigned int

          sbit sda = P2^3;

          sbit scl = P2^2;

          sbit wp = P2^1;

          void delay()//微妙級(jí)別的延時(shí)函數(shù)

          {;;}

          void start()//開始信號(hào)

          {

          sda = 1;

          delay();

          scl = 1;

          delay();

          sda = 0;

          delay();

          }

          void stop()//停止信號(hào)

          {

          sda = 0;

          delay();

          scl = 1;

          delay();

          sda = 1;

          delay();

          }

          void respons()//應(yīng)答信號(hào)

          {

          uchar i;

          scl = 1;

          delay();

          while((sda ==1)&&(i<250))//等到第九個(gè)時(shí)鐘周期的時(shí)候,還沒有變?yōu)?,

          //那么scl將自動(dòng)的變?yōu)?,表示收到信號(hào)

          {

          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,送走數(shù)據(jù)

          scl = 1;//數(shù)據(jù)穩(wěn)定了

          delay();

          sda = CY;

          delay();

          scl = 0;//讀走數(shù)據(jù)

          delay();

          }

          sda = 1;//注意養(yǎng)成釋放總線的習(xí)慣

          delay();

          }

          uchar read_byte()

          {

          uchar i,j,k;

          scl = 0;

          delay();

          sda = 1;//釋放數(shù)據(jù)總線

          delay();

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

          {

          scl = 1;

          delay();

          j = sda ;//讀取數(shù)據(jù)

          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();//初始化信號(hào)總線和地址總線

          start();//啟動(dòng)信號(hào)

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

          respons();

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

          respons();

          write_byte(date);//表示器件內(nèi)部的數(shù)據(jù)

          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);

          }



        關(guān)鍵詞: I2c SPI

        評(píng)論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 黎城县| 万盛区| 青田县| 于都县| 营口市| 衡山县| 平利县| 阿勒泰市| 阿拉尔市| 金湖县| 三门县| 冷水江市| 古蔺县| 曲靖市| 定安县| 黄冈市| 南城县| 龙海市| 双鸭山市| 达拉特旗| 永靖县| 桂东县| 鸡西市| 湟中县| 宝丰县| SHOW| 沅陵县| 长治市| 正阳县| 长阳| 钟山县| 玉龙| 木兰县| 盐边县| 晋州市| 大石桥市| 南乐县| 丹江口市| 曲靖市| 普定县| 肥乡县|