JP7FKFの備忘録

ヒトは,忘れる生き物だから.

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の少しややこしいところは,PICのようにチャネルを設定しADCをGOしてフラグが落ちるまで(ADC完了まで)待ち,データを取る.というシーケンスでチャネルを次々変えて変換すれば異なるチャンネルのADCができるというわけではないという点である.特に注意するべきがこの複数チャンネルのADCであり,これはDMAを使ってやるとかなり簡単に処理することができる.STM32でADCを利用するときはDMAの利用は必須と言えそうだ.

複数チャネルのADCについては,上記の記事でかなり詳細に紹介されているので,ここは自分が忘れない程度にざっくりと記載していく.参考にするのであれば上記の記事を参考にすることをお勧めする.

DMAを用いたADC

まずはSTM32CubeMXでペリフェラルの設定をする. ADCしたいピンをADCモードに設定する.GUIなので簡単である. f:id:jp7fkf:20180108234233p:plain

さらにconfigurationタブから,ADCのconfigは下記のようにしておく.

  • Continuous Conversion Mode: Enable
  • DMA Continuous Requests: Enable
  • Overrun behaviour: Overrun data overwritten

f:id:jp7fkf:20180108233837p:plain

さらにDMAのconfigをいじっておく.ADCからのDMAリクエストを追加して

  • Mode: Circular
  • Increment Address: Memory
  • Data width: half word f:id:jp7fkf:20180108233855p:plain ここまでできたらCubeMXを用いた設定は終了なので,コードを生成する.

ここからはSW4STM32でコードを書いて行く. 追加するべきは,初期化や変数宣言をするあたりに下記のコードを追加するだけである.

enum{ ADC_BUFFER_LENGTH = 1024 };
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のconfigをOverrun behaviourをOverrun data overwrittenにしていればもっとバッファが少なくてもいい気がするけど,どうなんだろう.ちょっとバッファにどういう風に格納されるかまだ確認してないのでわからない.まぁメモリはたっぷりあるから1024くらいとって今は動かしている.考える時が来たら考えることにしようと思う.

というわけで,これだけでDMAを使ってADC値を得ることができる.ADCするためにCPUを使う必要もないし,いい感じである.CPUのリソースを有効に使える感じがする.これからもSTM32の勉強を進めて色々なモノづくりを進めてみようと思う.

References