YS電子工作ラボ

1ch 1ADC変換

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


  PIC32MXのAD変換モジュールと比較すると分解能が10ビットから12ビットに変わっただけでなく、ADCモジュールの構成が大きく変わりました。一言で云うと 32MXは1つの共通ADCを入力チャンネルを切り替えてつかっていましが、32MZでは
5個の専用ADCと1つの共通ADCという構成になりました。 これら合計6個のADCはサンプル時間、変換時間が
お互いに独立なので複数の入力を並列に処理できることから高速処理が可能となっています。

 ここでは基本となる シングルエンドの1チャンネルAD変換の例を紹介します。 2チャンネル並列高速処理の例は 2ch 2ADC同時変換を
参照願います。



<仕様>
 ・アナログ入力ポートから 0 ~ 3.3v(Vdd)のアナログ電圧を入力する。
 ・アナログ入力ポートは、AN4(RB4)とし入力方式はシングルエンドとする。
 ・入力電圧読み込み値を以下の要領でキャラクタ液晶に表示する。
   1行目: 入力アナログ電圧のADC変換整数値
   2行目: 上記整数値を電圧に換算して表示する。
 ・AD変換は250msec毎にタイマ割り込みを行い、これを液晶に表示する。
 ・タイマはスタティクタイマを使用する。
 ・割り込み動作確認用として、250msec毎にLEDのON/OFFを行う。
 ・起動後、液晶に以下を表示する。
   1行目: "From Now"
   2行目: "AD Start !!"


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



<外観> PIC32MZ評価ボード(→購入方法)を使った実験品の外観です。
     汎用モジュール評価ボード(段積みボード)には本テーマと関係ない部品が多々実装されています。また、グラフィック液晶は
     本テーマと関係ないのではずしています。


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

起動直後 アナログ入力電圧(AN4/RB4)
 1行目: ADCの変換整数値
 2行目: 電圧換算表示 
約 0.01v 約 1.00v 約 3.26v



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


 ■ MHC設定
   Options

項目 ①Config設定 
Device & Project Configuration
  > PIC32MZ2048 Device Configuration
②ADC設定1
Harmony Framework Configuration > Drivers
 > ADC
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
デフォルトからの変更要領:
 □Use ADC Driver? チェックを追加
 □Channel Instance 0 チェックを追加
 Channel Selection: ADCHS_CHANNEL_4
 Channel1-4 .......... Input Selection:
          ADCHS_DEFAULT_CLASS1_AN4


AN4(RB4)は ADC4専用ADCモジュール(Dedicated
ADC modules)を AD変換モジュールとしています。
    (参照 → PIC32MZ ADCブロック図)
        (出典:マイクロチップ社 データシートDS60001320C
項目 ③ADC設定2
Harmony Framework Configuration > Drivers
 > ADC
④タイマ設定
Harmony Framework Configuration > Drivers
 > Timer
MHC
備考 デフォルトからの変更要領:
 以下、チェックをはずす(あっても動作します)
□Enable class2 Analogue Input Conversion?
□Enable Analogue Input scanning ?
□Enable Digital Comparator?
□Enable Digital Comparator Interrupt?
□Enable Digital Filter?
□Enable Digital Filter Interrupt?
□Enable CVC(Capacitive voltage divider)?
デフォルトからの変更要領:
 □Use Timer Driver?
 Driver Implemetation: STATIC



   Pin Settings

項目 ⑤ポート設定 
MHC
備考 デフォルトからの変更要領
RG15/Function: GPI_OUT
       (LED出力ポート設定)
RB4/Function: AN4
       (アナログ入力ポート設定))



■ キャラクタ液晶表示のライブラリ 1lcd_lib_XC32.h と 1lcd_lib_XC32.cを main.cと同じフォルダにコピーして、プロジェクトに追加します。
     (詳細→ キャラクタ液晶表示方法 参照




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

  ① 1lcd_lib_XC32.hのインクルード、system_interrupt.cで定義されているグローバル変数Timer_Trigger; などの宣言等します。
    #include "stdio.h"
    #include "1lcd_lib_XC32.h"
    bool LED = 0;

    ……
    ……

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

    ……
    ……

  ③ AdcFunc( ) で 入力のAD変換を行い、液晶に表示します。
   1. PLIB_ADCHS_GlobalSoftwareTriggerEnable(ADCHS_ID_0); でグローバルソフトウェアエッジトリガをかけAD変換を開始します。
   2. while(!PLIB_ADCHS_AnalogInputDataIsReady(ADCHS_ID_0,ADCHS_AN4));でAD変換の終了を待ちます。
   3. AdcValue = PLIB_ADCHS_AnalogInputResultGet(ADCHS_ID_0, ADCHS_AN4 );で 結果を取り出します。

    void AdcFunc(void) //AD変換、表示
    {
      unsigned int AdcValue;
      ……
      ……

   ④ この部分を使えばMHCのAD変換ドライバー部分の設定をしなくとも所要の結果が得られます。
    /*
    // Configure ADCCON1
    ADCCON1 = 0; // No ADCCON1 features are enabled including: Stop-in-Idle, turbo,
    ADCCON1bits.STRGSRC = 1; //スキャン開始を グローバルソフトウェアエッジトリガに設定 //ADCCON1bits.STRGSRC = 0; でも可

    ……
    ……
    */

    ⑤ この2つの関数を実行することでAD変換が有効になります。
     DRV_ADC0_Open();
     DRV_ADC_Start();


    ⑥ 起動時の液晶表示部分です。
     lcd_init(); // LCD初期化
     lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF
     lcd_cmd(0x80); //1目の先頭へ

     ……
     ……

    ⑦ インターバルタイマのタイマ1のインターバル時間設定と有効化です。
     PLIB_TMR_Period16BitSet(TMR_ID_1,3906); //5 nsec x2 x 3906 x 256 = 9.99936msec = 10msec //インターバル時間
     DRV_TMR0_Start()
;

    ⑧ AD変換のタイミングのフラグが立った場合の処理をAPP_Tasks ( )のcase APP_STATE_SERVICE_TASKS:に記述します。
    if(Timer_Trigger == 1) //AD変換、表示のタイミング
    {
      AdcFunc(); //AD変換、表示
      Timer_Trigger = 0;

      ……
      ……

以下、app.c




■ system_interrupt.c に 青字部を追加します。

   ①AD変換を開始するフラグと 10msec毎の割り込み検出回数の変数を定義します。
    bool Timer_Trigger = 0; //AD変換タイミングフラグ
    int Count_10msec = 0; //10msec経過カウンタ


   ② Count_10msec が25回になった時に、すなわち250msec毎に AD変換タイミングフラグTimer_Triggerを true("1")にします。
    Count_10msec++;
    if(Count_10msec >= 25) //250msec 経過
    {
      Count_10msec = 0;

    …… 
    ……


以下、system_interrupt.c