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

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

概要

dsPIC33CHシリーズにはAD(Analog to Digital)コンバータがマスターコアに1ch、スレーブコアに3ch搭載されており、スレーブの2chは専用入力構成となっております。本章ではマスターコア側のADコンバータを使用してポテンションの値をソフトウェアで平均化しLEDの点灯、消灯LEDを点灯させるサンプルについて説明しています。

ADコンバータとは

外部のアナログ信号をマイコンのソフトで扱えるようにデジタル信号に変換する機能です。

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

ハードウェアの構成として(fig.1)の青丸位置に実装されているポテンションのアナログ電圧をAN0チャンネルを介し、デジタル信号に変換します。
今回はソフトウェアでサンプリングとコンバートの指令を行い、8回の移動平均の結果値が1.65V以上の場合LEDを点灯させる仕様とします。

(fig.1)ポテンション
(fig.2)全体ブロック図

ソースコード

まずはメインループ外で各種初期設定を行います。
メインループ内では以下の4つのフェーズを繰り返し行います。

①サンプリングフェーズ

  • ADCON3Lbits.CNVRTCHがクリアされるまで待ちます。
  • ADCON3Lbits.SHRSAMPをセットし手動でサンプリングを開始します。
  • 任意のサンプリング時間を待ってから、ADCON3Lbits.SHRSAMPをクリアします。
u2_SamplingTime = 30u;
while (ADCON3Lbits.CNVRTCH == 1u){;}
ADCON3Lbits.SHRSAMP = 1u;
 while(u2_SamplingTime > 0){u2_SamplingTime --;}
ADCON3Lbits.SHRSAMP = 0u;

②AD変換フェーズ

  • ADCON3Lbits.CNVRTCH をセットしサンプリングを行います。
  • 数クロック待機します
ADCON3Lbits.CNVRTCH = 1u;
u2_SamplingTime = 10;
while(u2_SamplingTime > 0){u2_SamplingTime --;}

③移動平均フェーズ

  • AD変換完了フラグが立っていたら、ADCBUF0からデータを取り出し8回の移動平均を取ります
if ((ADSTATL & 0x0001u) == 0x0001u)
{
   Pot.u2_Sum -= Pot.u2_Buffer[Pot.u2_Head];
   Pot.u2_Buffer[Pot.u2_Head] = ADCBUF0;
   Pot.u2_Sum += Pot.u2_Buffer[Pot.u2_Head];
   Pot.u2_Head ++;
   Pot.u2_Head &= 0x07;
   Pot.u2_Ave = Pot.u2_Sum >> 3u;
}

④LED点灯判定フェーズ

  • 移動平均の結果、ポテンションの値が1.65Vを超える場合、LED1を点灯。以下の場合LED1を点灯させます
if (Pot.u2_Ave > 2048u ){ PIN_MASTER_LED1 = 1u;}
 else { PIN_MASTER_LED1 = 0u;}
コンフィグレーション設定について

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

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

クロック設定について

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

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

/*--------------------------------------------------------------------------------*/
/* @file      AD_POTANTION.c */
/* @brief     ポテンションの値をソフトで平均化、結果によって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>
/*--------------------------------------------------------------------------------*/
/*【CONST】定数定義*/
/*--------------------------------------------------------------------------------*/
#define ADSIZE       8u
/*--------------------------------------------------------------------------------*/
/*【VARI】変数定義*/
/*--------------------------------------------------------------------------------*/
struct
{
    unsigned int u2_Sum;
    unsigned int u2_Head;
    unsigned int u2_Ave;
    unsigned int u2_Buffer[ADSIZE];
}Pot;

unsigned int u2_SamplingTime;
/*--------------------------------------------------------------------------------*/
/* クロック設定 */
/*--------------------------------------------------------------------------------*/
//ここにクロック設定ソースを挿入する//
/*--------------------------------------------------------------------------------*/
/* Main関数 */
/*--------------------------------------------------------------------------------*/
int main(int argc, char** argv) 
{
    /*---------------------------------------------------------------------------*/
    /* クロック初期化*/
    /*---------------------------------------------------------------------------*/
        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;
        
        /***** 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の有効化 ******/
        ADCON1Lbits.ADON = 1u;              /* ADC全体のパワーON */
        ADCON5Lbits.SHRPWR = 1u;            /* シェアADCのパワーON */
        while(ADCON5Lbits.SHRRDY == 0u){;}
        ADCON3Hbits.SHREN = 1u;             /* シェアADCの有効化 */

        ADCON3Lbits.CNVCHSEL = 0u;
    /*-------------------------------------------------------------------------*/
    /* メインルーチン*/
    /*-------------------------------------------------------------------------*/
        while(1)
        {
            /*-----------------------------------------------------------------*/
            /* ①サンプリング*/
            /*-----------------------------------------------------------------*/
                u2_SamplingTime = 30u;
                while (ADCON3Lbits.CNVRTCH == 1u){;}
                ADCON3Lbits.SHRSAMP = 1u;
                while(u2_SamplingTime > 0){u2_SamplingTime --;}
                ADCON3Lbits.SHRSAMP = 0u;
            /*-----------------------------------------------------------------*/
            /* ②AD変換*/
            /*-----------------------------------------------------------------*/
                ADCON3Lbits.CNVRTCH = 1u;
                u2_SamplingTime = 10;
                while(u2_SamplingTime > 0){u2_SamplingTime --;}
            /*-----------------------------------------------------------------*/
            /* ③移動平均*/
            /*-----------------------------------------------------------------*/
                if ((ADSTATL & 0x0001u) == 0x0001u)
                {
                    Pot.u2_Sum -= Pot.u2_Buffer[Pot.u2_Head];
                    Pot.u2_Buffer[Pot.u2_Head] = ADCBUF0;
                    Pot.u2_Sum += Pot.u2_Buffer[Pot.u2_Head];
                    Pot.u2_Head ++;
                    Pot.u2_Head &= 0x07;
                    Pot.u2_Ave = Pot.u2_Sum >> 3u;
                }
            /*-----------------------------------------------------------------*/
            /* ④LED点灯判定*/
            /*-----------------------------------------------------------------*/ 
                if (Pot.u2_Ave > 2048u ){ PIN_MASTER_LED1 = 1u;}
                else { PIN_MASTER_LED1 = 0u;}
        }
}

コメント

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