前回の続きです。
Arduino STM32で手っ取り早くADCを使うには、analogRead()を利用します。
このanalogRead()を利用した場合、変換に要する時間はどれ程なのでしょうか?
疑問に思い、調べてみました。
STM32F1xでは、次のパラメタの設定値が変換時間を決定します。
1)ADCCLK
ADCのベースとなるクロックです。次の設定が可能です。
・システムクロックの1/2
・システムクロックの1/4
・システムクロックの1/6
・システムクロックの1/8
Arduino STM32では、デフォルトではシステムクロックを1/6 に分周したクロックが設定されています。
2)サンプリングタイム
サンプリングタイムはADCCLKサイクルを単位として、次の設定が可能です。
・1.5 × ADCCLK サイクル
・7.5 × ADCCLK サイクル
・13.5 × ADCCLK サイクル
・28.5 × ADCCLK サイクル
・41.5 × ADCCLK サイクル
・55.5 × ADCCLK サイクル
・71.5 × ADCCLK サイクル
・239.5 × ADCCLK サイクル
変換に要する時間は次の式で求めることが出来ます。
Tconv = サンプリングタイム + 12.5 サイクル (サイクル)
デフォルトでは 55.5 × ADCCLK サイクル が設定されています。
Blue Pillボードをシステムクロック 72MHzで利用した場合、
ADCCLK = 72MHz / 6 = 12MHz
Tconv(サイクル) = 12.5 + 55.5 = 68 サイクル
Tconv(μ秒) = 1/12e6 × 68 × 1e6 = 5.67 μ(マイクロ)秒
となります。
実際にBluePillボードで測定してみました。
テスト用スケッチ
void setup() {
Serial.begin(115200);
pinMode(PA0,INPUT_ANALOG);
}
void loop() {
uint32_t t1,t2;
uint16_t v;
t1 = micros();
v = analogRead(PA0);
t2 = micros();
Serial.print("v=");Serial.print(v);
Serial.print(" t=");Serial.println(t2-t1);
delay(1000);
}
|
実行結果

測定結果としては、おおよそ7~8μ秒 でした。
呼び出しのオーバーヘッド等もあるので妥当な値でしょう。
次に、変換時間が最短になるよう、ADCCLKとサンプリングタイムを変更してみました。
次の設定に変更します。
ADCCLK : システムクロックの1/2
サンプリングタイム : 1.5 × ADCCLK サイクル
この設定の場合、変換に要する時間は、
ADCCLK = 72MHz / 2 = 36MHz
Tconv(サイクル) = 12.5 + 1.5 = 14 サイクル
Tconv(μ秒) = 1/36e6 × 14 × 1e6 = 0.38 μ(マイクロ)秒
変更したスケッチ
#include <libmaple/adc.h>
void setup() {
Serial.begin(115200);
adc_set_prescaler(ADC_PRE_PCLK2_DIV_2);
adc_set_sample_rate(PIN_MAP[PA0].adc_device,ADC_SMPR_1_5);
pinMode(PA0,INPUT_ANALOG);
}
void loop() {
uint32_t t1,t2;
uint16_t v;
t1 = micros();
v = analogRead(PA0);
t2 = micros();
Serial.print("v=");Serial.print(v);
Serial.print(" t=");Serial.println(t2-t1);
delay(1000);
}
|
実行結果
測定結果としては、おおよそ2~3μ秒 でした。
デフォルト設定の実測値 7~8μ秒より、約5μ秒短縮出来ました。
計算値上でも5.3μ秒の短縮(5.67⇒0.38)ですので、オーバヘッドが2μ秒程度であることがわかります。
ですので、高速化時の測定結果 2~3μ秒(うちオーバヘッドが2μ程度)は妥当な値でしょう。
高速化のスケッチのADCCLK、サンプリングタイムの変更は、前回 ちょっこと触れた
・アナログ - デジタル変換(ADC)のサポート Analog to Digital Conversion (ADC) support(adc.h)
のAPI関数を利用しています。
analogRead() を使って、簡単なADCを行う分においては、
デフォルト設定と高速化でそれほど大きな差はないので、デフォルトのまま利用して問題ないと思います。
ただし、DMAを使って多チャンネルのADCを行う場合は、このパラメタの変更はかなり有効になってきます。
最近のコメント