Repository navigation
ADC_Template
ADC を搭載した AVR には VDD 電圧や、MPUシリコン温度を測定する機能がある。しかし ADC の回路設計は MPU 毎に異なるため、同じ目的を果たすのでも 応用記述には互換性がないのが普通だ。本稿では できるだけ多くの品種での、設定例を考察する。
単発での測定開始には ADC*_COMMAND に直接開始コマンドを書くか、EVSYS の事象イベントを使う方法がある。一方で、測定完了を知るには ループ検査で調べるか、ADC*_RESRDY_vect 割込で受ける方法がある。
-
ADC*_RESまたはADC*_RESULTを読むと、ADC*_INTFLAGSのADC_RESRDY_bpビットは自動解除される。
データシートでは INITDLY 等と表記される。内部参照基準電圧を使用する場合、そのバンドギャップ出力が安定するまで待つのに必要。0 us から 40 us の自動的に挿入される初期化時間と、手動で設定する追加の初期化時間との合算からなる。
データシートでは SAMPDUR あるいは SAMPDLY+SAMPLEN 等と表記される。入力されたアナログ電圧で内部コンデンサをチャージするための待ち時間。最小限必要な時間は回路のインピーダンス特性に依存する。
CLK_ADC は、0.5 us から 8.0 us の範囲になるよう、ADC0_CTRLB = ADC_PRESC_DIV*_gc で調整する。短すぎると自身の発生するノイズで採取値が擾乱され、長すぎると自己放電で採取値が低くあらわれる。以下は F_CPU(CLK_PER)に分周比 DIV* を掛けた us 粒度への換算表。これを見ると DIV12 か DIV16 で、2 MHz 〜 24 Mhz の周波数範囲をカバーできることがわかる。おおむね 1.0 us 〜 2.0 us になる分周比を選べば間違いはない。
| F_CPU Mhz | 2 | 4 | 6 | 8 | 10 | 12 | 16 | 20 | 24 |
|---|---|---|---|---|---|---|---|---|---|
| DIV2 | 1.00 | 0.50 | - | - | - | - | - | - | - |
| DIV4 | 2.00 | 1.00 | 0.50 | - | - | - | - | - | - |
| DIV6 | 3.00 | 1.50 | 1.00 | 0.75 | 0.60 | 0.50 | - | - | - |
| DIV8 | 4.00 | 2.00 | 1.33 | 1.00 | 0.80 | 0.66 | 0.50 | - | - |
| DIV10 | 5.00 | 2.50 | 1.66 | 1.25 | 1.00 | 0.83 | 0.62 | 0.50 | - |
| DIV12 | 6.00 | 3.00 | 2.00 | 1.50 | 1.20 | 1.00 | 0.75 | 0.60 | 0.50 |
| DIV16 | 8.00 | 4.00 | 2.66 | 2.00 | 1.60 | 1.33 | 1.00 | 0.80 | 0.66 |
| DIV20 | - | 5.00 | 3.33 | 2.50 | 2.00 | 1.66 | 1.25 | 1.00 | 0.83 |
| DIV24 | - | 6.00 | 4.00 | 3.00 | 2.40 | 2.00 | 1.50 | 1.20 | 1.00 |
| DIV28 | - | 7.00 | 4.66 | 3.50 | 2.80 | 2.33 | 1.75 | 1.40 | 1.16 |
| DIV32 | - | 8.00 | 5.33 | 4.00 | 3.20 | 2.66 | 2.00 | 1.60 | 1.33 |
| DIV40 | - | - | 6.66 | 5.00 | 4.00 | 3.33 | 2.50 | 2.00 | 1.66 |
| DIV48 | - | - | 8.00 | 6.00 | 4.80 | 4.00 | 3.00 | 2.40 | 2.00 |
| DIV56 | - | - | - | 7.00 | 5.60 | 4.66 | 3.50 | 2.80 | 2.33 |
| DIV64 | - | - | - | 8.00 | 6.40 | 5.33 | 4.00 | 3.20 | 2.66 |
- CLK_ADC は最短 x2 CLK_PER(=DIV2)であるため、1 MHz 動作では自ずと 0.5 us が最速となる。
- tinyAVR-0/1/2、megaAVR-0 世代の CLK_ADC は、0.5 us から 5.0 us が有効範囲。
- 必然的に ADC 動作可能範囲での
F_CPU最低周波数は 250 kHz(1 MHz の 4分周)となるので、OSC32K、OSC1K 主クロック動作は正常動作範囲外になる。
この系統は、10 bit 分解能で最大 170 ksps の変換速度を有する、シングルエンド変換機能を持っている。
- この系統は
CLKCTRL_MCLKTIMEBASEで CLK_ADC の時間基準を指定する。1〜31 us が指定でき、端数は切り上げすべき(0は不正)。これがADC*_CTRLEで指定するSAMPDUR起動遅延時間値の粒度になる。外部発振器 32 MHz 以上で動作させる場合は、TIMEBASEを半減し、ADC*_CTRLEの値を倍にする。 - 必要に応じて自動挿入される初期化時間は
ADC*_CTRLAにADC_LOWLAT_bmビットを立てると、次回以降の初期化時間を取り除くことができる。(いちど ON にした内部参照電圧を OFF にしない)
- 採取結果からは "温度感知器校正値" を適用すると "ケルビン" が取得される。
- 基準電圧は 2.048V を使用する。このため VDD は最低 2.6V 以上が必要。
- 追加の初期化時間は 35 us 以上が必要。
- 採取値は(符号付整数の)温度校正変位
SIGROW_TEMPSENSE1から減算する。
/* Temperature Measurement for AVR_DU/SD Famiry */
void adc_setup_temperature (void) {
CLKCTRL_MCLKTIMEBASE = F_CPU / 1e6; /* CLK_ADC 基準 : us */
ADC0_MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; /* 正入力選択 : 温度感知器 */
ADC0_CTRLF = ADC_SAMPNUM_NONE_gc; /* 累積変換なし */
ADC0_CTRLE = 35; /* 追加の遅延 : 35 us */
ADC0_CTRLC = ADC_REFSEL_2V048_gc; /* 基準電圧 */
ADC0_CTRLB = ADC_PRESC_DIV12_gc; /* 分周比 */
ADC0_CTRLA = ADC_ENABLE_bm;
}
float get_temperature (void) {
ADC0_COMMAND = ADC_MODE_SINGLE_10BIT_gc | ADC_START_IMMEDIATE_gc;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RESULT; /* 10 bit 採取値 */
float _temp = ((float)((int)SIGROW_TEMPSENSE1)) - _res;
_temp *= (int)SIGROW_TEMPSENSE0;
_temp += 1024 / 2 - (273.15 * 1024); /* 摂氏に補正 */
_temp /= 1024;
return _temp;
}- VDD 電圧を測定するには、
VDD/10入力を 基準電圧 1.024V で測定する。このため VDD は最低 1.6V 以上が必要。 - 追加の初期化時間は 40 usec 程度が必要。
- CLK_ADC は 1.0 us 以上にする。
/* Self Voltage Measurement for AVR_DU/LA/SD Famiry */
void adc_setup_voltage (void) {
CLKCTRL_MCLKTIMEBASE = F_CPU / 1e6; /* CLK_ADC 基準 : us */
ADC0_MUXPOS = ADC_MUXPOS_VDDDIV10_gc; /* 正入力選択 : VDD/10 */
ADC0_CTRLF = ADC_SAMPNUM_NONE_gc;
ADC0_CTRLE = 40;
ADC0_CTRLC = ADC_REFSEL_1V024_gc;
ADC0_CTRLB = ADC_PRESC_DIV24_gc;
ADC0_CTRLA = ADC_ENABLE_bm;
}
float get_voltage (void) {
ADC0_COMMAND = ADC_MODE_SINGLE_10BIT_gc | ADC_START_IMMEDIATE_gc;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RESULT; /* 10 bit 採取値 */
return map_double((double)_res, 0.0, 1023.0, 0.0, 10.23);
}この系統は、10 bit 分解能で最大 170 ksps の変換速度を有する、シングルエンド変換機能を持っている。
- 仕様は AVR_DU/SD 系統と同じだが、温度測定の仕様が異なる。(自己電圧測定応用記述は共通)
- 採取結果からは "温度感知器校正値" を適用すると "ケルビン" が取得される。
- 基準電圧は 1.024V を使用する。このため VDD は最低 1.6V 以上が必要。
- 追加の初期化時間は 60 usec 以上が必要。
- 採取値に 符号付整数の
SIGROW_TEMPSENSE1変位を加算し、符号付整数のSIGROW_TEMPSENSE0傾斜値を掛けて "1024" で割る。 - ・・・とデータシートには記述されているが、実機を用いた検証では、採取値を 4倍して(つまり 12 bit化して)変位を加算し、傾斜値を掛けて "4096" で割らないと正しい結果が得られない。
- おそらく工場製造時の試験+SIGROW 書き込みを "12 bit ADC" で行ったことによる Errata ではないかと思われる。(AVR32LA32 REVID=B1)
/* Temperature Measurement for AVR_LA Famiry */
void adc_setup_temperature (void) {
CLKCTRL_MCLKTIMEBASE = F_CPU / 1e6; /* CLK_ADC 基準 : us */
ADC0_MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; /* 正入力選択 : 温度感知器 */
ADC0_CTRLF = ADC_SAMPNUM_NONE_gc; /* 累積変換なし */
ADC0_CTRLE = 60; /* 追加の遅延 : 60 us */
ADC0_CTRLC = ADC_REFSEL_1V024_gc; /* 基準電圧 */
ADC0_CTRLB = ADC_PRESC_DIV24_gc; /* 分周比 */
ADC0_CTRLA = ADC_ENABLE_bm;
}
float get_temperature (void) {
ADC0_COMMAND = ADC_MODE_SINGLE_10BIT_gc | ADC_START_IMMEDIATE_gc;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RESULT; /* 10 bit 採取値 */
float _temp = (float)((int)SIGROW_TEMPSENSE1) + (_res << 2);
_temp *= (int)SIGROW_TEMPSENSE0;
_temp += 4096 / 2 - (273.15 * 4096); /* 摂氏に補正 */
_temp /= 4096;
return _temp;
}- AVR_DU/SD に同じ。
この系統は、12 bit 分解能で最大 130 ksps の変換速度を有する、差動およびシングルエンド変換機能を持っている。
- つまり AVR_DU/LA/SD は後発なのに分解能は退化した格好。
- バンドギャップ基準電圧は
VREF周辺機能から供給される。 - AVR_DA 系統は
ADCとは排他的に機能するPTC周辺機能を持っている。その関係からかMUXPOSの選択肢が後発と異なる。
- 温度感知器からの採取は、シングルエンド変換を用いる。
ADC0_MUXNEGは差動変換用なので参照されない。 - 採取結果からは "温度感知器校正値" を適用すると "ケルビン" が取得される。
- 基準電圧は 2.048V を使用する。このため VDD は最低 2.6V 以上が必要。
- 追加の起動遅延時間
SAMPDURは 25 us 以上が必要。 - 採取持続時間
SAMPLENは 28 us 以上が必要。
/* Temperature Measurement for AVR_DA/DB/DD Famiry */
void adc_setup_temperature (void) {
VREF_ADC0REF = VREF_REFSEL_2V048_gc; /* 基準電圧 2.048V */
ADC0_MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; /* 正入力選択 : 温度感知器 */
ADC0_CTRLD = ADC_INITDLY_DLY64_gc; /* 25 us 以上になる分周比 */
ADC0_CTRLC = ADC_PRESC_DIV12_gc; /* CLK_ADC を決める分周比 */
ADC0_SAMPCTRL = (F_CPU / 1e6 / 12) * 28; /* 28 us 以上 */
ADC0_CTRLA = ADC_ENABLE_bm
| ADC_RESSEL_12BIT_gc
| ADC_CONVMODE_SINGLEENDED_gc;
}
float get_temperature (void) {
ADC0_COMMAND = ADC_STCONV_bm;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RES; /* 12 bit 採取値 */
float _temp = ((float)((int)SIGROW_TEMPSENSE1)) - _res;
_temp *= (int)SIGROW_TEMPSENSE0;
_temp += 4096 / 2 - (273.15 * 4096); /* 摂氏に補正 */
_temp /= 4096;
return _temp;
}- VDD 電圧を測定するには、
VDD/10入力を 基準電圧 1.024V で測定する。このため VDD は最低 1.6V 以上が必要。
/* Self Voltage Measurement for AVR_DB/DD Famiry */
void adc_setup_voltage (void) {
VREF_ADC0REF = VREF_REFSEL_1V024_gc;
ADC0_MUXPOS = ADC_MUXPOS_VDDDIV10_gc;
ADC0_CTRLD = ADC_INITDLY_DLY64_gc;
ADC0_CTRLC = ADC_PRESC_DIV12_gc;
ADC0_SAMPCTRL = (F_CPU / 1e6 / 12) * 40; /* 目安で 40 us */
ADC0_CTRLA = ADC_ENABLE_bm
| ADC_RESSEL_12BIT_gc
| ADC_CONVMODE_SINGLEENDED_gc;
}
float get_voltage (void) {
ADC0_COMMAND = ADC_STCONV_bm;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RES; /* 12 bit 採取値 */
return map_double((double)_res, 0.0, 4095.0, 0.0, 10.23);
}- この系統には
ADC_MUXPOS_VDDDIV10_gcがないため、VREFからDAC0を経由してVDD/10を生成し、MUXPOSに与えなければならない。
/* Self Voltage Measurement for AVR_DA Famiry */
void adc_setup_voltage (void) {
VREF_ADC0REF = VREF_REFSEL_1V024_gc; /* 負入力選択 は 基準電圧 1.024V を参照 */
VREF_DAC0REF = VREF_REFSEL_VDD_gc; /* VREF から DAC0 に VDD を与える */
DAC0_DATA = (1023U / 10) << 6; /* DAC0 で VDD/10 を生成 */
DAC0_CTRLA = DAC_ENABLE_bm; /* DAC0 活性化 */
ADC0_MUXPOS = ADC_MUXPOS_DAC0_gc; /* 正入力選択 は DAC0 を参照 */
ADC0_CTRLD = ADC_INITDLY_DLY64_gc;
ADC0_CTRLC = ADC_PRESC_DIV12_gc;
ADC0_SAMPCTRL = (F_CPU / 1e6 / 12) * 40; /* 目安で 40 us */
ADC0_CTRLA = ADC_ENABLE_bm
| ADC_RESSEL_12BIT_gc
| ADC_CONVMODE_SINGLEENDED_gc;
}
float get_voltage (void) {
ADC0_COMMAND = ADC_STCONV_bm;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RES; /* 12 bit 採取値 */
return map_double((double)_res, 0.0, 4095.0, 0.0, 10.23);
}この系統は、12 bit 分解能で最大 300 ksps の変換速度を有する、差動およびシングルエンド変換機能を持っている。
- この系統には
CLKCTRL_MCLKTIMEBASEがある。→ AVR_DU/LA/SD - この系統は利得増幅器(PGA: Programmable Gain Amplifier)を備えている。
- 採取結果からは "温度感知器校正値" を適用すると "ケルビン" が取得される。
- 基準電圧は 1.024V を使用する。このため VDD は最低 1.6V 以上が必要。
- 追加の初期化時間は 32 usec 以上が必要。
/* Temperature Measurement for AVR_EA/EB Famiry */
void adc_setup_temperature (void) {
CLKCTRL_MCLKTIMEBASE = F_CPU / 1e6; /* CLK_ADC 基準 : us */
ADC0_MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; /* 正入力選択 : 温度感知器 */
ADC0_CTRLF = ADC_SAMPNUM_NONE_gc;
ADC0_CTRLE = 32; /* 32 us */
ADC0_CTRLC = ADC_REFSEL_1V024_gc; /* 基準電圧 */
ADC0_CTRLB = ADC_PRESC_DIV20_gc;
ADC0_CTRLA = ADC_ENABLE_bm;
}
float get_temperature (void) {
ADC0_COMMAND = ADC_MODE_SINGLE_12BIT_gc | ADC_START_IMMEDIATE_gc;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RESULT; /* 12 bit 採取値 */
float _temp = ((float)((int)SIGROW_TEMPSENSE1)) + _res;
_temp *= (int)SIGROW_TEMPSENSE0;
_temp += 4096 / 2 - (273.15 * 4096); /* 摂氏に補正 */
_temp /= 4096;
return _temp;
}- VDD 電圧を測定するには、
VDD/10入力を 基準電圧 1.024V で測定する。このため VDD は最低 1.6V 以上が必要。
/* Self Voltage Measurement for AVR_EA/EB Famiry */
void adc_setup_voltage (void) {
CLKCTRL_MCLKTIMEBASE = F_CPU / 1e6; /* CLK_ADC 基準 : us */
ADC0_MUXPOS = ADC_MUXPOS_VDD10_gc; /* 正入力は VDD/10 */
ADC0_CTRLF = ADC_SAMPNUM_NONE_gc;
ADC0_CTRLE = 60; /* 目安で 60 us */
ADC0_CTRLC = ADC_REFSEL_1V024_gc;
ADC0_CTRLB = ADC_PRESC_DIV20_gc;
ADC0_CTRLA = ADC_ENABLE_bm;
}
float get_voltage (void) {
ADC0_COMMAND = ADC_MODE_SINGLE_12BIT_gc | ADC_START_IMMEDIATE_gc;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp); /* 採取完了待ち */
uint16_t _res = ADC0_RESULT; /* 12 bit 採取値 */
return map_double((double)_res, 0.0, 4095.0, 0.0, 10.23);
}この系統は、12 bit 分解能で最大 375 ksps の変換速度を有する、差動およびシングルエンド変換機能を持っている。
- この系統は利得増幅器(PGA: Programmable Gain Amplifier)を備えている。
- この系統は
VREF周辺機能を持っているが、ADC はそちらを参照しない。 - この系統の
ADC0_RESULTは、32 bit 幅である。 - CTRLC の 上位 5 bit で
TIMEBASEを定義する。
- 採取結果からは "温度感知器校正値" を適用すると "ケルビン" が取得される。
- 基準電圧は 1.1V を使用する。このため VDD は最低 1.6V 以上が必要。
- 追加の初期化時間は 言及無し。
- 採取持続時間は 32 usec 以上が必要。
-
SIGROW_TEMPSENSE0は符号無し整数、SIGROW_TEMPSENSE1は符号付整数。 - 採取値は 12 bit 精度だが上記補正値を 2 bit 増しで評価するため、最後の除数は 1024 になる。
/* Temperature Measurement for tinyAVR-2 Famiry */
void adc_setup_temperature (void) {
ADC0_MUXPOS = ADC_MUXPOS_TEMPSENSE_gc;
ADC0_CTRLF = ADC_SAMPNUM_NONE_gc;
ADC0_CTRLE = 20;
ADC0_CTRLC = (((uint8_t)(F_CPU / 1e6)) << 3) | VREF_AC0REFSEL_1V024_gc;
ADC0_CTRLB = ADC_PRESC_DIV40_gc;
ADC0_CTRLA = ADC_ENABLE_bm;
}
float get_temperature (void) {
ADC0_COMMAND = ADC_MODE_SINGLE_12BIT_gc | ADC_START_IMMEDIATE_gc;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = (uint16_t)ADC0_RESULT;
float _temp = (float)_res - ((float)(((int8_t)SIGROW_TEMPSENSE1)));
_temp *= (uint8_t)SIGROW_TEMPSENSE0;
_temp += 1024 / 2 - (273.15 * 1024); /* 摂氏に補正 */
_temp /= 1024;
return _temp;
}/* Self Voltage Measurement for tinyAVR-2 Famiry */
void adc_setup_voltage (void) {
ADC0_MUXPOS = ADC_MUXPOS_VDDDIV10_gc;
ADC0_CTRLF = ADC_SAMPNUM_NONE_gc;
ADC0_CTRLE = 40; /* 目安 */
ADC0_CTRLC = (((uint8_t)(F_CPU / 1e6)) << 3) | ADC_REFSEL_1024MV_gc;
ADC0_CTRLB = ADC_PRESC_DIV40_gc;
ADC0_CTRLA = ADC_ENABLE_bm;
}
float get_voltage (void) {
ADC0_COMMAND = ADC_MODE_SINGLE_12BIT_gc | ADC_START_IMMEDIATE_gc;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = (uint16_t)ADC0_RESULT;
return map_double((double)_res, 0.0, 4095.0, 0.0, 10.23);
}この系統は、10 bit 分解能で最大 350 ksps の変換速度を有する、シングルエンド変換機能を持っている。
- CLK_ADC は、0.5 us から 5.0 us の範囲でなければならない。
- バンドギャップ基準電圧は
VREF周辺機能から供給される。 - この系統は
ADCとは排他的に機能するPTC周辺機能を持っている。
- 採取結果からは "温度感知器校正値" を適用すると "ケルビン" が取得される。
- 基準電圧は 1.1V を使用する。このため VDD は最低 1.6V 以上が必要。
- 追加の初期化時間は 32 usec 以上が必要。
- 採取持続時間は 32 usec 以上が必要。
-
SIGROW_TEMPSENSE0は符号無し整数、SIGROW_TEMPSENSE1は符号付整数。 - 採取値は 10 bit だが上記補正値は 8-bit で評価するため、最後の除数は 256 になる。
/* Temperature Measurement for tinyAVR-1, megaAVR-0 Famiry */
void adc_setup_temperature (void) {
VREF_CTRLA = VREF_ADC0REFSEL_1V1_gc; /* バンドギャップ 1.1V */
ADC0_MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; /* 正入力選択 : 温度感知器 */
ADC0_CTRLD = ADC_INITDLY_DLY32_gc;
ADC0_CTRLC = ADC_SAMPCAP_bm | ADC_REFSEL_INTREF_gc | ADC_PRESC_DIV32_gc;
ADC0_CTRLB = ADC_SAMPNUM_ACC1_gc;
ADC0_CTRLA = ADC_ENABLE_bm | ADC_RESSEL_10BIT_gc;
}
float get_temperature (void) {
ADC0_COMMAND = ADC_STCONV_bm;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RES;
float _temp = _res - ((float)((int8_t)SIGROW_TEMPSENSE1));
_temp *= (uint8_t)SIGROW_TEMPSENSE0;
_temp += 256 / 2 - (273.15 * 256);
_temp /= 256;
return _temp;
}- VDD 電圧を測定するには バンドギャップ入力電圧 1.1V を、VDD で測定する。このため VDD は最低 1.6V 以上が必要。
- この系統では
MUXPOS側が固定電圧(バンドギャップ)、比較側が可変電圧になる点が他と異なる。(採取値の逆数を取る)
/* Self Voltage Measurement for tinyAVR-1 Famiry */
void adc_setup_voltage (void) {
VREF_CTRLA = VREF_ADC0REFSEL_1V1_gc; /* バンドギャップ 1.1V */
ADC0_MUXPOS = ADC_MUXPOS_INTREF_gc;
ADC0_CTRLD = ADC_INITDLY_DLY32_gc;
ADC0_CTRLC = ADC_SAMPCAP_bm | ADC_REFSEL_VDDREF_gc | ADC_PRESC_DIV32_gc;
ADC0_CTRLB = ADC_SAMPNUM_ACC1_gc;
ADC0_CTRLA = ADC_ENABLE_bm | ADC_RESSEL_10BIT_gc;
}
float get_voltage (void) {
ADC0_COMMAND = ADC_STCONV_bm;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RES;
return map_double(1023.0 / (double)_res, 1.0, 2.0, 1.1, 2.2);
}この系統は、10 bit 分解能で最大 350 ksps の変換速度を有する、シングルエンド変換機能を持っている。
tinyAVR-1 とほとんど同じだが、MUXPOS や CTRLC に指定できる選択肢に違いがある。
- tinyAVR-1 に同じ。
-
MUXPOSに直接VDD/10等を指定する手段がない。このためVREFからAC0_DACREFを経由し、AVDD/5電圧を得てMUXPOSに供給する。
/* Self Voltage Measurement for megaAVR-0 Famiry */
void adc_setup_voltage (void) {
VREF_CTRLA = VREF_AC0REFSEL_AVDD_gc | VREF_ADC0REFSEL_1V1_gc;
AC0_DACREF = 255 / 5; /* AVDD/5 */
ADC0_MUXPOS = ADC_MUXPOS_DACREF_gc;
ADC0_CTRLD = ADC_INITDLY_DLY32_gc;
ADC0_CTRLC = ADC_SAMPCAP_bm | ADC_REFSEL_INTREF_gc | ADC_PRESC_DIV32_gc;
ADC0_CTRLB = ADC_SAMPNUM_ACC1_gc;
ADC0_CTRLA = ADC_ENABLE_bm | ADC_RESSEL_10BIT_gc;
}
float get_voltage (void) {
ADC0_COMMAND = ADC_STCONV_bm;
loop_until_bit_is_set(ADC0_INTFLAGS, ADC_RESRDY_bp);
uint16_t _res = ADC0_RES;
return map_double((double)_res, 0.0, 1023.0, 0.0, 5.5);
}Twitter(X): @askn37
BlueSky Social: @multix.jp
GitHub: https://github.com/askn37/
Product: https://askn37.github.io/
Copyright (c) 2026 askn (K.Sato) multix.jp
Released under the MIT license
https://opensource.org/licenses/mit-license.php
https://www.oshwa.org/
multix.jp/てくにかるむ(休眠中)
Multix Zinnia Product SDK [*AVR]
AVR.JP(日本語訳)
AVR-LIBC(日本語訳)