I2C接続でバーLED点灯

  1. I2C接続


    1. I2C接続の特徴

      I2C接続は、SCL(クロック信号)とSDA(双方向のデータ信号)の2本の信号で接続できる汎用のインタフェースです。この接続の例として、バー型LEDを点灯するシステムを紹介します。

    2. 回路構成

       回路は、I2Cマスタデバイスと複数のI2Cスレーブデバイスから構成されます。バーLEDの構造はLEDを並べただけなので、LEDと同じ回路で構成できます。詳細はこちらを参照してください。


    3. コマンド

      マスタ回路でI2Cの信号を送る回路なら、何でもかまいません。I2Cのコマンドは、下記のようにI2Cアドレスに続けて、0〜9の数字を送ります。0は10の扱いとします(フル点灯)。ここではI2Cアドレスは 0x68 とします。
      <I2Cアドレス><値>

  2. プログラム


    1. I2Cのマスタ側プログラム

       マスタ側のプログラムは、LEDの場合と同様ですから、こちらを参照してください。

    2. 16F88のスレーブ側プログラム

       マスタがデバイスアドレス 0x68 にデータを送信した場合、マスタからのデータを受け取り バーLED に表示します。表示する値が5の場合、左から5個のLEDをすべて点灯します。
       バーLEDは10個のLEDから構成されますが、PIC側には、連続したポートがありません。PA0-PA4,PA6,PA7,PB0,PB2,PB3、のトビトビの端子を利用します。A,B ポートにまたがり、連続でもありません。そこで、二つの配列を利用します。各配列は、表示したい値に対する、各ポートの値を設定しておきます。
      int sega[11]={0xFF,0x1,0x3,0x7,0xf,0x1f,0x7f,0xff,0xff,0xff,0xfF};
      int segb[11]={0x7,0x0,0x0,0x0,0x0,0x0, 0x0, 0x0, 0x1, 0x3, 0x7};
       表示が0(10と同じ)の場合、sega[0],segb[0]は、0xffと0x7、となりフル点灯になります。またポートBの場合、I2Cの信号がありますから、まとめて出力できません。1本づつ個別に出力します。
      //I2C LedBar Slave
      
      //マスタからのデータでAポートのLEDを点灯
      //LED Bar
      //I2Cアドレス 0x68
      //LED接続 PA0-PA4,PA6,PA7,PB0,PB2,PB3
      #include <16F88.h>
      
      //#fuses HS,NOWDT,NOLVP,NOBROWNOUT
      
      #fuses INTRC_IO,NOWDT,NOLVP,NOBROWNOUT
      #use delay(clock = 4000000) 
         
      #use I2c(slave,sda=PIN_B1,scl=PIN_B4,address=0x68,force_hw)
      
      #use fast_io(B)
      #use fast_io(A)
      
      int val;
      int state;
      
      int sega[11]={0xFF,0x1,0x3,0x7,0xf,0x1f,0x7f,0xff,0xff,0xff,0xfF};
      int segb[11]={0x7,0x0,0x0,0x0,0x0,0x0, 0x0, 0x0, 0x1, 0x3, 0x7};
      
      #INT_SSP
      void ssp_interupt (){
         state=i2c_isr_state();
         if(state>=0x80){//addrs match with master read         
                //i2c_write(0);//return  value
          }
          else if(state >0){//adrs match with master write
                 val=i2c_read(0);//1:ack,default 0:nack
             val=val %10;
             output_A(sega[val]);//1-7
             output_bit(PIN_B0,segb[val]&0x1);//8
             output_bit(PIN_B2,segb[val]&0x2);//9
             output_bit(PIN_B3,segb[val]&0x4);//10
             //output_bit(PIN_B5,segb[val]&0x8);//10
              output_toggle(PIN_B5);//受信で点滅
          }
      }
      
      void main (){
              
          set_tris_a(0x20);
                         
          output_float(PIN_B1);  //I2C pin float
          output_float(PIN_B4);  //I2C pin float
          set_tris_b(0x12); //I2Cの端子は入力に設定 
          
          val=0;
           enable_interrupts(INT_SSP);     //SSP割り込みを許可
           enable_interrupts(GLOBAL);      //全ての割り込みを許可
         
           while (1) {
            sleep();
          }
      }