ADCの初期化方法

説明

nRF54L15を用いてZephyr APIとnrfxドライバーを用いてADCで電圧を取得する方法について説明します。以下の点に注意してください。

  • IOはチップ指定のAINピンを使用する必要があります。
  • 最大解像度は14ビット(サンプリングレート:31.25 kSPS)です。
  • nRF54L15のADC内部リファレンス電圧(ADC_REF_INTERNAL)は0.9 Vです。
  • 電圧を取得する場合、分圧抵抗値が異なるため、ADC_ACQ_TIME_DEFAULTを調整する必要があります。

1. Zephyr API方式

1.1 prj.conf設定

prj.confファイルに以下を設定します。


1.2 overlay設定(例:nrf54l15dk_nrf54l15_cpuapp.overlay)

overlayファイルに以下を設定します。


&adc {
    #address-cells = <1>;
    #size-cells = <0>;
    status = "okay";
    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1_4";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
        zephyr,input-positive = <NRF_SAADC_AIN4>; /* nRF54L15 DKのP1.11ピン */
        zephyr,resolution = <14>;
    };
};

1.3 代码例

以下はZephyr APIを使用したADCのサンプルコードです。


#include <drivers/adc.h>

static const struct adc_dt_spec adc_spec = ADC_DT_SPEC_GET(DT_PATH(zephyr_user));

void main(void)
{
    int err;
    int16_t data_buffer;
    struct adc_sequence seq = {
        .buffer = &data_buffer,
        .buffer_size = sizeof(data_buffer),
    };

    if (!adc_is_ready_dt(&adc_spec)) {
        printk("ADCが準備されていません\n");
        return;
    }

    err = adc_channel_setup_dt(&adc_spec);
    if (err < 0) {
        printk("ADCチャンネルの設定に失敗しました: %d\n", err);
        return;
    }

    err = adc_sequence_init_dt(&adc_spec, &seq);
    if (err < 0) {
        printk("ADCシーケンス初期化に失敗しました: %d\n", err);
        return;
    }

    while (1) {
        err = adc_read(adc_spec.dev, &seq);
        if (err < 0) {
            printk("ADC読み取りに失敗しました: %d\n", err);
        } else {
            printk("ADC値: %d\n", data_buffer);
        }
        k_msleep(1000);
    }
}

2. nrfxライブラリ方式

2.1 prj.conf設定

prj.confファイルに以下を設定します。


CONFIG_NRFX_SAADC=y

2.2 代码例

以下はnrfxライブラリを使用したADCのサンプルコードです。


#include <nrfx_saadc.h>

#define SAADC_INPUT_PIN NRF_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_AIN4, 0)
static nrfx_saadc_channel_t saadc_channel = NRFX_SAADC_DEFAULT_CHANNEL_SE(SAADC_INPUT_PIN, 0);
static int16_t saadc_sample;

void main(void)
{
    nrfx_err_t err;

    err = nrfx_saadc_init(1, NULL); // 優先度は1、必要に応じて調整可能です。
    if (err != NRFX_SUCCESS) {
        printk("SAADC初期化失敗: %08x\n", err);
        return;
    }

    saadc_channel.channel_config.gain = NRF_SAADC_GAIN_1_4;
    err = nrfx_saadc_channels_config(&saadc_channel, 1);
    if (err != NRFX_SUCCESS) {
        printk("SAADCチャンネル設定失敗: %08x\n", err);
        return;
    }

    while (1) {
        err = nrfx_saadc_buffer_set(&saadc_sample, 1);
        if (err != NRFX_SUCCESS) {
            printk("SAADCバッファ設定失敗: %08x\n", err);
            return;
        }

        err = nrfx_saadc_mode_trigger();
        if (err != NRFX_SUCCESS) {
            printk("SAADCトリガー失敗: %08x\n", err);
            return;
        }

        printk("SAADCサンプル値: %d\n", saadc_sample);
        k_msleep(1000);
    }
}

電圧値(mV単位)を取得する場合は以下の式を使用します。

int battery_voltage = ((900 * 4) * saadc_sample) / ((1 << 12)); // 12ビット解像度の場合

タグ: ADC、Zephyr、nrfx

8月6日 06:42 投稿