目次
STM32Fの内蔵温度センサを読み出す
STマイクロエレクトロニクス社のSTM32Fシリーズにはチップ内に温度センサが内蔵されているのをご存知ですか。ADコンバータを試したいと思ってSTM32Fのスペックを見ていると内蔵温度センサがあるのに気づきました。このセンサはADコンバータの入力ポートにつながっていているので、チップ単体で読み出すことができます。手元にSTM32F334を搭載したNucleoボードがありましたので、これを使って実験してみましょう。
(※本記事は株式会社コンピューテックスのホームページより転載したものです。)
準備するもの
準備するものを列挙します。
- NUCLEO-F334R8(STマイクロエレクトロニクス製開発ボード)
- STM32CubeIDE v1.4.2(統合開発環境)
- PALMiCE4(コンピューテックス製JTAG-ICE)
- USBケーブル(電源供給用)
- パソコン
- ドキュメント類
NUCLEO-F334R8はSTM32F334R8(Arm Cortex-M4、64KBフラッシュ・メモリ、16KB RAM)を搭載したボードです。コンパイラと統合開発環境は、STマイクロエレクトロニクスからダウンロードできるSTM32CubeIDEを使用し、動作確認用のJTAG-ICEとしてPALMiCE4を使用します。このボードにはJTAG-ICEの機能が搭載されているのですが、PALMiCE4のリアルタイム・モニタ機能を使って、ADコンバータの値を「見える化」したいと思います。
STM32CubeIDEをインストールする
STM32CubeIDEはEclipseベースの統合開発環境で、STマイクロエレクトロニクスのホームページから無料でダウンロードできるようになっています。「stm32cubeide」で検索すればダウンロードサイトにたどり着けると思います。
ダウンロードするためにはユーザー登録を行い、ライセンス契約に同意する必要があります。ダウンロードが完了すればzipファイルを展開し、EXEを実行してインストールします。なお、今回ダウンロードしたバージョンは1.4.2でしたので、このバージョンで以降の説明を行います。
最近のEclipseベースの開発環境は素晴らしく良くできていて、使用するリファレンスボードやチップを選択するだけで、初期化ルーチンをすべて生成してくれます。ペリフェラルの初期化もGUIでできるようになっていますし、さらに、ペリフェラルにアクセスするためのAPIがソース提供されていますので、I/Oを直接制御する必要がありません。
STM32CubeIDEの起動
それでは早速STM32CubeIDEを起動します。最初にワークスペースのフォルダを入力します。
起動するとInformation Centerの画面が表示されますので、「Start new STM32 project」ボタンを押して新規プロジェクトを作成します。
「Board Selector」を選択します。
検索フィールドで「NUCLEO-F334R8」と入力すれば、該当ボードが表示されますので、選択して「Next」ボタンを押します。
プロジェクト名は「adc」と入力しておきます
後の質問にはYESと答えておけば、たぶん問題ありません。しばらく時間がかかりますが、最終的に以下の画面が表示されれば終了です。
デバイスのコンフィグレーション
ここからは「Device Configuration Tool」を使ってペリフェラルの設定を行います。と、言ってもADコンバータの設定だけで、後はデフォルトでOKです。
最初に「Analog」をクリックして展開し、「ADC1」を選択します。ADCはADC1とADC2の二つありますが、内蔵温度センサはADC1のIN16に接続されていますのでADC1を選択します。
次に「Temperature Sensor Channel」にチェックを入れます。これをチェックすることで内蔵温度センサをADコンバータに割り当てるための初期化コードが出力されます。
次は下側の設定項目を変更します。「Continuous Conversion Mode」を「Enable」にします。これでADコンバータが継続して動作します。
内蔵温度センサを使うための設定作業は以上です。意外にシンプルでした。そして、ファイルの保存ボタンを押す、または[Ctrl]+[s]を押すことで、コード生成が行われます。
ご覧のようにソースコードが表示されればOKです。
ソースコードを眺めてみる
実際にどんなコードが出力されているのか確認してみます。ADCの初期化らしき関数、MX_ADC1_Initを見ると、先ほど設定したContinuousConvModeがEnableになっていて、HAL_ADC_Init関数で初期設定が行われているようです。
ソースコードを見ると「hadc1」という変数を利用してパラメータを設定していますが、今後のADC1のアクセスはhadc1を使用することになります。
もう少し下にはチャネルの設定が行われています。ここでは温度センサをHAL_ADC_ConfigChannel関数でチャネル登録しています。
内蔵温度センサの読み出し
この段階では初期化が完了しただけで、内蔵温度センサの値はまだ読み出せていません。ADCの値を読み出すにはポートを直接読み出してもいいのですが、ペリフェラルアクセスの豪華なAPIが用意されていますので、それを利用します。実際、その方が細かいことを注意しなくて済みます。
まず、メインループとなる読み出しを繰り返すための関数を一つ用意します。名前は「adc_test」としておきます。この関数では以下の処理を行います。
- ADCのスタート
- ADCの変換待ち
- ADCの値を読み出す
実際にコードを書くとこのようになります。エラー処理は省略しています。
それぞれのAPIを簡単に説明しますと以下のようになります。
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
指定されたADCの変換を開始します。
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
指定されたADCの変換を待ちます。タイムアウト時間を指定することもできます。
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
指定されたADCの値を読み出します。
各APIは引数にhadcを指定することでADCのパラメータを渡すことができます。ADCの値の読み出しにはHAL_ADC_GetValueを使用しますが、STM32F334のADCは12ビットの分解能となっていますので、アナログ値をデジタル値に変換して0~0xFFF(0から4095)の範囲で値が返ってきます。
あとはmain関数からadc_test関数を呼び出すのを忘れないようにします。
これでとりあえずビルドして動作を確認してみましょう。STM32CubeIDEでハンマーのアイコンを押してビルドを行います。
ST-LINKで動作確認する
ビルドが正常に終了すれば、いよいよADCの値を確認してみましょう。プログラムの動作確認はST-LINKを使って行います。準備はNucleoボードにUSBケーブルをつなぐだけで電源も不要です。
デバッグを行うためにSTM32CubeIDEの虫(Debug)ボタンを押すと、デバッガの設定画面が表示されますので、デフォルト設定のままOKボタンを押します。
ウィンドウがデバッガの構成に切り替わり、main関数で停止します。
ここで先ほどの「adc_test」を表示させ、変数「gu_temp」の代入行にブレークを設定して値を確認してみます。ブレークの設定は行番号をダブルクリックします。
緑三角(Resume)ボタンでプログラムを実行し、マウスカーソルをgu_tempの上に持っていって値を確認します。
何度か実行を繰り返すと700前後の値となっているようですが、この値はアナログ電圧をデジタル変換した値です。このボードでは3.3Vの電圧が供給されていますので、3.3を12ビットの最大値(4096)で割った値が、測定値の1に相当します。つまり、測定値が700の場合、
さらに内蔵温度センサに関するドキュメントを探したところ以下の数式のVTSに当てはめれば温度が求まるとのことです。
V25とAvg_Slopeはの値は別のドキュメントより、V25 = 1.43、Avg_Slope = 0.0043ということが判明しています。つまり、測定値700とした場合、
いやいや、ありえないでしょ。
何か設定ミスがないか試行錯誤する中で、サンプリングタイムがデフォルトの設定では問題となることが判明しました。ドキュメントによると、温度センサのADCの読み出しは2.2μsより大きい間隔を取る必要があります。デフォルトでは1.5 Cyclesなので、ADCクロック(64MHz)の1.5倍ですから、
と、なり2.2μsよりも短い間隔となっています。この間隔はADCの「Sampling Time」で設定しますが、2.2μs以上に設定するには140.8サイクル以上の設定が必要になります(たぶん)。では、再度STM32CubeIDEに戻って設定を行います。左側のツリーの「adc.ioc」をダブルクリックすれば設定画面に切り替わりますので、ADC1のSampling Timeを「601.5 Cycles」と余裕のサイクル数に変更して保存します。
ついでに、ADCの精度を上げるため、以下の行を追加してキャリブレーション(校正)もやっておきましょう。これはHAL_ADC_Startの前にやる必要があります。
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
ビルドして実行すると1753~1755の値が返ってきました。これを温度に変換すると29.1℃という値になります。若干高めな気はしますが、何となく納得できる値になりました。実際にはセンサの個体差により誤差がありますので、校正データを使う必要があるのですが、本題からズレますのでここはスキップします。
PALMiCE4でADCを見える化
一応、温度データを取得することはできましたが、このデータがどんな傾向になっているのか見える化したいと思います。PALMiCE4のリアルタイム・モニタ機能を使えば、変数値をリアルタイムにグラフ化できますので、データの傾向を確認するには持ってこいです。
それでは早速、PALMiCE4を接続して起動してみましょう。NucleoボードのSWDピンに直接接続するプローブを使用します。
STM32CubeIDEのデバッグモードが有効になっているとまずいので、ツールバーの赤い四角のボタンを押して終了させておいてください。
CSIDEを起動する
ここからはPALMiCE4のデバッガソフト「CSIDE」がインストールされている前提で進めますのでご了承ください。スタートメニューよりCSIDEを起動し、[設定]メニューの[ターゲットシステムの設定]を選択すると、CPUの選択画面が表示されます。ここで、[CPU検索]を押してフィルタに「334」と入力すれば「STM32F334x8」が表示されますので選択します。
この画面で[起動する]ボタンを押します。
次はCPUの初期設定を行います。初期値の設定ボタンを押します。
設定項目は2箇所です。[PC,SPの初期値をベクタ空間より取得する]と[内蔵フラッシュ・メモリの書き込みに専用モニタを使用する]にチェックを入れOKを押します。
更新ボタンを押すことで起動が完了します。
オブジェクトファイルのダウンロード
さて、次はビルドしたオブジェクトファイルをダウンロードします。ツールバーの一番左にある[ファイルロード]のボタンを押して、ファイルを選択します。STM32CubeIDEでビルドしたDebugのフォルダにある「adc.elf」を選択し、追加ボタンを押します。
ご覧のようにオブジェクトファイルが登録されますので、ダウンロードボタンを押します。
リアルタイム・モニタの登録
では、ここからいよいよリアルタイム・モニタを使用します。まず[表示]メニューより[リアルタイム・モニタ]を選択してウィンドウを開き、追加ボタンを押して表示したい変数を登録します。
変数の登録では、ADCの値を読み出した変数「gu_temp」を登録します。表示に関しては色々と細かい設定が可能ですが、以下のように設定しました。
変数の登録が完了すれば、ウィンドウの左上のチェック[RTMを有効にする]をチェックします。
プログラムの実行ボタンを押すと、プログラムが走り出し、同時にリアルタイム・モニタのウィンドウにグラフが表示されます。上下の振れ幅が少ないので、ただの線になっています。
CTRL+マウスホイールをぐりぐり回すと、縦軸の拡縮ができますので拡大してみましょう。
こんな感じで微小な変化を繰り返していることが分かりました。では、今度は横軸を拡大してみましょう。CTRLを押さずにマウスホイールをぐりぐり回すと横軸の拡縮ができます。
拡大するとなんとなくそれっぽい感じになりました。下側のウィンドウにはリードした値の最大値と最小値が表示されています。これを見れば1740~1753の間で変化していることが分かります。
内蔵温度センサなので温度が変化するか見てみましょう。チップを人肌で温めてみます・・・。
・・・何も変化しません。まあ、当たり前と言えば当たり前ですが(つまらん)。
と、いうことで次回は、もう少しADCが変化するもので試したいと思います。
今回の続きは…
今回の内容をベースに、外部からアナログ入力してADコンバータの変化を見る「STM32マイコンでアナログ入力(第2回)~別の素子でADCを試してみよう~」は、コンピューテックス社のWebサイトで公開中です。是非ご覧ください!
JTAGエミュレータ PALMiCE4
Cortex-M系からCortex-A系までの最新のArmチップに対応した高機能JTAGエミュレータ「PALMiCE4」。システムを稼働させた状態でのデバッグを実現する「リアルタイム・モニタ機能」や「ホットプラグイン・デバッグ機能」、難しいバグの解析が行なえる「トレース機能」など、様々な機能でスムーズなデバッグを徹底追及、問題の早期解決を実現します。また、マルチコアCPUにも対応しており、同期実行や同期ブレーク、コアごとの実行状態を監視するステータス表示機能など、これ1台でスムーズなマルチコア・デバッグを実現します。
- CSIDEに関する著作権は(株)コンピューテックスに帰属します。
- CSIDE、PALMiCEおよびCOMPUTEXは、(株)コンピューテックスの登録商標です。
- その他本記事で取り上げる会社名および製品名などは、一般に各メーカーの商標、または登録商標です。
【免責事項】
- 本記事は当社の独自の調査によるものであるため、誤った内容が含まれる場合があります。
- 本記事のソフトウェア、ハードウェア、ホームページなどのバージョン及び内容は執筆時のものです。
- 本記事の内容によって発生した損害や結果について、当社は一切の責任を負わないものとします。