AD変換モジュールの使い方3(ADコンパレータ機能)

AD変換モジュールの使い方

概要

dsPIC33CHシリーズにはハードウェアでアナログ電圧をコンパレート(比較)するアナログコンパレータが搭載されていますが、デジタルで アナログ電圧をコンパレータするADコンパレータ機能がマスターコアに4ch、スレーブコアに4ch搭載されております。

ADコンパレータとは

AD変換結果と指定の値をハード的に比較し、結果を出力する機能です。

ADコンパレータは(fig.1)のような構成となっており、閾値以下や閾値以上、閾値の間など様々な条件で割り込みを発生させる事が可能です。

(fig.1)ADコンパレータの構成(DS70005213C_JP – p. 48より抜粋)

ハードウェア構成と制御ブロック

前回の記事とハードウェアはほぼ同じですが、デジタルコンパレータの結果をそのまま出力しています。

(fig.2)全体ブロック図

レジスタ

前回の記事で紹介したレジスタに加え、ADコンパレータを実現するADCモジュールのレジスタは以下の4種類です。

レジスタ名機能説明
ADCMPnCONADC Channel Trigger n
Selection Register Low
デジタル コンパレータの動作( 割り込みの生成、
比較基準等) を制御
ADCMPnENL
ADCMPnENH
ADC Level-Sensitive Trigger
Control Register
変換結果をデジタルコンパレータで処理する
アナログ入力を選択
(fig.3)ADコンパレータ関連レジスタ

ソースコード

コンパレータのステータスをそのままピンの状態として出力させています。

PIN_MASTER_LED1 = ADCMP0CONbits.STAT; 
コンフィグレーション設定について

コンフィグレーション設定についてはコンフィグレーション設定に記載しております。

コピーして下記のソースコードの「 //ここにコンフィグレーション設定を挿入する// 」の位置に挿入してください。

クロック設定について

クロック設定用関数 vds_Main_Init_Clock_Register(); のソースコードはクロック設定のページに記載しております。

コピーして下記のソースコードの「 //ここにクロック設定ソースをコピペする// 」の位置に挿入してください。

/*------------------------------------------------------------------------------*/
/* @file      ADCMP_POTANTION.c */
/* @brief     ポテンションの値をADコンパレータの結果によってLEDの点灯・消灯 */
/* @details   GPIO(TRIS,LAT) */
/*            AD(ADCON1H,ADCON2L,ADCON2H,ADCON3L,ADCON3H,ADCON5H) */
/*            AD(ANSELA,ADSTATL,ADCBUF) */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* コンフィグレーション設定*/
/*------------------------------------------------------------------------------*/
//ここにコンフィグレーション設定を挿入する//
/*------------------------------------------------------------------------------*/
/* インクルードファイル*/
/*------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
/*------------------------------------------------------------------------------*/
/* クロック設定 */
/*------------------------------------------------------------------------------*/
//ここにクロック設定ソースを挿入する//
/*------------------------------------------------------------------------------*/
/* Main関数 */
/*------------------------------------------------------------------------------*/
int main(int argc, char** argv) 
{
        static unsigned int u2l_Temp = 0;
    /*---------------------------------------------------------------------------*/
    /* クロック初期化*/
    /*---------------------------------------------------------------------------*/
        vds_Main_Init_Clock_Register();     /* クロック初期化 */
    /*---------------------------------------------------------------------------*/
    /* GPIO初期化*/
    /*---------------------------------------------------------------------------*/
        TRISEbits.TRISE0 = 0u;              /* LED1ピンはデジタル出力ピン */
        ANSELAbits.ANSELA0 = 1u;            /* RA0ピンはアナログピン*/
    /*---------------------------------------------------------------------------*/
    /* AD初期化*/
    /*---------------------------------------------------------------------------*/
        ADCON1L = 0x0000u;
        ADCON1H = 0x0000u;
        ADCON2L = 0x0000u;
        ADCON2H = 0x0000u;
        ADCON3L = 0x0000u;
        ADCON3H = 0x0000u;
        ADCON5H = 0x0000u;
        ADTRIG0L = 0x0000u;
        ADTRIG0H = 0x0000u;
        ADTRIG1L = 0x0000u;
        ADTRIG1H = 0x0000u;
        ADTRIG2L = 0x0000u;
        ADTRIG2H = 0x0000u;
        ADTRIG3L = 0x0000u;
        ADTRIG3H = 0x0000u;
        ADTRIG4L = 0x0000u;
        ADTRIG4H = 0x0000u;
        ADTRIG5L = 0x0000u;
        ADLVLTRGL = 0x0000u;
        ADLVLTRGH = 0x0000u;
        ADCMP0CON = 0x0000u;
        ADCMP0ENL = 0x0000u;
        ADCMP0ENH = 0x0000u;
        
        /***** AD制御レジスタの設定 ******/
        ADCON1Hbits.SHRRES = 3u;            /* シェアADC分解能 (3 = 12bit) */
        ADCON2Lbits.SHRADCS = 2u;           /* シェアADCクロックディバイダ */
        ADCON2Hbits.SHRSAMC = 4u;           /* シェアADCサンプル時間 (3 = 4TAD) */
        ADCON3Lbits.CNVCHSEL = 0u;          /* ソフトウェアAD入力(0 =AN0入力) */
        ADCON3Hbits.CLKSEL = 2u;            /* ADCクロックソース (2 = AFVCODIV) */
        ADCON3Hbits.CLKDIV = 2u;            /* ADCクロックディバイダ(2 = 3Clock)*/
        ADCON5Hbits.WARMTIME = 15u;         /* ウォームアップ時間(15 = 32768Clock) */

        /***** ADトリガ―の設定 ******/
        ADTRIG0Lbits.TRGSRC0 = TRG_MODE;    /* AN0入力のトリガ設定 */
        ADTRIG5Lbits.TRGSRC20 = TRG_MODE;   /* AN20入力のトリガ設定 */
        
        /***** ADの有効化 ******/
        ADCON1Lbits.ADON = 1u;              /* ADC全体のパワーON */
        ADCON5Lbits.SHRPWR = 1u;            /* シェアADCのパワーON */
        while(ADCON5Lbits.SHRRDY == 0u){;}
        ADCON3Hbits.SHREN = 1u;             /* シェアADCの有効化 */
        
        /***** ADComp ******/
        ADCMP0HI = 0x7FFu;
            ADCMP0ENLbits.CMPEN0 = 1u;      /* 入力チャンネル設定 */
            ADCMP0CONbits.HILO = 1u;        /* ADCBUFx ≥ ADCMPxHIの時に反応 */
            ADCMP0CONbits.CMPEN = 1u;       /* ADコンパレータの有効化 */
    /*--------------------------------------------------------------------------*/
    /* SCCPでトリガ*/
    /* タイマーモードではADのトリガが発生しない*/
    /*--------------------------------------------------------------------------*/   
        CCP2CON1L = 0x0000u;
        CCP2CON1Lbits.CLKSEL = 0;       /* クロック源選択(0 = FP) */
        CCP2CON1Lbits.TMRPS = 0u;       /* クロックプリスケーラ選択(0 = 1:1) */
        CCP2CON1Lbits.CCSEL = 0u;       /* キャプチャモード選択(0 = OC,Timerモード) */
        CCP2CON1Lbits.MOD = 5u;         /* 動作モード(5 = PWMモード(必須)) */
        CCP2CON1Lbits.T32 = 0u;         /* 32ビットモード(0 = 16bit / 1 = 32Bit) */
        
        CCP2CON1H = 0x0000u;

        CCP2PRL = 22500;                /* 周期 */
        CCP2RAL = 0;                    /* 立ち上がりタイミング */
        CCP2RBL = 8000;                 /* 立ち下がりタイミング */
    /*---------------------------------------------------------------------------*/
    /* CCP2の有効化*/
    /*---------------------------------------------------------------------------*/
        CCP2CON1Lbits.CCPON = 1u;
    /*---------------------------------------------------------------------------*/
    /* メインルーチン*/
    /*---------------------------------------------------------------------------*/
        while(1)
        {
            /*--------------------------------------------------------------------*/
            /* LED点灯判定*/
            /*--------------------------------------------------------------------*/ 
            if (ADSTATLbits.AN0RDY == 1)
            {
                 u2l_Temp = ADCBUF0;
                PIN_MASTER_LED1 = ADCMP0CONbits.STAT;
            }
        }
}

コメント

タイトルとURLをコピーしました