I 2 Cバスの(一)---概要

11391 ワード

記事の転載先http://www.cnblogs.com/BitArt/archive/2013/05/27/3101037.htmlああ、ここでブロガーに感謝します.
一、概説
  • I²CはInter-integrated Circuitの略で、発音は「eye-squared cee」or「eye-two-cee」で、2線インタフェースです.
  • I²Cは2本の双方向の線、1本のSerial Data Line(SDA)、もう1本のSerial Clock(SCL)を使うだけです.
  • SCL:立ち上がりエッジは各EEPROMデバイスにデータを入力する.下降駆動EEPROMデバイスに沿ってデータを出力します.(エッジトリガ)
  • SDA:双方向データ線であり、ODゲートであり、他の任意の数のODとOCゲートと「線与」関係にある.

  • しゅつりょくレベル
    I 2 Cバス装置内部のSDA、SCLピン回路構成は同一であり、ピンの出力駆動は入力バッファに接続されている.ここで出力はドレイン開路の電界効果管であり、入力バッファは高入力インピーダンスの同相器であり、この回路は2つの特徴を持っている:1)SDA、SCLはドレイン開路構造(OD)であるため、それらは引張抵抗を接続しなければならず、抵抗値の大きさは常に1 k 8、4 k 7 and 10 kであるが、1 k 8の時性能が最も良い;バスが空いている場合、2本の線はいずれもハイレベルです.バスに接続されたいずれかのデバイスが出力するローレベルは、バスの信号を低くします.すなわち、各デバイスのSDAおよびSCLは線「与」関係になります.2)ピンは、信号を出力するとともにピンのレベルを検出し、先ほどの出力と一致するか否かを検出し、「クロック同期」と「バス調停」にハードウェア基盤を提供する.

  • プライマリ・デバイスとスレーブ・デバイス
    システム内のすべての周辺デバイスは、7ビットの「スレーブデバイス専用アドレスコード」を有し、そのうち上位4ビットはデバイスタイプであり、メーカーが作成し、下位3ビットはデバイスピン定義アドレスであり、使用者が定義する.マスタデバイスは、アドレスコードを介してマルチマシン通信のメカニズムを確立するので、I 2 Cバスは、バスに複数のデバイスが接続されていても、システムが簡潔な二線構造であるように、周辺デバイスのチップ選択線を省くことができる.端末はバスに搭載され、主端と従端の区別があり、主端はCPU付きの論理モジュールでなければならず、同じバス上で同じ時刻に1つの主端を持つことができ、複数の従端を持つことができ、従端の数はアドレス空間とバスの最大容量400 pFによって制限される.  
  • メインエンドは主にSCLラインを駆動するために使用される.
  • は、デバイスからプライマリデバイスに応答する.


  •  
    両方ともデータを転送することができるが、デバイスから転送を開始することができず、転送はプライマリデバイスによって制御される.
     
     
      4.速度:
    通常モード:100 kHz;
    高速モード:400 kHz;
    高速モード:3.4 MHz;
    高速SCLを使う必要はありません.SCLを100 k以下にして忘れましょう.
    二、協議
    1.アイドル状態I 2 CバスバスのSDAとSCLの2本の信号線が同時にハイレベルであり、バスのアイドル状態として規定されている.このとき,各素子の出力段電界効果管はいずれもカットオフ状態,すなわち解放バスにあり,2本の信号線のそれぞれの引張抵抗によってレベルが高くなる.2.開始ビットと停止ビットの定義:
  • 開始信号:SCLが高い間、SDAは高いから低いへジャンプする.起動信号は、レベルホッピングシーケンス信号であり、レベル信号ではない.
  • 停止信号:SCLが高い間、SDAは低いから高いへジャンプする;停止信号もレベルホッピングシーケンス信号であり、レベル信号ではない.

  • I2C总线之(一)---概述_第1张图片 3.ACK
    送信機は、1バイトずつ送信すると、クロックパルス9の間にデータ線を解放し、受信機から応答信号をフィードバックする.応答信号は低レベルであり、有効応答ビット(ACKは応答ビットと略称する)と規定され、受信機がこのバイトを正常に受信したことを示す.応答信号は高レベルであり、非応答ビット(NACK)と規定されており、受信機がこのバイトを受信することに成功しなかったことを示すのが一般的である.フィードバック有効応答ビットACKについては、受信器は、9番目のクロックパルスより前のローレベル期間においてSDA線を低くし、そのクロックのハイレベル期間において安定したローレベルであることを確保することが要求される.受信機がマスタである場合、最後のバイトを受信した後、制御された送信機にデータ送信の終了を通知し、SDAラインを解放して、マスタ受信機が停止信号Pを送信するようにNACK信号を送信する.
    I2C总线之(一)---概述_第2张图片
                    :     ,        ,sda          ,             ,        ,         。
    
                :1)    SCL                SDA;2)         SCL      ;              。

     
    4.      : 

     
    I2C         ,          ,             ,                ,                   。 
    
        :               ,         ,      SCL             ,     I2C   ( )---         ,    SCL         (EEPROM)  。

       

    5.データの転送:
     
    I 2 Cバス上で伝送される各データには、SCLシリアルクロックの組み合わせにより、SDA上で各データが1ビットずつシリアル伝送されるクロックパルスが対応する(または同期制御される).データビットの転送はエッジトリガです.
    二、作業過程
    バス上のすべての通信はホストコントローラによって開始されます.1回の通信では、メインコントローラと被コントローラは常に2つの異なる役割を果たしています.
    1.マスタ装置からスレーブ装置へのデータ送信
    プライマリ・デバイスは、バス上のすべてのデバイスの転送が開始されたことを通知し、次にホストはデバイス・アドレスを送信し、このアドレスに一致するslaveはこの転送プロセスを継続し、他のslaveは次の転送を無視して次の転送の開始を待つ.プライマリ・デバイスは、スレーブ・デバイスにアドレスされた後、それを読み出すか書き込むスレーブ・デバイスの内部レジスタ・アドレスを送信する.その後、データを送信します.データ送信完了後、送信停止ビット:
    書き込みプロセスは次のとおりです.
    送信開始ビット
  • は、デバイスのアドレスおよび読み書き選択ビットを送信する.バスを解放し、EEPROMがバスを下げて応答するまで待つ.EEPROM受信が成功した場合、応答を行う.握手に成功または送信されたデータエラーがない場合、EEPROMは応答を生じず、再送または終了を要求する.
  • は、書き込みたい内部レジスタアドレスを送信する.EEPROMはそれに応答する.
  • 送信データ
  • は、停止ビットを送信.
  • EEPROMは停止信号を受信した後、1つの内部への書き込み周期に入り、約10 msを必要とし、この間のいかなる操作もEEPROMに応答されない.(そのため、このような2回の書き込みの間に遅延を挿入する必要があります.そうしないと、失敗します.ブロガーはここで小さな穴を開けました)
  • I2C总线之(一)---概述_第3张图片
       
    詳細:
    I2C总线之(一)---概述_第4张图片
    説明する必要があるのは、1マスタはアドレスコードを送信することによって対応するマスタと通信関係を確立し、バスに接続された他のマスタは同時にアドレスコードを受け取ったが、それ自体のアドレスと一致しないため、マスタとの通信を早期に終了する.
     
    2.マスタがデータを読み込むプロセス:
    読み取りのプロセスは複雑です.slaveからデータを読み出す前に、どの内部レジスタが読み取りたいのかを教えなければなりません.そのため、まず書き込み(dummy write):
  •   slave  +write bit set;
  •        , restart;
  •     slave  +read bit set;
  •     
                    ,     ACK  。  ,       SDA ,       P      。 
  •         

  •  

    三、検証
    I 2 Cバスの理解を深めるため、C言語でIICバスをシミュレートし、ソースコードを見ながら波形を読みます.
    次の図に示すように、書き込み動作のタイミングチャートを示します.

     

    読み方の理解は同じです.タイミングがわからない方は「I 2 Cバスの(2)---タイミング」を参考にしてください
    完全な手順は次のとおりです.
    #include
    #define uchar unsigned char
    #define uint unsigned int
    #define write_ADD 0xa0
    #define read_ADD 0xa1
    uchar a;  
    sbit SDA=P2^0;
    sbit SCL=P2^1;
    void SomeNop();     //   
    void init();    //   
    void check_ACK(void);
    void I2CStart(void);
    void I2cStop(void);
    void write_byte(uchar dat);//   
    void delay(uint z);
    uchar read_byte();     //   
    void write(uchar addr,uchar dat);  //     
    uchar read(uchar addr);       //     
    bit flag;  //     
    void main()
    {
        init();
        write_add(5,0xaa); //   5  0xaa
        delay(10);      //  ,     !!!
         P1=read_add(5);      //    5  
         while(1);    
    }
    
    
    
    //***************************************************************************  
    void delay()//        
    { ;; }  
    //***************************************************************************  
    void start()  //     SCL      ,SDA              
    {     
        sda=1; //  SDA    
        delay();  
        scl=1;  
        delay();  
        sda=0;  
        delay();  
    }  
    //***************************************************************************  
    void stop()   //   SCL      ,SDA              
    {  
        sda=0;  
        delay();  
        scl=1;  
        delay();  
        sda=1;  
        delay();  
    }
    //***************************************************************************  
    void respons()  //   SCL      ,SDA               
    {  
        uchar i;  
        scl=1;  
        delay(); 
        //    250 CPU     
        while((sda==1)&&(i<250))i++;  
        scl=0;  
        delay();  
    }  
    //***************************************************************************  
    void init()//                          ,       。                     
    {  
        sda=1;  
        delay();  
        scl=1;  
        delay();  
    }  
    //***************************************************************************  
    void write_byte(uchar date) //       
    {  
        uchar i,temp;  
        temp=date;  
      
      
        for(i=0;i<8;i++)  
        {  
            temp=temp<<1;  
            scl=0;//  SCL,                                ;           scl=1           
            delay();  
            sda=CY;  
            delay();  
            scl=1;//  SCL,  SDA        
            delay();  
        }  
        scl=0;//  SCL,             
        delay();  
        sda=1;//  SDA  ,         ,           , SCL   ,  SDA        
        delay();  
    }  
    //***************************************************************************  
    uchar read_byte()//       
    {  
        uchar i,k;  
        scl=0;  
        delay();  
        sda=1;  
        delay();  
        for(i=0;i<8;i++)  
        {  
            scl=1;//    ,IIC       sda  ,             ,       
            delay();      
            k=(k<<1)|sda;  
            scl=0;//  SCL,           SDA   
            delay();      
        }  
        return k;  
    }  
    //***************************************************************************  
    void write_add(uchar address,uchar date)//           
    {  
        start();//    
        write_byte(0xa0);//         
        respons();//          
        write_byte(address);//         
        respons();//          
        write_byte(date);//      
        respons();//          
        stop();//    
    }  
    //***************************************************************************  
    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;//      
    }