要約
Nordic Semiconductor社製SoC nRF52840のAD変換器でVDDH電圧, VDD電圧を読み出す。
コード
prj.conf
CONFIG_ADC=y
app.overlay
/ {
zephyr,user {
io-channels = <&adc 0>, <&adc 1>;
};
};
&adc {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
channel@0 {
reg = <0>;
zephyr,gain = "ADC_GAIN_1_2";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,input-positive = <NRF_SAADC_VDDHDIV5>;
zephyr,resolution = <12>;
};
channel@1 {
reg = <1>;
zephyr,gain = "ADC_GAIN_1_6";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,input-positive = <NRF_SAADC_VDD>;
zephyr,resolution = <12>;
};
};
C
#include <zephyr/drivers/adc.h>
#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
ADC_DT_SPEC_GET_BY_IDX(node_id, idx),
static const struct adc_dt_spec adc_channels[] = {
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels, DT_SPEC_AND_COMMA)};
static uint16_t buf[ARRAY_SIZE(adc_channels)];
static struct adc_sequence sequence[ARRAY_SIZE(adc_channels)];
void adc_initialize(void) {
int err;
for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
if (!adc_is_ready_dt(&adc_channels[i])) {
return;
}
err = adc_channel_setup_dt(&adc_channels[i]);
if (err < 0) {
return;
}
sequence[i].buffer = &buf[i];
sequence[i].buffer_size = sizeof(buf[i]);
}
}
void adc_update(void) {
int err;
for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
(void)adc_sequence_init_dt(&adc_channels[i], &sequence[i]);
err = adc_read_dt(&adc_channels[i], &sequence[i]);
if (err < 0) {
return;
}
}
}
int32_t adc_get(const uint8_t kIdx) {
int err;
int32_t val_mv;
if (ARRAY_SIZE(adc_channels) <= kIdx) {
return -1;
}
if (adc_channels[kIdx].channel_cfg.differential) {
val_mv = (int32_t)((int16_t)buf[kIdx]);
} else {
val_mv = (int32_t)buf[kIdx];
}
if (0 == kIdx) {
val_mv *= 5; // VDDH DIV 5
}
err = adc_raw_to_millivolts_dt(&adc_channels[kIdx], &val_mv);
if (err < 0) {
return -1;
} else {
return val_mv;
}
return -1;
}
設計メモ
- 内蔵リファレンス電圧は0.6V。(余談: nRF54L15は0.9Vらしい)
- VDDの動作範囲は1.7V〜3.6Vなので、Gainは1/6倍を選択すればリファレンス電圧を超えない。
- VDDHの動作範囲は2.5V〜5.5V、AD変換器の入力時点で1/5されているので、Gainは1/2倍を選択すればリファレンス電圧を超えない。
今後の取り組み
- VDDHDIV5はインピーダンスが高いためか、直前のAD変換結果の影響を受けているような気がするので、アクイジションタイムを長くする、事前にサンプルホールドキャパシタを放電させる等の対策を実施したい。
動作確認環境
- toolchains v2.6.2
- nRF Connect SDK v2.6.2
- MDBT50Q-DB-40 (raytac_mdbt50q_db_40_nrf52840)