I2Cによる8スイッチ入力

  1. I2Cと8スイッチ入力


    1. I2C

       I2Cインタフェースについては、別項を参照してください。このインタフェースは2本のバスラインで複数の回路を接続できます。

    2. 8スイッチ入力

       wsNAKさんのボードを利用しています。16F88 を利用した小型のボードで、スイッチ8個の入力が可能です。
      図はwsNAKさんのHPより引用

       ICSP、I2Cのコネクタが利用できます。

    3. 回路図

       wsNAKさんの回路図を参照させていただきます。
       
  2. プログラム


    1. 試験用ソース

      回路のチェック用で、完成版ではありません。I2Cのマスタ側が 4bit のLEDのみなので、キー入力は4個のみしか送っていません。また、LED表示もサボっています。

      //I2C Slave
      //return SW value
      //
      
      #include <16F88.h>
      
      #fuses HS,NOWDT,NOLVP,NOMCLR,NOBROWNOUT
      #use delay(clock = 20000000)      
      #use I2c(slave,sda=PIN_B1,scl=PIN_B4,address=0x44,FORCE_HW)//address must be EvenNumber
      #use fast_io(B)
      int val2;
      int state;
      int swb,swv;
      
      #INT_SSP
      void ssp_interupt (){
          
         state=i2c_isr_state();
         //printf("state:%x\r\n",state);
         
         if(state>=0x80){//addrs match with master read
                output_bit(PIN_A3,0);
                output_bit(PIN_B0,1);
                swv=0;
                swb=~input_b();
                swv = (swb&0xc0)>>4 | (swb&0x8)>>2 | (~input_a() & 0x10)>>4;
                
                i2c_write(swv);//return sw value
                output_bit(PIN_A3,1);
          }
          else if(state >0){//adrs match with master write
                 val2=i2c_read();
                 //output_low(pin_b0);//led
          }
          
      }
      
      void main (){
       
            set_tris_b(0xFE);     //RB 7-4:IN 3-0:OUT
            set_tris_a(0xC0);
                   
            output_float(PIN_B4);  //I2C pin float
            output_float(PIN_B1);  //I2C pin float
      
            enable_interrupts(GLOBAL);      //全ての割り込みを許可
            enable_interrupts(INT_SSP);     //SSP割り込みを許可
      
            output_bit(PIN_A3,1);
                output_bit(PIN_B0,1);
             while (1) {
      
               }       
      }

    2. 試験用マスタプログラム

       上記回路をチェックする簡単な構成です。I2C接続と、ポートBの下位4ビットをLEDで表示しています。

      //////////////////////////////////////////////////
      // I2Cマスターテストプログラム      //  
      //////////////////////////////////////////////////
      
      #include <16f873a.h>
      #fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
      #use delay(clock = 20000000)      
      //#use fast_io(B)                // 固定入力モード
      #use i2c(MASTER,sda=PIN_C4,scl=PIN_C3,FORCE_HW)
      
      //メイン関数/////////////////////////////////////////
      #define KbChipa 0x44
      
      int val;
      int tm;
      
      void main(){
      
          val=0xAA;
          tm=0;
          set_tris_b(0xf0);          //RB 7-4:IN 3-0:OUT
           
          output_float(PIN_C3);       //I2C pin float
          output_float(PIN_C4);       //I2C pin float 
            
          //output_low(pin_b0); 
          delay_ms(100); //wait for Client up  
             
          while(1){
               //output_a(i2c_get(0x04));
               output_bit(PIN_A0,tm);
               output_bit(PIN_A1,tm);
               tm = ~tm;
               //if(tm ==0 ) tm=1; else tm=0;
               
               
               i2c_start();       //スタートコンディション
               i2c_write(KbChipa);
                                         
              i2c_start();
              i2c_write(KbChipA|0x1);  
              val=i2c_read(0); 
              i2c_stop();
                         
               output_b(val);
               delay_ms(500);
      
                 }
               
      }

  3. コメント


    1. 不具合

       なぜか、上段右端のスイッチが動作しません。実装上の問題のようです。

    2. 10キー

       8スイッチでなく、12スイッチ構成とし、10キー入力が可能なら、もっと利用範囲が増えるのだが、

    3. 設計

       ポートBはI2CやICSPのため連続4ビットの確保はできませんが、ポート A3-A0 は連続確保できそうなのだが。設計では、スイッチを(B7,B6,B3,A4) から入力するので、プログラムがきれいになりません。
      また、4個のLEDはスイッチのオン(読み取り時)、または、ポートの設定で発光するので、独立ではありません。