読者です 読者をやめる 読者になる 読者になる

denshikobo’s blog

PICプログラミングやPCの操作で感じた日々の由無し事を綴ります

Harmonyを手なずける

(2015.10.18)
PICを使ったオシロジの開発を続けています。

以前掲げた開発項目は機能確認の段階に達しました。
(1)時間軸の導入
(2)計測パラメータ変更
(3)PIC側の計測機能変更
(4)カーソル機能の導入
(5)拡大表示機能の導入

 

<4CHサンプリングを試して見た>

f:id:denshikobo:20151018160255p:plain

 

Harmonyを使ったアプリケーション開発では、ペリフェラル(例えばADC)の初期設定をHMC(ハーモニー・コンフィグレータ)で行います。グラフィカルな操作でパラメータを設定するだけで、必要なコードが自動生成にされるので大変便利です。しかし、その設定をカスタマイズしようとすると、色々問題がでてきます。

オシロジ・アプリではユーザの設定によりオシロのサンプリングCHを(1CHサンプリングから4CHサンプリングまで)自由に変更できるようにしようと考えています。そのためにはサンプリングCH(ScanChannel)の設定を書き換えなければなりませんが、HMCが生成するADCドライバには、一度設定したScanChannel設定を変更する機能が有りません。orz

AD1CSSLレジスタを書き換えてしまえば済むのですが、Harmonyフレーム・ワークを使ったアプリケーション開発では、制御レジスタを直接書き換えるのは禁じ手です。なんとか、ADCドライバ機能を拡張して対応しなければなりません。


ADCドライバの機能は”PLIB_ADC_*****"という関数で記述されていて、それらは”plib_adc.h”に定義されていていることが判りました。
C:\microchip\harmony\v1_06\framework\peripheral\adc\plib_adc.h

さらに、”plib_adc.h”を調べてみるとScanChannel設定を追加する関数”PLIB_ADC_InputScanMaskAdd”の隣にScanChannel設定を削除する関数”PLIB_ADC_InputScanMaskRemove”が見つかりました。
パチパチパチ~

で、こんな関数を定義してScanChannel設定を書き換えることにしました。

inline void DRV_ADC_Custom_Initialize( bool *sampling_ch, int sampling_ch_count )
{
一部省略
    switch( sampling_ch_count)
    {
        case 1:
                PLIB_ADC_SamplesPerInterruptSelect(DRV_ADC_ID_1, ADC_1SAMPLE_PER_INTERRUPT);
                break;
        case 2:
                PLIB_ADC_SamplesPerInterruptSelect(DRV_ADC_ID_1, ADC_2SAMPLES_PER_INTERRUPT);
                break;
        case 3:
                PLIB_ADC_SamplesPerInterruptSelect(DRV_ADC_ID_1, ADC_3SAMPLES_PER_INTERRUPT);
                break;
        default:
                PLIB_ADC_SamplesPerInterruptSelect(DRV_ADC_ID_1, ADC_4SAMPLES_PER_INTERRUPT);
                break;
    }

    PLIB_ADC_InputScanMaskRemove( DRV_ADC_ID_1, ADC_INPUT_SCAN_AN0 );
    PLIB_ADC_InputScanMaskRemove( DRV_ADC_ID_1, ADC_INPUT_SCAN_AN1 );
    PLIB_ADC_InputScanMaskRemove( DRV_ADC_ID_1, ADC_INPUT_SCAN_AN9 );
    PLIB_ADC_InputScanMaskRemove( DRV_ADC_ID_1, ADC_INPUT_SCAN_AN10 );
    
    if( sampling_ch[0] )
    {
      PLIB_ADC_InputScanMaskAdd(DRV_ADC_ID_1, ADC_INPUT_SCAN_AN0);
    }
    if( sampling_ch[1] )
    {
      PLIB_ADC_InputScanMaskAdd(DRV_ADC_ID_1, ADC_INPUT_SCAN_AN1);
    }
    if( sampling_ch[2] )
    {
      PLIB_ADC_InputScanMaskAdd(DRV_ADC_ID_1, ADC_INPUT_SCAN_AN9);
    }
    if( sampling_ch[3] )
    {
      PLIB_ADC_InputScanMaskAdd(DRV_ADC_ID_1, ADC_INPUT_SCAN_AN10);
    }
}
やれやれ