STM32のADC/DAC活用:アナログ信号処理入門
現代のエレクトロニクスにおいて、マイクロコントローラ(MCU)は、デジタル制御の中核を担っています。中でも、STM32は、豊富な周辺機能と柔軟なアーキテクチャにより、様々なアプリケーションで広く利用されています。STM32の強みの一つが、高性能なアナログ-デジタル変換器(ADC)とデジタル-アナログ変換器(DAC)を内蔵していることです。これらの機能を効果的に活用することで、アナログ信号の取得、処理、生成をMCU内部で完結させることができ、外部回路の簡素化、コスト削減、システム全体の性能向上に貢献します。
本稿では、STM32のADCとDACに焦点を当て、アナログ信号処理の基礎から応用までを網羅的に解説します。ADCとDACの基本的な原理、STM32における具体的な実装方法、そして実際のアプリケーションにおける活用事例を通じて、STM32を用いたアナログ信号処理の可能性を深く掘り下げていきます。
1. アナログ-デジタル変換器(ADC)の基礎
1.1. ADCとは
ADC(Analog-to-Digital Converter)は、連続的なアナログ信号を離散的なデジタル信号に変換するデバイスです。現実世界のアナログ信号(温度、圧力、光など)をMCUで処理するためには、まずADCを用いてデジタルデータに変換する必要があります。
1.2. ADCの主要な特性
ADCの性能を評価する上で重要な特性には、以下のようなものがあります。
- 分解能 (Resolution): 出力できるデジタル値の数で、通常ビット数で表されます(例:8ビット、10ビット、12ビット)。分解能が高いほど、微細なアナログ信号の変化を捉えることができます。
- 変換速度 (Conversion Rate): 1秒間に変換できるサンプル数で、SPS(Samples Per Second)やKSPS(Kilo Samples Per Second)、MSPS(Mega Samples Per Second)で表されます。変換速度が高いほど、高速なアナログ信号の変化に対応できます。
- 入力レンジ (Input Range): ADCが正常に動作できる入力電圧の範囲です。入力レンジを超える電圧が入力されると、変換結果が飽和したり、デバイスが損傷したりする可能性があります。
- 精度 (Accuracy): 実際の入力電圧と変換されたデジタル値との誤差を表します。精度が高いほど、より正確な変換が可能です。
- 直線性 (Linearity): 入力電圧に対する出力コードの直線性を表します。理想的なADCは、入力電圧と出力コードが線形の関係を持ちますが、実際には多少の非線形性があります。
- サンプルレート (Sampling Rate): アナログ信号をデジタル信号に変換する頻度です。ナイキスト・シャノンの定理に従い、サンプリングレートは、入力信号の最大周波数の2倍以上である必要があります。
1.3. ADCの動作原理
ADCの動作原理には、様々な方式がありますが、ここでは代表的な方式である逐次比較型ADCについて説明します。
逐次比較型ADCの動作:
- サンプルホールド: 入力されたアナログ信号を一定期間保持します。これにより、変換中に信号が変化することを防ぎます。
- DACとコンパレータ: 内部にDAC(デジタル-アナログ変換器)とコンパレータを備えています。DACは、デジタル値をアナログ電圧に変換します。コンパレータは、入力されたアナログ電圧とDACの出力電圧を比較します。
- 逐次比較ロジック: デジタル値をMSB(Most Significant Bit:最上位ビット)から順番に決定していきます。
- MSBの決定: まず、DACの出力電圧を、入力レンジの中央値に設定します。コンパレータは、入力されたアナログ電圧とDACの出力電圧を比較します。入力されたアナログ電圧がDACの出力電圧より大きい場合、MSBは1に設定されます。小さい場合、MSBは0に設定されます。
- 次のビットの決定: MSBが決定された後、次のビットを決定します。DACの出力電圧は、MSBの値に基づいて調整されます。コンパレータは、入力されたアナログ電圧とDACの出力電圧を比較し、次のビットの値を決定します。
- LSBの決定: LSB(Least Significant Bit:最下位ビット)まで、上記の手順を繰り返します。
- デジタル出力: すべてのビットが決定されると、デジタル出力として結果が出力されます。
1.4. STM32のADC
STM32シリーズのMCUには、通常、複数のADCが内蔵されています。これらのADCは、通常、12ビットの分解能を持ち、最大で数MSPSの変換速度を実現します。また、DMA(Direct Memory Access)コントローラと連携することで、CPUの負荷を軽減しながら連続的なデータ取得が可能です。
STM32のADCの特徴:
- 複数のチャンネル: 複数のアナログ入力チャンネルを持つため、複数のアナログ信号を同時に監視できます。
- 様々なトリガーソース: 変換開始のトリガーソースとして、タイマー、外部割り込み、ソフトウェアなど、様々なオプションを選択できます。
- DMAサポート: DMAを使用することで、ADCの変換結果を自動的にメモリに転送し、CPUの負荷を軽減できます。
- 様々な変換モード: シングル変換モード、連続変換モード、スキャンモードなど、様々な変換モードを選択できます。
- オーバーサンプリング: オーバーサンプリングを使用することで、ADCの分解能を向上させることができます。
2. デジタル-アナログ変換器(DAC)の基礎
2.1. DACとは
DAC(Digital-to-Analog Converter)は、離散的なデジタル信号を連続的なアナログ信号に変換するデバイスです。MCUで生成されたデジタル信号を、モーターの制御、オーディオ信号の出力、電圧の制御など、現実世界の様々なアプリケーションで使用できるアナログ信号に変換するために使用されます。
2.2. DACの主要な特性
DACの性能を評価する上で重要な特性には、以下のようなものがあります。
- 分解能 (Resolution): 出力できるアナログ電圧のステップ数で、通常ビット数で表されます(例:8ビット、10ビット、12ビット)。分解能が高いほど、より細かい電圧制御が可能です。
- セトリングタイム (Settling Time): 出力電圧が、指定された精度範囲内に入るまでの時間です。セトリングタイムが短いほど、高速なアナログ信号の生成が可能です。
- 出力レンジ (Output Range): DACが出力できる電圧の範囲です。出力レンジは、アプリケーションに必要な電圧範囲に合わせて選択する必要があります。
- 直線性 (Linearity): 入力されたデジタル値に対する出力電圧の直線性を表します。
- 単調性 (Monotonicity): 入力されたデジタル値が増加するにつれて、出力電圧が常に増加または変化しないことを表します。
- スルーレート (Slew Rate): 出力電圧が時間あたりに変化できる最大速度を表します。
2.3. DACの動作原理
DACの動作原理には、様々な方式がありますが、ここでは代表的な方式であるR-2Rラダー型DACについて説明します。
R-2Rラダー型DACの動作:
- R-2R抵抗ラダー: Rと2Rの抵抗を組み合わせたネットワークを使用します。
- スイッチング: 各ビットに対応するスイッチは、入力デジタル値に応じて、基準電圧またはグランドに接続されます。
- 電流の加算: スイッチングされた電流は、R-2R抵抗ラダーを流れ、出力ノードで加算されます。
- 出力電圧: 出力ノードの電圧は、入力デジタル値に比例したアナログ電圧になります。
2.4. STM32のDAC
STM32シリーズのMCUには、通常、1つまたは複数のDACが内蔵されています。これらのDACは、通常、12ビットの分解能を持ち、電圧出力モードと電流出力モードをサポートしています。また、DMAコントローラと連携することで、CPUの負荷を軽減しながら連続的なアナログ信号の生成が可能です。
STM32のDACの特徴:
- 複数のチャンネル: 複数のアナログ出力チャンネルを持つため、複数のアナログ信号を同時に生成できます。
- 様々なトリガーソース: 出力開始のトリガーソースとして、タイマー、外部割り込み、ソフトウェアなど、様々なオプションを選択できます。
- DMAサポート: DMAを使用することで、DACの出力値を自動的に更新し、CPUの負荷を軽減できます。
- ノイズ低減: 内部のノイズ低減回路により、高品位なアナログ信号を生成できます。
- 波形生成: タイマーと組み合わせて、様々な波形(正弦波、三角波、矩形波など)を生成できます。
3. STM32におけるADC/DACの実装
3.1. ADCの設定
STM32のADCを設定するには、以下の手順が必要です。
- クロックの設定: ADCモジュールにクロックを供給します。
- GPIOの設定: ADCの入力ピンとして使用するGPIOピンを設定します。
- ADCの初期化: ADCの分解能、変換速度、トリガーソース、DMA設定などのパラメータを設定します。
- チャンネルの設定: 変換するアナログ入力チャンネルを選択します。
- 割り込みの設定 (必要に応じて): 変換完了時の割り込みを設定します。
- ADCの有効化: ADCを有効にします。
- 変換開始: 変換を開始します。
3.2. DACの設定
STM32のDACを設定するには、以下の手順が必要です。
- クロックの設定: DACモジュールにクロックを供給します。
- GPIOの設定: DACの出力ピンとして使用するGPIOピンを設定します。
- DACの初期化: DACの分解能、トリガーソース、DMA設定などのパラメータを設定します。
- 出力バッファの有効化 (必要に応じて): DACの出力バッファを有効にします。
- 割り込みの設定 (必要に応じて): 出力完了時の割り込みを設定します。
- DACの有効化: DACを有効にします。
- 出力値の設定: DACの出力値を設定します。
3.3. HALライブラリの使用
STMicroelectronicsは、STM32のペリフェラルを簡単に操作するためのHAL(Hardware Abstraction Layer)ライブラリを提供しています。HALライブラリを使用することで、レジスタレベルでの複雑な操作を抽象化し、より簡単にADC/DACを使用できます。
例えば、ADCの初期化は、HAL_ADC_Init()
関数、変換開始は、HAL_ADC_Start()
関数、変換完了の読み出しは、HAL_ADC_GetValue()
関数を使用して行うことができます。同様に、DACの初期化は、HAL_DAC_Init()
関数、出力開始は、HAL_DAC_Start()
関数、出力値の設定は、HAL_DAC_SetValue()
関数を使用して行うことができます。
3.4. コード例 (ADC)
“`c
include “stm32f4xx_hal.h”
ADC_HandleTypeDef hadc1;
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
uint32_t read_adc(void) {
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
uint32_t adc_value = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
return adc_value;
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
“`
3.5. コード例 (DAC)
“`c
include “stm32f4xx_hal.h”
DAC_HandleTypeDef hdac;
void MX_DAC_Init(void)
{
DAC_ChannelConfTypeDef sConfig = {0};
hdac.Instance = DAC;
if (HAL_DAC_Init(&hdac) != HAL_OK)
{
Error_Handler();
}
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
void set_dac_value(uint16_t value) {
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value);
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
“`
4. アナログ信号処理の応用例
4.1. センサーデータの取得と処理
様々なセンサー(温度、圧力、光、加速度など)のアナログ出力をSTM32のADCで取得し、デジタルデータに変換します。その後、取得したデータに対して、フィルタリング、校正、線形化などの処理を行い、信頼性の高いセンサー情報を提供します。例えば、温度センサーから取得したデータに対して、ノイズを除去するための移動平均フィルタを適用したり、センサーの個体差による誤差を補正するための校正処理を行ったりすることができます。
4.2. モーター制御
STM32のDACを用いて、モーターの速度やトルクを制御するためのアナログ電圧を生成します。PWM(Pulse Width Modulation)信号を生成し、ローパスフィルタを通してアナログ電圧に変換する方法もよく用いられます。モーターのフィードバック信号(エンコーダからの信号など)をADCで取得し、PID制御などのアルゴリズムを用いて、より精密なモーター制御を実現することも可能です。
4.3. オーディオ信号の生成と処理
STM32のDACを用いて、オーディオ信号を生成し、スピーカーやヘッドホンから出力します。また、マイクから入力されたオーディオ信号をADCで取得し、フィルタリング、増幅、イコライジングなどの処理を行い、音質を改善したり、特定の周波数帯域の音を強調したりすることができます。
4.4. 電圧/電流制御
STM32のDACを用いて、精密な電圧や電流を生成し、電源回路や実験装置などの制御を行います。DACの出力電圧をフィードバック制御することで、より安定した電圧/電流源を実現できます。
4.5. 信号発生器
STM32のDACとタイマー機能を組み合わせることで、正弦波、三角波、矩形波などの様々な波形を生成する信号発生器を構築できます。生成した波形は、実験、テスト、計測などの様々な用途に利用できます。
5. 高度なアナログ信号処理テクニック
5.1. オーバーサンプリングとデシメーション
オーバーサンプリングは、ナイキスト周波数よりも高い周波数でサンプリングすることで、ADCの有効分解能を向上させるテクニックです。オーバーサンプリングされたデータは、その後、デシメーションフィルタを通してダウンサンプリングされ、ノイズを低減します。
5.2. フィルタリング
デジタルフィルタは、特定の周波数帯域の信号を強調したり、減衰させたりするために使用されます。STM32のCPUまたは専用のDSP(Digital Signal Processor)を使用して、FIR(Finite Impulse Response)フィルタやIIR(Infinite Impulse Response)フィルタなどの様々な種類のデジタルフィルタを実装できます。
5.3. 高速フーリエ変換 (FFT)
FFTは、時間領域の信号を周波数領域の信号に変換するためのアルゴリズムです。STM32を使用してFFTを実装することで、信号の周波数成分を分析したり、スペクトラムアナライザを構築したりすることができます。
5.4. PID制御
PID制御は、目標値と現在値との誤差に基づいて、制御量を調整するフィードバック制御アルゴリズムです。STM32を使用してPID制御を実装することで、モーター、温度、電圧などの様々なシステムを安定かつ正確に制御できます。
6. 注意点とトラブルシューティング
6.1. ノイズ対策
アナログ回路は、ノイズの影響を受けやすいです。ノイズ対策として、以下の点に注意する必要があります。
- グランド設計: グランドループを避けるために、適切なグランド設計を行う必要があります。
- シールド: アナログ回路をノイズ源からシールドする必要があります。
- フィルタリング: 電源ラインや信号ラインにフィルタを挿入することで、ノイズを除去することができます。
- 配線: アナログ信号ラインとデジタル信号ラインを分離して配線する必要があります。
6.2. キャリブレーション
ADC/DACの精度は、温度や電源電圧などの環境要因によって変動する可能性があります。高い精度が求められるアプリケーションでは、定期的なキャリブレーションを行う必要があります。
6.3. サンプリングレートの選定
サンプリングレートは、入力信号の最大周波数の2倍以上である必要があります。サンプリングレートが不適切だと、エイリアシングが発生し、信号が歪んでしまう可能性があります。
6.4. 分解能の選定
ADC/DACの分解能は、アプリケーションに必要な精度に合わせて選定する必要があります。分解能が不足すると、信号の微細な変化を捉えることができません。
6.5. 入力レンジ/出力レンジの選定
ADC/DACの入力レンジ/出力レンジは、アプリケーションに必要な電圧範囲に合わせて選定する必要があります。入力レンジ/出力レンジを超える電圧が入力/出力されると、変換結果が飽和したり、デバイスが損傷したりする可能性があります。
7. まとめ
STM32に内蔵されたADCとDACは、アナログ信号処理において非常に強力なツールです。本稿で解説した基礎知識、実装方法、応用例、そして高度なテクニックを習得することで、STM32を最大限に活用し、革新的なアプリケーションを開発することができます。
アナログ信号処理は、奥深く、学ぶべきことがたくさんありますが、本稿が、STM32を用いたアナログ信号処理への入門の手助けとなれば幸いです。今後も継続的に学習し、実践を通じてスキルを向上させていくことをお勧めします。