STM32マイコンでADCを使ってみる話
最近はPICよりかはSTM32を用いて電子な工作をしている. 基本的なペリフェラルとして,GPIO(論理出力/入力),ADC, PWM,Timer(割り込み),通信系(I2C,SPI,USART,I2S,CAN,USBなどなど)等がある.このうちでもセンシング等でよく利用されるのがADCであろう.秋月で簡単にチップが入手できるSTM32F042には,12bitというわりと分解能の高いADCが付いている.PICでは8bitや10bitが多い中,12bitもの分解能が得られるADCはありがたいものだ.
今回はこのSTM32のADCを利用する方法を簡単にまとめてみようと思う. 主に下記の記事を参考にさせていただいた.
- STM32でADCをやってみる1(レギュラ変換) - ガレスタさんのDIY日記
- STM32でADCをやってみる2(DMAを使ったレギュラ変換) - ガレスタさんのDIY日記
- /STM32/STM32L0のADCで、複数チャンネルの入力でハマる – Talk Like Singing
- 複数chのAD変換: Crescent
STM32の少しややこしいところは,PICのようにチャネルを設定しADCをGOしてフラグが落ちるまで(ADC完了まで)待ち,データを取る.というシーケンスでチャネルを次々変えて変換すれば異なるチャンネルのADCができるというわけではないという点である.特に注意するべきがこの複数チャンネルのADCであり,これはDMAを使ってやるとかなり簡単に処理することができる.STM32でADCを利用するときはDMAの利用は必須と言えそうだ.
複数チャネルのADCについては,上記の記事でかなり詳細に紹介されているので,ここは自分が忘れない程度にざっくりと記載していく.参考にするのであれば上記の記事を参考にすることをお勧めする.
DMAを用いたADC
まずはSTM32CubeMXでペリフェラルの設定をする. ADCしたいピンをADCモードに設定する.GUIなので簡単である.
さらにconfigurationタブから,ADCのconfigは下記のようにしておく.
- Continuous Conversion Mode: Enable
- DMA Continuous Requests: Enable
- Overrun behaviour: Overrun data overwritten
さらにDMAのconfigをいじっておく.ADCからのDMAリクエストを追加して
- Mode: Circular
- Increment Address: Memory
- Data width: half word
ここまでできたらCubeMXを用いた設定は終了なので,コードを生成する.
ここからはSW4STM32でコードを書いて行く. 追加するべきは,初期化や変数宣言をするあたりに下記のコードを追加するだけである.
enum{ ADC_BUFFER_LENGTH = 2 }; uint16_t g_ADCBuffer[ADC_BUFFER_LENGTH]; memset(g_ADCBuffer, 0, sizeof(g_ADCBuffer)); HAL_ADC_Start_DMA(&hadc, g_ADCBuffer, ADC_BUFFER_LENGTH);
これで,任意の場所でg_ADCBufferの中身をみてやれば各chのADC値が読み取れる.ch1とch2を使っているのであればg_ADCBuffer[0]にch1が,g_ADCBuffer[1]にch2のADC値が入っている.
ADCを複数チャネルで利用する場合であっても,チャネルの若番から順に配列に格納されていく.ch1とch3のみを有効化した場合でもg_ADCBuffer[0]にch1, g_ADCBuffer[1]にch3の結果が入る.
というわけで,これだけでDMAを使ってADC値を得ることができる.ADCするためにCPUを使う必要もないし,いい感じである.CPUのリソースを有効に使える感じがする.これからもSTM32の勉強を進めて色々なモノづくりを進めてみようと思う.