セクションの複数ページをまとめています。 印刷またはPDF形式で保存...

もとのページに戻る

2025-08-08 現在

mwf_periph_adc - ADC

mwf_periph_adc - ADC
    アナログディジタル変換(ADC)を利用するための手続きをまとめたペリフェラルオブジェクトです。

    mwf_periph_adc - ADC

    アナログディジタル変換(ADC)を利用するための手続きをまとめたペリフェラルオブジェクトです。

    コード例

    以下の例では mwf:: 名前空間を明示的に指定しています。省略する場合は using namespape mwf; を記述してください。

    • include
    #include "mwf_periph_adc.hpp"
    • 初期化手続き
    // the_adc クラスオブジェクトの生成
    mwf::the_adc->global_init_adc_manager();
    
    // ADCの入力ピンを指定
    mwf::pin::conf_adc_input(14);
    mwf::pin::conf_adc_input(15);
    
    // 初期化
    mwf::the_adc->init();
    • ADCの開始(ワンショット)
    // チャネルの指定
    mwf::the_adc->enable(
         (1ul << mwf::adc::CH_0)
       | (1ul << mwf::adc::CH_1)
       | (1ul << mwf::adc::CH_VCC));
    
    // ADC 開始
    mwf::the_adc->start(); // ワンショット
    while(!mwf::the_adc->available()) {} // ポーリングで終了待ちを行う
    
    // 値の取得
    int16_t v_ch0 = mwf::the_adc->get_value_mv(mwf::adc::CH_0);
    int16_t v_ch1 = mwf::the_adc->get_value_mv(mwf::adc::CH_1);
    int16_t v_vcc = mwf::the_adc->get_value_mv(mwf::adc::CH_VCC);
    • ADCの開始(連続)
    // チャネルの指定
    mwf::the_adc->enable(
         (1ul << mwf::adc::CH_0)
       | (1ul << mwf::adc::CH_1)
       | (1ul << mwf::adc::CH_VCC));
    
    // ADC 開始
    mwf::the_adc->start(true); // 連続
    
    // アプリケーションループ内で。
    void loop() {
        if (mwf::the_adc->available()) {
            // 値の取得(周期的に実行する)
            int16_t v_ch0 = mwf::the_adc->get_value_mv(mwf::adc::CH_0);
            int16_t v_ch1 = mwf::the_adc->get_value_mv(mwf::adc::CH_1);
            int16_t v_vcc = mwf::the_adc->get_value_mv(mwf::adc::CH_VCC);
    
            ...
        }
    }
    • 温度の測定
    int32_t i32temp;
    int16_t i16volt;
    
    // 内部センサーの電源ON、安定化待ち処理、ADCの計測処理 (1回のみ)までを実行。
    mwf::the_adc->temp_capture(i32temp, i16volt, 0);
    
    // i32temp は温度℃の128倍値。i16volt はミリボルト
    Serial << format("%dC %dmV", i32temp >> 7, i16volt);

    class mwf::periph::adc

    the_adc クラスオブジェクトの主要定義を記載します。

    定数定義

    static const uint8_t CH_MAX = 7;
    static const uint8_t CH_0 = 0; // ADC0
    static const uint8_t CH_1 = 1; // ADC1
    static const uint8_t CH_2 = 2; // ADC2
    static const uint8_t CH_3 = 3; // ADC3
    static const uint8_t CH_4 = 4; // ADC4
    static const uint8_t CH_5 = 5; // ADC5
    static const uint8_t CH_VCC = 6; // VCC
    static const uint8_t CH_TEMP = 7; // 内部温度センサー (通常のADとは取得方法が違います)
    

    ADCチャネルについての設定定義です。

    struct config

    struct config {
      uint8_t prescale;
    };

    設定を行うための構造体。init()のパラメータとして渡す。

    • prescale : **《現バージョンでは DEFAULT_PRESCALE=6 のみに対応》**ADCの変換時間を決めるためのプリスケール値。fslライブラリで定義されるadc_config_t::clockDividerNumber(1ul << .prescale) を設定し::ADC_Init()を呼び出します。

    global_init_adc_manager() global_deinit_adc_manager()

    static void global_init_adc_manager();
    static void global_deinit_adc_manager();

    クラスオブジェクトthe_adc の生成と破棄を行う。

    set_pin_as_adc()

    static void set_pin_as_adc(uint8_t pin)

    指定したピン番号pinをADC入力にする。

    init() deinit()

    void init(bool b_wait_init = true);
    void deinit();

    ADCを初期化します。

    b_wait_initをFALSEに設定すると、ADCの安定化の待ち時間 (300ms) を省略します。待ち時間の扱いについてはis_periph_enabled()を参照してください。

    内部温度センサー取得用に ADC を初期化または再初期化するには init_for_temp_volt()を呼び出します。すでに init() により初期化済みの場合は temp_capture()

    is_periph_enabled()

    bool is_periph_enabled()
    void force_periph_enabled()
    uint32_t get_init_freerun_tick()

    ADCが初期化され必要な待ち時間を経過すると true を戻します。

    • the_wtimerで提供するFRWT(Free Running Wake Timer)が動作している場合は、is_periph_enabled()が適切な時期までfalseを戻します。init()が呼び出されたときのカウント値を得るには get_init_freerun_tick()を呼び出します。
    • FRWTが動作していない場合は初回のis_periph_enabled()の呼び出し時におよそ300usecの待ち時間が発生します。この待ち処理を行わないようにするためには init()呼び出し直後にforce_periph_enabled()を呼び出しておきます。この処理は内部状態を強制的に待ち時間が経過したものとして取り扱います。

    enable()

    void enable(uint32_t chmask);

    ADCを動作可能な状態にします。chmaskは変換対象のチャネルのビットマスクで、ADC0 と ADC1 と VCC が対象の場合は (1ul << CH_0) | (1ul << CH_1) | (1ul << CH_VCC) と指定します。

    start() stop()

    void start(bool b_cont = false);
    void stop();

    enable() 実行後に start() を実行することで、ADCを開始します。b_cont == trueとした場合は、連続変換を行います。すでにstart()が呼び出されADCが実行中のときには、呼び出してはいけません。

    連続変換時に変換を停止するには stop() を呼び出します。

    変換が終了した時点で the_adc->available() の読み出しが true になります。

    available()

    bool available();

    変換終了後に true を戻します。trueを読み出した後は再びfalseを戻します。

    is_started()

    bool is_started();

    start()によりADCが実行中である場合trueを戻します。

    get_value()

    uint16_t get_value(uint8_t ch);

    chで指定するチャネルのAD変換値(12bit)を取得する。AD変換終了後に呼び出す。

    get_value_mv()

    int16_t get_value_mv(uint8_t ch);

    chで指定するチャネルのAD変換値をmvで取得する。AD変換終了後に呼び出す。

    global_init_device() global_deinit_device()

    static void global_init_device();
    static void global_deinit_device();

    ハードウェアの初期化と利用終了の手続きを行う。

    ※ コンストラクタ、デストラクタなどから内部的に呼び出され、ユーザアプリケーションから明示的に呼び出す必要はありません。

    register_callback()

    typedef void (*PFN_ADC_CALLBACK)(uint32_t, uint32_t);
    void register_callback(PFN_ADC_CALLBACK pfn)

    割り込みハンドラ内からのコールバック関数の指定。

    コールバック関数の第一パラメータは kADC_ConvSeqAInterruptFlag, 第二パラメータは変換が行われたチャネルのビットマスクが渡されます。

    温度センサー

    temp_capture()

    bool temp_capture(
        int32_t& temp128th,
        int16_t& volt_mv,
        uint8_t times_adc_scaler = 0,
        bool b_power_on_temp_sensor = true)

    オンチップ温度センサーの値を取得する。副次的に電源電圧も計測する。

    • temp128thには、温度の計測結果を格納する変数を指定する。値は摂氏の128倍値になる。整数部は temp128th >> 7、小数点1桁部分は (10 * temp128th) >> 7 で計算できる。
    • volt_mvには、電圧の計測結果を格納する変数を指定する。値はミリボルト[mV]。
    • times_adc_scalerには、ADCの繰り返し回数に対応するスケーラ値を指定する。0..3まで指定でき、0の場合は1回、1は2回、2は4回、3は8回のAD変換を行ったのち、値を平均化処理する。
    • 戻り値は成功時にtrue,失敗時にfalseを戻す。

    暗黙に以下の処理を行います。

    • 温度センサーがONになっていない場合は、センサーをONに設定し必要な待ち処理を行います。(temp_power_on()参照)
    • 実行後は温度センサーをOFFにします。
    • ADCの初期化(init())が行われていない場合は失敗します。
    • ADCの初期化後、デバイスが利用可能になっていない場合は、待ち処理を行います (is_periph_enabled()参照)。

    temp_get_capt_tick()

    uint32_t temp_get_capt_tick()

    最後に温度を取得したときの FRWT のカウンタ値を返す。

    temp_power_on(), temp_power_off()

    void temp_power_on()
    void temp_power_off()

    明示的に温度センサーのON/OFFを行う。

    FRWT が有効な場合に限り、カウント値をもとに待ち時間が完了しているかを判定するため、事前にON処理を行っておくことで待ち時間を短縮できる。

    temp_computation()

    int32_t temp_computation(
    	uint16_t adcout_vbat_lsb_sum8,
    	uint16_t tsens_adcout_T_sum8,
    	uint8_t nb_samples_actual = 1)

    内部的に利用します。ADC計測値から温度を計算します。

    get_ctrl0_adc_reg_context()

    class ctrl0_adc_reg;
    ctrl0_adc_reg get_ctrl0_adc_reg_context(uint8_t mode, uint8_t tsamp)
    
    //例
       	if (auto rc = get_ctrl0_adc_reg_context(
    			  0x0
    			, 0x14
    	)) {
            ; // このスコープ内は (0x0, 0x14) の設定が有効。スコープを出ると元の値に戻す。
        }

    内部的に利用します。一時的に ADCの設定パラメータを変更します。

    class mwf::periph::adc (sys_ev_handler)

    on_sleep()

    ADCの停止処理を行います。

    on_wakeup()

    スリープ前に ADC が初期化されていた場合は、初期化手続き(init())を行います。enable(), start()は改めて実行する必要があります。

    その他

    連続モードでの動作について

    変換周期はハードウェアによって決まっています。現バージョンではプリスケーラの値は固定です。

    AHI, mwx での利用

    AHI や mwx ライブラリの内部では mwf::the_adc を利用していますので、直接 mwf::the_adc を利用する場合は注意が必要です。

    • AHIライブラリを利用しかつ mwf::the_adc を利用する場合は、ADCに関連する一切の手続きを呼び出さないようにしてください (vAHI_ApConfigure(), vAHI_AdcEnable(), vAHI_AdcStartSample()など。App_Tweline 付属の adc.c)
    • mwx ライブラリを利用しかつ mwf::the_adc を利用する場合は、Analogue クラスオブジェクトに対して操作を行わないようにしてください(Analogue.setup() など)。