YS電子工作ラボ

<V.3版>
共有ADCモジュールによる
AD変換

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


 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  





<解説>(以下に、記載してある内容は要点だけです。 詳細はプロジェクトファイルを精読願います)
       


 ■ MHC設定  

項目 1. [Clock Diagram]タブで、クロックの構成を外付け24MHz水晶発振器用、システムクロック200MHzに設定します。
 POSCMOD: → EC
 FPLLICLK: → POSC
 FPLLIDIV: → DIV_3
2. [Prpject Graph]タブでの設定
■追加コンポーネント
  ADCHS, I2C5
■ コンポーネント間の接続
 なし

■ ソースコードで直接レジスタの設定をおこなうので、コンポーネントでの設定は行いません
MHC




■ プロジェクトに 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
とします。



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

➀stdio.hがないと、sprintf( )がコンパイラのバージョンによってコンパイルで警告となることがあります。
  #include <stdio.h>
  #include "lcd_ACM1602_lib_i2c.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 )を追加します。 関数の名称はPP_Initialize ( )でなくてもOKです。 AD変化に係るレジスタの設定を行います。
 ソースコードに併記してあるコメントを参照願います。 PIC32MZのデータシートにあるレジスタに係る資料が
大変参考になります。 精読をおすすめします。

void APP_Initialize ( void )
{

   // 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


}


⑥ main の最初で APP_Initialize ( );を呼び出し モジュールを初期化します。
  APP_Initialize ( ); 


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



以下、main.c