概要
dsPIC33CHシリーズにはハードウェアでアナログ電圧を比較するアナログコンパレータがマスターコアに1ch、スレーブコアに3ch搭載されております。
コンパレータとは入力された二つの信号を比較し、どちらが大きいかによって出力信号が切り替わる電子回路のこと。本マイコンに搭載されているコンパレータの反応速度は15nsecと非常に速い。
前回、前々回の記事はポテンションの値をAD変換して比較していましたが、今回はその比較結果をGPIOに反映するだけのサンプルについて説明します。
dsPIC33C系は電源の制御を行うための「スロープ補償回路」という機能が搭載されている事が特徴で、次回の記事で紹介します。

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

またアナログのコンパレータですので、境目ではチャタリングが発生します。このアナログコンパレータにはフィルタ機能が搭載されていますので、その効果についても確認しています。
レジスタ
アナログコンパレータを制御するレジスタは以下の10種類です。
| レジスタ名 (x = 1~3) | 機能 | 説明 |
| DACCTRL1L | DAC Control 1 Low Register | は DAC モジュールの有効化、クロック源の選択、クロック分周比の選択、アイドル中の動作を選択 |
| DACCTRL2L | DAC Control 2 Low Register | DAC の定常および遷移モードの期間を指定 |
| DACCTRL2H | DAC Control 2 High Register | DAC の定常および遷移モードの期間を指定 |
| DACxCONL | DACx Control Low Register | 個別 DACx モジュール、制御割り込み、DACx 出力接続、コン パレータ入出力を選択 |
| DACxCONH | DACx Control High Register | リーディング エッジ ブランキング (LEB) 信号の期間を指定 |
| DACxDATL | DACx Data Low Register | DACx データ値を指定 |
| DACxDATH | DACx Data High Register | DACx データ値を指定 |
| SLPxCONL | DAC Slope x Control Low Register | DACxモード制御信号 ( 開始、停止等 ) を選択 |
| SLPxCONH | DAC Slope x Control High Register | スロープ機能とモード設定の有効化を設定 |
| SLPxDAT | DAC Slope x Data Register | は DACx スロープのランプレートを指定 |
スイッチング電源の制御で「インダクタ電流をコンパレータ入力に接続し、閾値を超えた時にPWMを任意の値に遷移する」といったアプリケーションが有ったとした場合、PWM信号変化直後にスイッチングノイズがコンパレータ入力に入り、誤動作する可能性が有ります。
リーディングエッジブランキングはこのコンパレータの反応を一時的に無効にしノイズの誤動作を防止する機能です。
ソースコード
以下のマクロの値を変更して フィルタの効果を確かめました。機能の意味とその範囲は以下の通り
| マクロ名 | 機能 | 範囲 |
| FILTER_EN | フィルタの有効/無効を切り替える | 0 = フィルタ無効 1 = フィルタ有効 |
| FILTER_CLK | フィルタのクロックを選択する | 0 = クロック1倍 1 = クロック2分周 . . 7 = クロック8分周 |
| FILTER_HYS | コンパレータのヒステリシスを設定する | 0 = ヒステリシス無効 1 = ヒステリシス 15mV 2 = ヒステリシス 30mV 3 = ヒステリシス 45mV |
ヒステリシスとはコンパレータや演算などで、出力の切り替わりの際に出るノイズを除去するために使われます。
コンフィグレーション設定についてはコンフィグレーション設定に記載しております。
コピーして下記のソースコードの「 //ここにコンフィグレーション設定を挿入する// 」の位置に挿入してください。
クロック設定用関数 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)の状態を示します。今回の例ではデジタルフィルタが有効になった時に思ったような動作をしてくれなかったのですが、想定の使い方(電源やモータ制御)に対してポテンションの変化速度が遅かったのが原因かもしれません。






コメント