共有ADCモジュールによる
AD変換

(→プロジェクトファイル(Harmony Ver.2.04版 ) ダウンロード


 PIC32MZの場合AD変換モジュールの構成は、下図のようになっています。 図からわかるように、使用するアナログ入力ポートによってAD変換のやり方が異なります。 共有(Shared)ADCモジュールと呼ばれるADC7をつかうアナログ入力ポートに係るAD変換の例を紹介します。





<仕様>
 ・アナログ入力ポートは、AN8とし入力方式はシングルエンドとする。
 ・アナログ入力ポートから 0 ~ 3.3v(Vdd)のアナログ電圧を入力する。
 ・入力電圧読み込み値を以下の要領でキャラクタ液晶に表示する。
   1行目: 入力アナログ電圧のADC変換整数値
   2行目: 上記整数値を電圧に換算して表示する。
 ・キャラクタ液晶はI2Cインターフェースの液晶を使用のこと。
 ・AD変換モジュールの初期化 及びAD変換プログラムに於いて、 MHCやHaramonyのライブラリ関数は
  使用せずに直接レジスタを制御をおこなうこと。




<回路図>(→ PDFファイル




<外観>PIC32MZ評価ボード(→購入方法)を使った実験品の外観です。
      mikro BUS評価評価ボード(→ 購入方法) 及びmikro BUS用ユニバーサルキバン(→購入方法)には
      本テーマと関係ない部品が多々実装されています。


<動作結果> (→ 動画:1080pのHD動画を見ることができます。)

 AN8入力電圧  キャラクタ液晶画面 表示  備考 
➀ 約 0V   
➁ 約 1V  
③ 約3.3V  





<解説>(以下に、記載してある内容は要点だけです。 詳細はプロジェクトファイルを精読願います)
        (以下は、Harmony v2.04 をもとに作成しています。最新のバージョンとは異なることがあるかもしれませんので注意してください。)


 ■ MHC設定
   Options

項目 ①Config設定 
Device & Project Configuration
  > PIC32MZ2048 Device Configuration
②Harmony Framework Configuration
Drivers >I2C
MHC
備考 デフォルトからの変更要領:
 FPLLIDIV: DIV3
 FPLLICLK: PLL_POSC
 POSCMOD: EC

システムクロック周波数: 200MHz
外部OSC: 24MHz
タイマ用ペリフェラルクロック
     周波数(PBCLK3): 100MHz


#pragma config FNOSC = SPLL
#pragma config POSCMOD = EC
#pragma config FPLLIDIV = DIV_3
#pragma config FPLLICLK = PLL_POSC
#pragma config FPLLMULT = MUL_50
#pragma config FPLLODIV = DIV_2
デフォルトからの変更要領:
 I2C Module_ID: I2C_ID5
 I2C Clock Frequency: 100000 (Hz)



   Pin Settings

項目 ⑤ポート設定 
MHC
備考 デフォルトからの変更要領

RB13/Function: AN8
       (アナログ入力ポート設定))

RF4/Function: SDA5
RF5/Function: SCL5




■ プロジェクトに I2Cインターフェース用液晶表示のライブライ関数 lcd_ACM1602_lib_i2c.h と lcd_ACM1602_lib_i2c.c を追加します。
   そして、EEPROM 24LC用の読み書き用ライブラリ関数 mem_24LC_lib_i2c.h と mem_24LC_lib_i2c.cも追加します。
  ① lcd_ACM1602_lib_i2c.h と lcd_ACM1602_lib_i2c.c 及びmem_24LC_lib_i2c.h と mem_24LC_lib_i2c.cを main.cがあるフォルダにコピーします。
  ➁ 以下のように、mem_24LC_lib_i2c.h と mem_24LC_lib_i2c.cをプロジェクトファイルに追加します。



  ③以下のように mem_24LC_lib_i2c.hの中のI2CレジスタをI2C2 → I2C5に変更します。 すなわち

#define I2CXCONbits I2C2CONbits   → #define I2CXCONbits I2C5CONbits
#define I2CXSTATbits I2C2STATbits   → #define I2CXSTATbits I2C5STATbits
#define I2CXTRN I2C2TRN   → #define I2CXTRN I2C5TRN
とします。



■ app.cに、青字部分を追加します。

➀stdio.hがないと、sprintf( )がコンパイラのバージョンによってコンパイルで警告となることがあります。
  #include "stdio.h"


➁所要の変数を定義します。
  int delay_Clock = 200000000; //200MHz
  char Buf[32];


③μsec、msecの遅延関数 delay_us( )、delay_ms( )を定義します。
  void delay_us(volatile unsigned int usec) //1μsec遅延
  {
    volatile int count;

    count = (int)(delay_Clock/20000000)*usec;
  ……
  ……


④ 関数AdcFunc( )でAD変換を実行して、結果を液晶に表示します。
  ・ADCCON3bits.GSWTRG = 1;でAD変化をソフト的に開始します。
  ・while (ADCDSTAT1bits.ARDY7 == 0);でステータスレジスタのReadyビットが1になる(AD変換が終了する)まで待ちます。
  ・ AdcValue = ADCDATA7; ADC7のバッファレジスタを読み出します。
   void AdcFunc(void) //AD変換、表示
  {
    unsigned int AdcValue;
    float Volt;

    //AD変換開始 Trigger a conversion
    ADCCON3bits.GSWTRG = 1; //AD変換ソフトウェアトリガ //Global Level Software Trigger bit

    //変換完了を待つ Wait the conversions to complete
    while (ADCDSTAT1bits.ARDY7 == 0);

    //結果の取り出し fetch the result
    AdcValue = ADCDATA7;

    Volt =(float)AdcValue/4095*3.3; //ボルト表示化

    lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
    sprintf(Buf,"AdV=%u ",AdcValue); //バッファーに文字列をセット
    lcd_ACM1602_str_i2c(Buf);

    lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
    sprintf(Buf,"Volt=%.2f[V] ",Volt); //文字列としてバッファーに収納
    lcd_ACM1602_str_i2c(Buf);

    delay_ms(250);
  }



⑤void APP_Initialize ( void )の中で AD変化に係るレジスタの設定を行います。
 ソースコードに併記してあるコメントを参照願います。 PIC32MZのデータシートにあるレジスタに係る資料が
大変参考になります。 精読をおすすめします。

   // Configure ADCCON1
  ADCCON1 = 0; //
  ADCCON1bits.FRACT = 0; // use Integer output format
  ADCCON1bits.SELRES = 3; // ADC7 resolution is 12 bits //default
  ADCCON1bits.STRGSRC = 0; // No scan trigger.


  // Configure ADCCON2
  ADCCON2 = 0;
  ADCCON2bits.SAMC = 5; // ADC7 sampling time = 5 * TAD7
  ADCCON2bits.ADCDIV = 1; // ADC7 clock freq is half of control clock = TAD7


  // Configure ADCCON3
  ADCCON3 = 0;
  ADCCON3bits.ADCSEL = 0; //クロックソース:PBCLK3 // Select input clock source
  ADCCON3bits.CONCLKDIV = 1; // Control clock frequency is half of input clock
  ADCCON3bits.VREFSEL = 0; // Select AVdd and AVss as reference source
  ADCCON3bits.DIGEN7 = 1; //ADC7:有効 //Shared ADC (ADC7) Digital Enable bit
  ADCCON3bits.RQCNVRT = 1; //個別ポート入力モード //Individual ADC Input Conversion Request bit
  ADCCON3bits.ADINSEL = 8; //入力ポートに AN8 設定 //Analog Input Select bits
  ADCCON3bits.SAMP = 1; //クラス2モード設定 //Class 2 and Class 3 Analog Input Sampling Enable bit


  // No selection for dedicated ADC modules, no pre sync trigger, not sync sampling
  ADCTRGMODE = 0;

  // Select ADC input mode //ADC INPUT MODE CONTROL REGISTER 1
  ADCIMCON1bits.SIGN8 = 0; // unsigned data format
  ADCIMCON1bits.DIFF8 = 0; // Single ended mode

  ADCTRG2bits.TRGSRC7 = 1; //AN7(ADC7)をソフトウェアトリガに設定 //Trigger Source for Conversion of Analog Input AN7 Select bits   //必須


  // Turn the ADC on
  ADCCON1bits.ON = 1;


  // Enable clock to analog circuit
  ADCANCONbits.ANEN7 = 1; // Enable the clock to analog bias

  // Wait for ADC to be ready
  while(!ADCANCONbits.WKRDY7); // Wait until ADC7 is ready

  // Enable the ADC module
  ADCCON3bits.DIGEN7 = 1; // ADC7 ADCデジタル回路ON


⑥ 関数AdcFunc()をAPP_Tasks( )で250msec毎に呼び出し、AD変換を実行し表示します。
  AdcFunc();



以下、app.c