フォト
2025年3月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
無料ブログはココログ

« Arduino STM32のADC(アナログ・デジタル コンバータ)周辺の調査(1) | トップページ | ココログのリニューアル後の不具合、2ヶ月経っても改善されず... »

2019年5月25日 (土)

Arduino STM32のADC(アナログ・デジタル コンバータ)周辺の調査(2)

前回の続きです。

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); }

実行結果

01_7

測定結果としては、おおよそ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); }

実行結果

02_4

測定結果としては、おおよそ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を行う場合は、このパラメタの変更はかなり有効になってきます。

« Arduino STM32のADC(アナログ・デジタル コンバータ)周辺の調査(1) | トップページ | ココログのリニューアル後の不具合、2ヶ月経っても改善されず... »

arduino」カテゴリの記事

STM32」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

« Arduino STM32のADC(アナログ・デジタル コンバータ)周辺の調査(1) | トップページ | ココログのリニューアル後の不具合、2ヶ月経っても改善されず... »