Open5
megaAVR 0-seriesで電源電圧を測る方法
環境
IDE:Arduino IDE
ボードパッケージ:MegaCoreX
Arduino IDE を使っているので、ADCの初期化は設定済?
unsigned int getVrefValue() {
// 内部基準電圧を1.1Vに設定
VREF.CTRLA = VREF_AC0REFSEL_1V1_gc;
// 読み取る値を内部基準電圧に設定
ADC0.MUXPOS = ADC_MUXPOS_DACREF_gc;
// 変換開始
ADC0.COMMAND = ADC_STCONV_bm;
// 結果待ち
while (!(ADC0.INTFLAGS & ADC_RESRDY_bm))
{
;
}
// 結果を返す
return ADC0.RES;
}
読み取ったVrefの値を電圧に変えて返す。
#define INT_REF_VOLT 1.1
float cpuVcc(){
long sum=0;
for(int n=0; n < 10; n++){
// adcの値を読んで積分
sum = sum + getVrefValue();
}
float adcAverage = sum / 10.0;
return (1023.0 / adcAverage) * INT_REF_VOLT;
}
ADC採取累積器なるものが存在していて、自動で値を累積してくれるらしい。
#define ADC_SHIFT_DIV32 (5)
uint16_t getVrefValue() {
// 内部基準電圧を1.1Vに設定
VREF.CTRLA = VREF_AC0REFSEL_1V1_gc;
// 採取累積設定
ADC0.CTRLB = ADC_SAMPNUM_ACC32_gc;
// 読み取る値を内部基準電圧に設定
ADC0.MUXPOS = ADC_MUXPOS_DACREF_gc;
// 変換開始
ADC0.COMMAND = ADC_STCONV_bm;
// 結果待ち
while (!(ADC0.INTFLAGS & ADC_RESRDY_bm))
{
;
}
// 値を読み取って32で割る
uint16_t adcVal = ADC0.RES;
adcVal = adcVal >> ADC_SHIFT_DIV32;
// フラグ解除
ADC0.INTFLAGS = ADC_RESRDY_bm;
// 結果を返す
return adcVal ;
}
参考資料
TB3209
megaAVR 0-series では、内部基準電圧を直接測ることはできず、AC0にあるDAC経由の電圧しか測れない。
しかし、tinyAVR 0-Series と tinyAVR 1-Series は直接内部基準電圧を測ることができるっぽい。