I2CによるAD変換

  1. I2C接続でAD変換


    1. 目的

      センサー情報のアナログ変換は、専用のアナログ処理回路で必要な場合が多いので、AD変換後I2C接続しておくと便利です。これは、簡単なI2Cを利用した、スレーブが送出を行うシステム例になります。

  2. 回路構成


    1. スレーブ回路

       ここでは、16F88のチャンネル3に温度変換素子を増幅したopアンプの出力を接続します。
      (回路作成中)

    2. テスト用マスタ回路

       マスタ回路は、I2C接続のLED表示マスタ回路と同じです。

    3. AD変換専用IC

       実は、AD変換を行うだけなら、SPI接続の12bit8チャンネルのデバイス(MCP3208)が利用できます。SPI接続については、別項目で紹介する予定です。

  3. AD変換


    1. スレーブソース

      16F88でI2Cのスレーブを構成します。マスタからの要求に応えて、チャンネル0のAD変換値を返します。実際の処理は、割込み処理 ssp_interupt () で行っています。state>=0x80 はマスタからのデータ要求ですから、
            val= read_adc()>>2;
            i2c_write(val);//return  value
      でデータをマスタに送ります。read_adc()>>2; で2ビット右シフトし、10ビットの測定データの上位8ビットのみを転送しています。

      //I2C Slave
      
      //マスタにAD変換値を渡す
      //I2Cアドレス 0x42
      #include <16F88.h>
      
      //#fuses HS,NOWDT,NOLVP,NOBROWNOUT
      
      #fuses INTRC_IO,NOWDT,NOLVP,NOBROWNOUT
      #use delay(clock = 4000000)  //設定を間違えるとI2Cの受信を失敗する 
         
      #use I2c(slave,sda=PIN_B1,scl=PIN_B4,address=0x42,force_hw)
      
      #use fast_io(B)
      #use fast_io(A)
      
      //long val2;
      int val;
      int state;
      
      #INT_SSP
      void ssp_interupt (){
          
         state=i2c_isr_state();
        
         if(state>=0x80){//addrs match with master read        
                 
                val= read_adc()>>2;
                i2c_write(val);//return  value
                
                output_toggle(PIN_A0);//受信で点滅
          }
          else if(state >0){//adrs match with master write
                 
                 val=i2c_read();
          }    
      }
      
      void main (){
              
          set_tris_a(0x0E);
          setup_adc_ports(sAN3);
          setup_adc(ADC_clock_div_32);
          set_adc_channel(3);
                         
          output_float(PIN_B1);  //I2C pin float
          output_float(PIN_B4);  //I2C pin float
          set_tris_b(0x36); //I2Cの端子は入力に設定 
          
          val=0;
                    
           enable_interrupts(INT_SSP);     //SSP割り込みを許可
           enable_interrupts(GLOBAL);      //全ての割り込みを許可
         
           while (1) {
            //sleep();
          }              
      
      }
      

    2. テスト用マスタ

       以下は、I2C接続したAD変換回路のテスト用マスタプログラムです。
            i2c_start();       //スタートコンディション
            i2c_write(ADdva);
       で ADdva のI2Cと接続し、読み取りに必要なパラメータ(チャンネル番号など)を渡しますが、ここでは1チャンネルですので、何も送っていません。続けて、スタートコンディションを送り、ADdva+1 でADdvaのデバイスにデータ送出を要求します。
            i2c_start();       //スタートコンディション
            i2c_write(ADdva+1);
            val=i2c_read(0);
            i2c_stop();
       val=i2c_read(0); でデータを受け取ります。最後のデータ読み取りには、パラメータ 0 が必須で、これがないとハングアップします。

      // I2Cマスターテストプログラム      //  
      //I2CでLED点灯
      //I2Cデバイスアドレスは0x62
      //コマンド (num,val)、num,valは4bit
      //num:桁番号、val:値
      
      
      //マスタの回路は、C4,C3をI2C接続
      //ポートB(下位4bit)、A0 をLED表示(動作確認用)
      
      #include <16f873.h>
      #fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
      #use delay(clock = 20000000)      
      #use i2c(MASTER,sda=PIN_C4,scl=PIN_C3,FORCE_HW)
      
      //メイン関数/////////////////////////////////////////
      #define ADdva 0x42
      
      int val;
      
      
      void main(){
      
          val=0;
      
          //set_tris_c(0x99);          //RB 7-4:IN 3-0:OUT
           
          output_float(PIN_C3);       //I2C pin float
          output_float(PIN_C4);       //I2C pin float 
          //Cポートに出力する場合、set_tris_c()が必要  
          
          delay_ms(100); //wait for Client up  
             
          while(1){
      
             output_toggle(PIN_A0);//動作確認
                          
            i2c_start();       //スタートコンディション
            i2c_write(ADdva);
      
            i2c_start();       //スタートコンディション
            i2c_write(ADdva+1);
            val=i2c_read(0);
            i2c_stop();      
            
            output_toggle(PIN_B0);
            //valの表示
                                      
            delay_ms(200);
      
           }
               
      }

  4. 発展


    1. チャンネル指定

       マスタからスレーブにまずチャンネル番号を送ります。スレーブは受け取ったチャンネルのAD変換値を送ります。

    2. 2バイト出力

       マスタはスレーブに2バイトのデータを要求します。スレーブはAD変換した先頭の8ビットを送り、続けて残りの2ビットを続くバイトで送ります。