忍者ブログ

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

2025/05/22

dsPIC33CH Curiosity Development Board(ADフィルタ―の使い方):

以前のAD変換は手動でサンプリングとAD変換の指令を行い、ソフトウェアにて平均化を行っていました。dsPIC33CHシリーズにはマスターコアに4ch、スレーブコアに4chのADフィルターモジュールが搭載されており、ソフトウェアで平均化処理をしなくても良くなっています。このフィルタはオーバーサンプリングモード(ADFLxCONbits.MODE = 0)か平均化モード(ADFLxCONbits.MODE = 1)が選択可能で、平均化モードでは12bitの結果、オーバーサンプリングモードでは最大16bitの結果が得られます。サンプリングの回数は ADFLxCONbits.OVRSAMで指定し、回数が多くなるほど結果が出力されるまでの時間も増加します。

 AD専用コアによる4倍オーバーサンプリング(DS70005213C_JP - p.50より抜粋)

ハードウェア構成

今回はADの変換トリガをSCCPで定期的に行う、もしくはレベルソフトトリガにて発生させます。その切り替えは#define TRG_MODEの値をTRG_MODE_LVLSOFTかTRG_MODE_SCCP2に切り替えてコンパイルします。 

    
 
  
  ソースコード

コンフィグレーション設定やクロック設定の関数に関して記述を省略していますが「dsPIC33CH Curiosity Development Board(準備編)」と同じです。

/*----------------------------------------------------------------------------------*/
/*【INC】インクルードファイル*/
/*----------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
/*----------------------------------------------------------------------------------*/
/*【CONST】定数定義*/
/*----------------------------------------------------------------------------------*/
#define ADSIZE       8u

#define TRG_MODE_CMNSOFT 0x01
#define TRG_MODE_LVLSOFT 0x02
#define TRG_MODE_SCCP2   0x15

#define TRG_MODE        TRG_MODE_SCCP2
/*----------------------------------------------------------------------------------*/
/*【VARI】変数定義*/
/*----------------------------------------------------------------------------------*/
struct
{
    unsigned int u2_FilAve;
    unsigned int u2_Ave;
    
}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;
        ADTRIG0L = 0x0000u;
        ADTRIG5L = 0x0000u;
        
        /***** AD制御レジスタの設定 ******/
        ADCON1Hbits.SHRRES = 3u;            /* シェアADC分解能 (3 = 12bit) */
        ADCON2Lbits.SHRADCS = 2u;           /* シェアADCクロックディバイダ (2 = 4Clock) */
        ADCON2Hbits.SHRSAMC = 4u;           /* シェアADCサンプル時間 (3 = 4TAD) */
        ADCON3Lbits.CNVCHSEL = 0u;          /* ソフトウェアAD入力(0 =AN0入力) */
        ADCON3Hbits.CLKSEL = 2u;            /* ADCクロックソース (2 = AFVCODIV = 500MHz) */
        ADCON3Hbits.CLKDIV = 2u;            /* ADCクロックディバイダ(2 = 3Clock)*/
        ADCON5Hbits.WARMTIME = 15u;         /* ウォームアップ時間(15 = 32768Clock) */

        /***** ADトリガ―の設定 ******/
        ADTRIG0Lbits.TRGSRC0 = TRG_MODE;
        ADTRIG5Lbits.TRGSRC20 = TRG_MODE;
        ADLVLTRGLbits.LVLEN0 = 0u;
        ADLVLTRGHbits.LVLEN20 = 0u;
        
        /***** ADFilter ******/
        ADFL0CONbits.FLCHSEL = 0u;          /* 入力チャンネル設定*/
        ADFL0CONbits.MODE = 0u;             /* フィルタモード */
        ADFL0CONbits.OVRSAM = 2u;           /* オーバーサンプリング比 */
        ADFL0CONbits.FLEN = 1u;             /* フィルタの有効化 */
        
        /***** ADの有効化 ******/
        ADCON1Lbits.ADON = 1u;              /* ADC全体のパワーON */
        ADCON5Lbits.SHRPWR = 1u;            /* シェアADCのパワーON */
        while(ADCON5Lbits.SHRRDY == 0u){;}
        ADCON3Hbits.SHREN = 1u;             /* シェアADCの有効化 */
        
    /*----------------------------------------------------------------------------------*/
    /* SCCPでトリガ*/
    /* タイマーモードではADのトリガが発生しない*/
    /*----------------------------------------------------------------------------------*/   
#if (TRG_MODE == TRG_MODE_SCCP2)
           
        CCP2CON1L = 0x0000u;
            CCP2CON1Lbits.CLKSEL = 0;       /* クロック源選択(0 = FP) */
            CCP2CON1Lbits.TMRPS = 1u;       /* クロックプリスケーラ選択(1 = 1:4) */
            CCP2CON1Lbits.CCSEL = 0u;       /* キャプチャモード選択(0 = OC,Timerモード) */
            CCP2CON1Lbits.MOD = 5u;         /* 動作モード(5 = PWMモード(必須)) */
            CCP2CON1Lbits.T32 = 0u;         /* 32ビットモード(0 = 16bit / 1 = 32Bit) */
        
        CCP2CON1H = 0x0000u;
            CCP2CON1Hbits.TRIGEN = 0u;
            CCP2CON1Hbits.ALTSYNC = 0u;
            CCP2CON1Hbits.SYNC = 0u;
            CCP2CON2H = 0x0000u;
            CCP2CON2Hbits.AUXOUT = 0u;      /* イベント時補助出力信号選択ビット*/
        CCP2PRL = 22500;                /* 周期 */
        CCP2RAL = 0;                    /* 立ち上がりタイミング */
        CCP2RBL = 8000;                 /* 立ち下がりタイミング */
    /*----------------------------------------------------------------------------------*/
    /* CCP2の有効化*/
    /*----------------------------------------------------------------------------------*/
        CCP2CON1Lbits.CCPON = 1u;
#endif

#if (TRG_MODE == TRG_MODE_LVLSOFT)
        ADCON3Lbits.SWLCTRG = 0;
        ADCON3Lbits.SWLCTRG = 1;
#endif
    /*----------------------------------------------------------------------------------*/
    /* メインルーチン*/
    /*----------------------------------------------------------------------------------*/
        while(1)
        {
            if(ADFL0CONbits.RDY == 1)
            {
                Pot.u2_FilAve = ADFL0DAT;
                /*----------------------------------------------------------------*/
                /* LED点灯判定*/
                /*----------------------------------------------------------------*/  
                    if (Pot.u2_Ave > 2048u ){ PIN_MASTER_LED1 = 1u;}
                    else { PIN_MASTER_LED1 = 0u;}
                #if (TRG_MODE == TRG_MODE_LVLSOFT)
                    ADCON3Lbits.SWLCTRG = 0;
                    ADCON3Lbits.SWLCTRG = 1;
                #endif
            }
        }
}

結果

実行すると中間電圧付近でLEDが点灯/消灯すると思います。
 
PR

2020/08/15 dsPIC33C Comment(0)

COMMENT

COMMENT FORM

NAME
MAIL
WEB
TITLE
COMMENT
PASSWORD

プロフィール
 
HN:
ぴくお
性別:
非公開
 
 
カテゴリー
 
 
 
最新記事
 
(10/03)
(09/05)
(08/23)
(08/17)
(08/16)
 
 
RSS
 
 
 
リンク
 
 
 
免責事項
当サイトに掲載の回路図やプログラム等は動作する事を期待して掲載しておりますが、その動作の保証、性能の保証は致しません。 また掲載されているソフトウェアの使用により生じたいかなる損害に関しまして作者は一切責任を負いません。