前回はADからDAへの「垂れ流し」ポーリング方式を勉強させていただきました。今回は割り込み方式です。そんな悠長に刻んでいたら死ぬまでに読み終わらない、とも思ったのですが、ちょっと立ち止まってSTM32F446REのハードを確認しておくことにいたしました。ロウレベルなところが気になると夜も眠れませぬ。
※「手習ひデジタル信号処理」投稿順 Indexはこちら
拝読させていただいております、三上直樹先生著の『「Armマイコン」プログラムで学ぶデジタル信号処理』なのでありますが、本文中にはADやらDAやらをどう制御するとかいう話はほとんど出てきません。付録のPDFに書いてあるのかと思って見にいくと書いてありました。1行引用させていただきます。
「マイコン」に内蔵する「AD 変換器」と「タイマ」の設定方法については、脚注の書籍1で詳しく説明しているので、この付録では説明を省略します。
脚注にかかれてある書籍は、『三上直樹:「Mbed を使った電子工作プログラミング」、工学社、2020 年』であります。そこは別なご本を買って読んでね、という感じ。一瞬、注文だそうかとも思ったのですが思いとどまりました。すみません。STM32についてはF401REとかF072RBとか過去にやった経験あり「土地感」がないわけでもないのです(それらのマイコンの資料は手元にダウンロード済でチラチラ読んではいました。)ST社から、今回使っているF446関係の資料をダウンロードして確認しておけばよかろう、ということでお茶を濁してしまいました。
さて、STMicroelectronics社の関係資料のダウンロード先は以下です。
上記のページは日本語ですが、ダウンロードできるPDF資料はあらかた英文です(一部日本語資料もあります。)
基本、STM32F446シリーズのデータシートはまず必要かと思いますが、今回の目的にはデータシートだけでは不足です。リファレンスマニュアルの方が必要です。データシートにはどの型番(F446でも機種は多い)のマイコンに何が何個といった情報は書かれていますが、各ペリフェラルの詳細などは書かれてません。詳細はリファレンスマニュアルに書かれています。上記のページには他にも役立ちそうな資料がいろいろ掲載されています。充実。とりあえずF446のデータシートと、RM0390という文書番号のリファレンスマニュアルをダウンロードいたしました。
ADからDAへの手順(割り込み方式の場合)
ADからアナログ値を読み取って、DAに書き込んで出力させるための手順はかいつまむと以下の通りです。
- タイマのトリガを使ってADCの変換を開始させる
- ADCの変換完了で割り込みを発生させる
- 割り込みサービスルーチンが呼び出される
- 割り込みサービスルーチンの中でADCの変換済の値を読み出し、その値をDACに書き込む
タイマにサンプリング周波数の時間間隔でトリガが引かれるようにセットしておけば、目出度くADからDAにデータが垂れ流されることになります。
さて、STM32F446のデータシートおよびリファレンスマニュアルを読むと、なんとタイマは14本も搭載されていることが分かります。これまた充実。タイマによっては1本のタイマの中にCapture/Compareを4チャネルとか持っているので、タイマからのトリガに使えそうな信号の候補は多数あることが分かります。
一方、ADコンバータ(12ビット)は3本の搭載です。3本の搭載ですが、チャネル数は16あるようです。これは1本のADを無駄なく使えるように、複数の端子(チャネル)を切り替えて接続できるようになっているためです。今回は1本のADを1チャネルで占有だと思います。
ADの変換開始をトリガできるタイマ出力は1本のADコンバータにつき、32本もあり、マルチプレクサで選択できます。使えるタイマを列挙するとTIM1,2,3,4,5,8です。それらタイマの一部のチャネルなどがトリガを引くことができます。タイマは全部でTIM1からTIM14まであるので、そのうちの6本のみがADCの制御に使えるわけです。しかし、合計32本のトリガ線は16本づつ2系統にさらに分かれています。1本のADCの変換結果を格納するためのレジスタに regular groupとinjected groupの2系統があるためです。ぶっちゃけ、CPUがADCの変換結果を読み出すまで、ADCを遊ばせておくのは勿体ないので、表と裏の2セットを用意しておき、表を見せている間に、裏に変換しておく、といった技に使われるのではないかと。ただし、今回のような程度の速度では余裕があるので、2つも使わないで済むようです。
今回のコードではTIM8が使われていました。TIM8は Advanced-control timerとよばれるゴージャスな16bitタイマです。カウンタ1本にCapture/Compareが4本ぶらさがる、あちこちのMCUで「よく見る」構造です。当然Capture/Compareの各CHの出力をADCのトリガにつかえます(ただしCHによりregularだったり、injectedだったりキメウチです。)しかし、ここではCH出力ではなくTRGOという「他の回路をトリガするための専用の信号」を使っていました。これまたアクティブになる条件をいくつも設定できるのですが、使っているのはカウンタがUpdateされたときにトリガが引かれるモードです。
ようやく割り込み方式のプログラムで実験
動作の背景がホンワカ分かった気がしたので、ご本のとおりにプログラムを入力して動作させてみました。例によってArm社のMbedウエブ環境を利用です。なお、今回からNucleoに接続している「外付け回路」は基板上にハンダづけしたものに変更しています(先頭のアイキャッチ画像のもの。)「貴重な」ブレッドボードを解放するとともに、ハンダ付けの練習用です。タマにちょこっとやってるくらいじゃ、いまさら上手にはなりませんが。
まずは、1kHzの正弦波を入力したものがこちら。黄色が入力、青が出力です。出力は「予定どおり」LPFしきれずに「ちょっと」ガタガタな波形になっています。これが次回になったら直るという期待。
試みに入力3.5kHzにあげてみたのがこちら。サンプリング周波数10kHz、ナイキスト周波数5kHzなんだけれども。なんか「うなっている」感じ。大丈夫か。
一応ポーリング方式のオブジェクトでも見てみました。前回作成の出力振幅半分の版。やっぱり唸っている感じ。次回どうなることか。