I2C總線是PHILIPS公司推出的一種具備多主機系統(tǒng)所需的包括裁決和高低速設備同步等功能的高性能串行總線。它使用兩條線:串行數(shù)據(jù)線(SDA)和串行時鐘線(SCL),使連接到該總線上可訪問的器件之間傳送信息,屬于多主控制總線。總線上的每個器件都有唯一的地址識別,而且都可以作為一個發(fā)送器或接收器。由于I2C總線的使用可以簡化電路,省掉了很多常規(guī)電路中的接口器件,提高產(chǎn)品的可靠性,">

      技術頻道

      I2C總線在8051單片機系統(tǒng)中的應用

      1、引言
        I2C總線是PHILIPS公司推出的一種具備多主機系統(tǒng)所需的包括裁決和高低速設備同步等功能的高性能串行總線。它使用兩條線:串行數(shù)據(jù)線(SDA)和串行時鐘線(SCL),使連接到該總線上可訪問的器件之間傳送信息,屬于多主控制總線。總線上的每個器件都有唯一的地址識別,而且都可以作為一個發(fā)送器或接收器。由于I2C總線的使用可以簡化電路,省掉了很多常規(guī)電路中的接口器件,提高產(chǎn)品的可靠性,在許多領域尤其在目前使用的IC卡獲得了廣泛的應用。
        現(xiàn)今,8051系列的單片機應用很廣,但是它們都沒有I2C總線接口。但是分析I2C總線的時序可知, I2C總線規(guī)定其時鐘線(SCL線)和和數(shù)據(jù)線(SDA線)是各設備對應輸出狀態(tài)相“與”的結(jié)果,任一設備都可以用輸出低電平的方法延長SCL低電平時間,迫使高速設備進入等待狀態(tài),實現(xiàn)不同速度設備間的時鐘同步。因此,即使時鐘脈沖的高、低電平時間長短不一,也能實現(xiàn)數(shù)據(jù)的可靠傳送,因此我們可以通過軟件控制單片機的普通I/O口做I2C接口,實現(xiàn)I2C總線功能。本文以ATMEL公司的具有I2C總線的AT24C256為例介紹I2C總線在8051單片機系統(tǒng)中的應用并給出C語言的軟件實現(xiàn)。
        2、I2C總線構(gòu)成及時序
        2.1 I2C總線組成
        I2C總線是一個多主機總線,即可以連接多于一個能控制總線的器件到總線。I2C串行總線有兩根信號線:一根雙向的數(shù)據(jù)線SDA;另一根是時鐘線SCL。SDA和SCL都是雙向I/O口線,當總線空閑時這兩條線路都是高電平。所有接到I2C總線上的器件的串行數(shù)據(jù)線都接到總線的SDA線,各器件的時鐘線都接到SCL總線上。其結(jié)構(gòu)如圖一所示。


      圖一:I2C總線的組成
      圖一:I2C總線的組成

        2.2 I2C總線時序
        所有主機在SCL線上產(chǎn)生自己的時鐘來傳輸I2C總線上的數(shù)據(jù),數(shù)據(jù)只在時鐘的高電平周期有效,每傳輸一個數(shù)據(jù)位就產(chǎn)生一個時鐘脈沖,數(shù)據(jù)線的高或低電平狀態(tài)只有在SCL線的時鐘信號是低電平時才能改變,當SCL為高電平時,SDA的改變表示“開始”和“停止”狀態(tài),即SDA由高電平轉(zhuǎn)入低電平表示開始,該命令必須在其它命令前執(zhí)行;SDA由低電平轉(zhuǎn)入高電平表示停止狀態(tài),該命令可終止所有通訊。在開始條件后,SCL低電平期間,SDA允許變化,每位數(shù)據(jù)需一個時鐘脈沖,當SCL為高時,SDA必須穩(wěn)定,主控器在應答時鐘脈沖高電平期間釋放SDA線,轉(zhuǎn)由接收器控制。相同總線上的設備在收到數(shù)據(jù)后,以置SDA為低電平的方式對其確認。總線不忙時,數(shù)據(jù)線和時鐘線保持為高電平。I2C的時序如圖二所示。

      圖二:I2C總線時序圖
      圖二:I2C總線時序圖
        3、8051單片機系統(tǒng)中I2C總線的實現(xiàn)
        8051系列單片機上并不帶I2C總線,因此必須根據(jù)I2C總線的時序用單片機上的I/O口模擬I2C總線時序?qū)崿F(xiàn)其功能。現(xiàn)以單片機應用系統(tǒng)中較為常見的E2PROM中AT24C256為例,介紹在8051上利用普通I/O口實現(xiàn)I2C串行總線的方法和軟件設計。
        AT24C256是ATMEL公司256kbit串行電可擦的可編程存儲器,8引腳雙排直插式封裝,具有結(jié)構(gòu)緊湊、存儲容量大等特點,其引腳排列如圖三所示。

      圖三:AT24C256引腳圖
      圖三:AT24C256引腳圖
        其中A0、A1為地址選擇輸入端。A0、A1用來區(qū)分各芯片地址,地址分布從0到3。A0、A1懸空時為0。SCL為串行時鐘輸入,上升沿將SDA上的數(shù)據(jù)寫入存儲器,下降沿從存儲器讀出數(shù)據(jù)送SDA上。SDA是雙向串行數(shù)據(jù)輸入輸出口,用于存儲器與單片機之間的數(shù)據(jù)交換。WP為寫保護輸入。此引腳與地相連時,允許寫操作;與VCC相連時,所有的寫存儲器操作被禁止。如果不連,芯片內(nèi)部下拉到地;VCC接+5V電源;GND接地;NC懸空。
        AT24C256在開始狀態(tài)后需緊接一個8位器件地址,以進行相應的讀寫操作。設備尋址碼的高4位為1、0、1、0,尋址碼高4位后面的三位是器件尋址碼,與它們的硬連線管腳相對應。最低應是讀寫選擇位,置0時可激發(fā)寫操作,置1激發(fā)讀操作。器件的具體的格式為:1010A2A1A0R/W,其中當R/W為0時,為寫AT24C256,當為1時為讀操作。
        因為AT24C256片內(nèi)地址是以8位為單元的,其總存儲容量為256K,所以其片內(nèi)地址為從0到32767的任意數(shù)值。因此在編寫軟件時設置其片內(nèi)地址數(shù)據(jù)類型時要設置為unsigned int型,而不能為unsigned char型。
        圖四所示為AT89S51單片機和AT24C256的接口圖,分別用I/O口P1.6、P1.7連接SDA和SCL總線。通過控制P1.7口的高低電平得到I2C的虛擬時鐘,P1.6口作為數(shù)據(jù)傳輸?shù)碾p向端口,作為單片機和AT24C256之間的數(shù)據(jù)線。


        4、虛擬I2C總線軟件結(jié)構(gòu)
        對于虛擬I2C總線來說要實現(xiàn)其功能主要是要軟件要注意I2C器件的操作時序,總線的運行由主機控制。所謂主機即啟動數(shù)據(jù)的傳送即發(fā)出啟動信號,發(fā)出時鐘信號,傳送結(jié)束時發(fā)出停止信號的設備,通常主機是微處理器。被主機尋訪的設備都稱為從機。為了進行通訊,每個接到I2C總線的設備都有一個唯一的地址,以便于主機尋訪。主機和從機的數(shù)據(jù)傳送,可以由主機發(fā)送數(shù)據(jù)到從機,也可以是從機發(fā)到主機。凡是發(fā)送數(shù)據(jù)到總線的設備稱為發(fā)送器,從總線上接收數(shù)據(jù)的設備被稱為接受器。根據(jù)I2C的時序,軟件分為開始、停止、應答、檢查應答、不產(chǎn)生應答、讀操作、寫操作。以下為C程序清單調(diào)試成功。
        #include
        Sbit sda=P1^7;
        Sbit scl=P1^6;
        啟動函數(shù),在SCL為高時,SDA的下降沿為啟動信號。
      void Start(void)
      { scl=0; //SCL處于低電平時,SDA才能改變
      sda=1;// 一個"開始"狀態(tài),該狀態(tài)必須在其他命令之前執(zhí)行
      scl=1; // 當scl為高電平時sda的下降沿表示開始狀態(tài)
      _nop_(); _nop_(); _nop_(); //給一個延時
      sda=0; //給下降沿表示開始
      _nop_(); _nop_(); _nop_(); _nop_();
      scl=0; //恢復低電平以改變sda的值
      sda=1; }
        停止函數(shù),在SCL為高時,SDA的上升沿為停止信號。
      void Stop(void)
      {scl=0; //SCL處于低電平時,SDA改變數(shù)值 */
      sda=0; //scl為高電平時,sda的上升沿表示停止,
      scl=1; //scl為高電平時改變sda的狀態(tài)表示啟動,停止
      _nop_(); _nop_(); _nop_(); // 延時
      sda=1;
      _nop_(); _nop_(); _nop_();
      scl=0; }
      /* * * * * 檢查應答位 * * * * */
      bit RecAck(void)
      { scl=0; //在scl為0的時候改變sda的值
      sda=1;
      scl=1; //在scl為1的時候等待sda值的變化,在器件接受到數(shù)據(jù)后會把sda拉低。
      _nop_(); _nop_(); _nop_(); _nop_();
      CY=sda; // 因為返回值總是放在CY中的
      scl=0;
      _nop_();
      return(CY); //如果為CY為低則表示接受成功,如果為高,則表示接受失敗。
      }
      /* * * * *對I2C總線產(chǎn)生應答(一般用在讀操作中) * * * * */
      void Ack(void)
      {
      sda=0;// EEPROM通過在收到每個地址或數(shù)據(jù)之后,
      _nop_();_nop_();
      scl=1;//置SDA低電平的方式確認表示收到讀SDA口狀態(tài)
      _nop_(); _nop_(); _nop_(); _nop_();
      scl=0;
      _nop_();
      sda=1;
      }

      /* * * * * * * * * 不對I2C總線產(chǎn)生應答 * * * * */
      void NoAck(void)
      { sda=1;
      scl=1;
      _nop_(); _nop_(); _nop_(); _nop_();
      scl=0;
      }
        向I2C總線寫數(shù)據(jù),每次寫8位數(shù)據(jù)。
      void Send(uchar sendbyte)
      {uchar j=8;
      for(;j>0;j--)
      {scl=0;//拉低scl準備給上升沿
      delay(5);//延時
      sendbyte <<= 1;// 使CY=sendbyte^7;
      sda=CY; // CY 進位標志位
      scl=1; //給上升沿,發(fā)出sda的狀態(tài)值
      }
      scl=0;
      }
        從I2C總線上讀數(shù)據(jù)子程序 ,每次讀8位數(shù)據(jù)。
      uchar Receive(void)
      { register receivebyte,i=8;
      scl=0;
      while(i--)
      { scl=1; //拉高scl準備給下降沿
      receivebyte=(receivebyte <<1)|sda; //接受值左移一位把低位和sda相或得到sda的狀態(tài)值
      scl=0; //給下降沿發(fā)出sda的狀態(tài)值
      }
      return(receivebyte);
      }
        5、結(jié)論
        本文介紹了I2C總線的組成及時序,并以ATMEL公司的AT24C256為例給出了用8051C語言模擬I2C總線的時序的起始、停止及CPU向I2C總線的發(fā)送和接收8位字節(jié)的程序。

      文章版權歸西部工控xbgk所有,未經(jīng)許可不得轉(zhuǎn)載。

      主站蜘蛛池模板: 国产在线观看一区精品| 亚洲Av无码一区二区二三区| 亚洲一区二区三区在线观看蜜桃| 精品国产一区二区麻豆| 亚洲AV福利天堂一区二区三| 日韩精品一区二区三区影院| 亚洲欧洲无码一区二区三区| 久久久久成人精品一区二区| 久久99久久无码毛片一区二区| 精品乱码一区二区三区在线| 成人国产精品一区二区网站公司| 亚洲美女视频一区| 搡老熟女老女人一区二区| 亚洲一区二区三区影院 | 色狠狠一区二区三区香蕉| 中文字幕一区二区在线播放| 一区二区三区四区视频在线| 精品一区二区AV天堂| 无码欧精品亚洲日韩一区| a级午夜毛片免费一区二区 | 韩国福利一区二区美女视频| 久久福利一区二区| 人妻激情偷乱视频一区二区三区| 亚洲电影一区二区| 久久久久人妻一区二区三区| 精品福利一区二区三区免费视频| 无码av免费毛片一区二区| 亚洲.国产.欧美一区二区三区| 国产主播在线一区| 国产综合无码一区二区色蜜蜜| 免费无码一区二区三区蜜桃大| 国产伦精品一区二区| 日本一区二区三区不卡视频中文字幕| 偷拍精品视频一区二区三区| 国产婷婷一区二区三区| 国产一区二区三区91| 国产精品视频一区二区三区经| 亚洲AV香蕉一区区二区三区| 精品91一区二区三区| 日韩精品无码一区二区三区AV | 亚洲国产一区二区a毛片|