アナログコンパレータモジュールの使い方

アナログコンパレータモジュールの使い方

概要

dsPIC33CHシリーズにはハードウェアでアナログ電圧を比較するアナログコンパレータがマスターコアに1ch、スレーブコアに3ch搭載されております。

コンパレータとは

コンパレータとは入力された二つの信号を比較し、どちらが大きいかによって出力信号が切り替わる電子回路のこと。本マイコンに搭載されているコンパレータの反応速度は15nsecと非常に速い。

前回前々回の記事はポテンションの値をAD変換して比較していましたが、今回はその比較結果をGPIOに反映するだけのサンプルについて説明します。

dsPIC33C系は電源の制御を行うための「スロープ補償回路」という機能が搭載されている事が特徴で、次回の記事で紹介します。

(fig.1)アナログコンパレータブロック DS70005280A_JP-p.3より抜粋

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

ポテンションのアナログ電圧をアナログコンパレータでDAC1Hの値と比較し、大小によってLEDを点灯させます。またアナログコンパレータの結果をダイレクトにピンに出力することも可能で、リマッパブルピン(RP50)に割り当てます。

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

またアナログのコンパレータですので、境目ではチャタリングが発生します。このアナログコンパレータにはフィルタ機能が搭載されていますので、その効果についても確認しています。

レジスタ

アナログコンパレータを制御するレジスタは以下の10種類です。

レジスタ名
(x = 1~3)
機能説明
DACCTRL1LDAC Control 1
Low Register
は DAC モジュールの有効化、クロック源の選択、クロック分周比の選択、アイドル中の動作を選択
DACCTRL2LDAC Control 2
Low Register
DAC の定常および遷移モードの期間を指定
DACCTRL2HDAC Control 2
High Register
DAC の定常および遷移モードの期間を指定
DACxCONLDACx Control
Low Register
個別 DACx モジュール、制御割り込み、DACx 出力接続、コン
パレータ入出力を選択
DACxCONHDACx Control
High Register
リーディング エッジ ブランキング (LEB) 信号の期間を指定
DACxDATLDACx Data
Low Register
DACx データ値を指定
DACxDATHDACx Data
High Register
DACx データ値を指定
SLPxCONLDAC Slope x
Control Low Register
DACxモード制御信号 ( 開始、停止等 ) を選択
SLPxCONHDAC Slope x
Control High Register
スロープ機能とモード設定の有効化を設定
SLPxDATDAC Slope x
Data Register
は DACx スロープのランプレートを指定
(fig.3)コンパレータ関連レジスタ
リーディングエッジブランキングとは

スイッチング電源の制御で「インダクタ電流をコンパレータ入力に接続し、閾値を超えた時にPWMを任意の値に遷移する」といったアプリケーションが有ったとした場合、PWM信号変化直後にスイッチングノイズがコンパレータ入力に入り、誤動作する可能性が有ります。

リーディングエッジブランキングはこのコンパレータの反応を一時的に無効にしノイズの誤動作を防止する機能です。

ソースコード

以下のマクロの値を変更して フィルタの効果を確かめました。機能の意味とその範囲は以下の通り

マクロ名機能範囲
FILTER_EN フィルタの有効/無効を切り替える0 = フィルタ無効
1 = フィルタ有効
FILTER_CLK フィルタのクロックを選択する0 = クロック1倍
1 = クロック2分周
.
.
7 = クロック8分周
FILTER_HYS コンパレータのヒステリシスを設定する0 = ヒステリシス無効
1 = ヒステリシス 15mV
2 = ヒステリシス 30mV
3 = ヒステリシス 45mV
(fig.4)フィルタ効果を確かめるマクロ
ヒステリシスとは

ヒステリシスとはコンパレータや演算などで、出力の切り替わりの際に出るノイズを除去するために使われます。

コンフィグレーション設定について

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

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

クロック設定について

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

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

/*------------------------------------------------------------------------------*/
/* @file      CMP_POTANTION.c */
/* @brief     ポテンションの値をコンパレータの結果によってLEDの点灯・消灯 */
/* @details   GPIO(TRIS,LAT) */
/*            DAC(DACCTRL1L,DACCTRL2H,DACCTRL2L,DAC1CONL,DAC1DATH) */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* コンフィグレーション設定*/
/*------------------------------------------------------------------------------*/
//ここにコンフィグレーション設定を挿入する//
/*------------------------------------------------------------------------------*/
/* インクルードファイル*/
/*------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
/*------------------------------------------------------------------------------*/
/* 定数定義*/
/*------------------------------------------------------------------------------*/
#define FILTER_EN   0
#define FILTER_CLK  2
#define FILTER_HYS  3
/*------------------------------------------------------------------------------*/
/* クロック設定 */
/*------------------------------------------------------------------------------*/
//ここにクロック設定ソースを挿入する//
/*------------------------------------------------------------------------------*/
/* Main関数 */
/*------------------------------------------------------------------------------*/
int main(int argc, char** argv) 
{
     /*------------------------------------------------------------------------*/
    /* クロック初期化*/
    /*-------------------------------------------------------------------------*/
        vds_Main_Init_Clock_Register();     /* クロック初期化 */
    /*-------------------------------------------------------------------------*/
    /* GPIO初期化*/
    /*-------------------------------------------------------------------------*/
        TRISEbits.TRISE0 = 0u;              /* LED1ピンはデジタル出力ピン */
        ANSELAbits.ANSELA0 = 1u;            /* RA0ピンはアナログピン*/
    /*-------------------------------------------------------------------------*/
    /* リマッパブルピン初期化*/
    /*-------------------------------------------------------------------------*/
        RPOR9bits.RP50R	= 0x17u;            /* ダミー出力 [CMP1] */
    /*-------------------------------------------------------------------------*/
    /* CMP初期化*/
    /*-------------------------------------------------------------------------*/
        DACCTRL1L = 0x0000u;
        DACCTRL1Lbits.CLKSEL = 0u;      /* DACクロック源( 0 = AFVCO/2 = 500MHz) */
        DACCTRL1Lbits.CLKDIV = 0u;      /* DACクロックディバイダ (0 = 1/1) */
        DACCTRL1Lbits.FCLKDIV = CHAP243_FILTER_CLK; /**/
        DACCTRL1Lbits.DACON = 1u;       /* モジュール有効化(0 = 無効,1 = 有効) */
        DACCTRL2H = 0x001Au;            /* 移行開始からの時間 */
        DACCTRL2L = 0x0055u;            /* 遷移モードの継続時間 */
        DAC1CONH = 0x0000u;
       
        DAC1CONL = 0x0000u;
        DAC1CONLbits.INSEL = 0u;      /*コンパレータ入力ソース*/
        DAC1CONLbits.HYSSEL = CHAP243_FILTER_HYS;/*コンパレータHys(1 = 15mV) */
        DAC1CONLbits.DACOEN = 0u;     /* DAC外部出力 (0 = 無効,1 = 有効) */
            
        DAC1CONLbits.FLTREN = CHAP243_FILTER_EN;  /* コンパレータフィルタ*/
        DAC1DATH = 0x07FFu;                 /* コンパレータ比較値 */
        DAC1DATL = 0x0000u;
  
    /*-------------------------------------------------------------------------*/
    /* DAC1の有効化*/
    /*-------------------------------------------------------------------------*/
        DAC1CONLbits.DACEN = 1u;         /* DAC1の有効化 */
    /*-------------------------------------------------------------------------*/
    /* メインルーチン*/
    /*-------------------------------------------------------------------------*/
        while(1)
        {
            /*-----------------------------------------------------------------*/
            /* LED点灯*/
            /*-----------------------------------------------------------------*/ 
                LATEbits.LATE0 = DAC1CONLbits.CMPSTAT;
        }
}

結果

以下に各マクロの設定を変更した時の29番端子(ch1)、2番端子(ch2)の状態を示します。今回の例ではデジタルフィルタが有効になった時に思ったような動作をしてくれなかったのですが、想定の使い方(電源やモータ制御)に対してポテンションの変化速度が遅かったのが原因かもしれません。

(fig.5) FILTER_EN = 0 , FILTER_CLK = 7 , FILTER_HYS = 1の時の動作結果
(fig.6)FILTER_EN = 1 , FILTER_CLK = 7 , FILTER_HYS = 1の時の動作結果
(fig.7)FILTER_EN = 1 , FILTER_CLK = 2 , FILTER_HYS = 1の時の動作結果
(fig.8)FILTER_EN = 0 , FILTER_CLK = 2 , FILTER_HYS = 7の時の動作結果

コメント

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