MTU2の使い方(その2)
MTU2の使い方 2
MTU2からA/D変換器を起動する
多くの機能を持ったMTU2であるが、もうひとつの代表的な使い方としてA/D変換器の起動がある。
通常のA/D変換器の使い方においては、ソフトウェアからA/D変換器の起動フラグを立て、変換を開始していた。
ここでは、MTU2とA/D変換器の双方の設定をすることにより、MTU2からA/D変換器を起動できることを学ぶ。
仕組み
MTU2からA/D変換器を起動するには
1.MTU2側の設定(コンペアマッチが発生したときに、A/D変換開始のトリガ信号を発生する)
2.A/D変換器側の設定(MTU2からのトリガ信号により、A/D変換を開始する)
二つが必要になる。変換開始を発行する側と、それを受け取る側の双方の設定が必要ということである。
これらについて、順番に説明していく。
MTU2側の設定
MTU2側の設定は、周期タイマのときの設定とほとんど同一である。唯一の違いはコンペアマッチが発生したときにA/D変換トリガを出力するよう設定をすることである。
図1 MTU2チャネル0の概略構成図
上図の①~③までは、周期タイマのときと同じであるが、もう一度簡単に説明する。
①分周比の選択
周辺クロックPφを分周してカウントクロックを作るときの、分周比を選択する。選択はタイマコントロールレジスタ(MTU20.TCR)のビット2~0で行う。
TPSCビットは次のように操作する。
MTU20.TCR.BIT.TPSC = 0; // Pφ/1を選択
②TCNTのクリア条件設定
手順①で選択したクロックによりTCNTはカウントアップするのだが、ジェネラルレジスタの一つと一致したときに0クリアされるように設定することができる。これにより、カウントが一周する周期を決めることができる。
MTU20.TCR.BIT.CCLR = 1; // TGRAのコンペアマッチでTCNTクリア
③ジェネラルレジスタの設定
手順②で使用する、ジェネラルレジスタに値を設定する。設定する値は、カウントクロックを20MHz、カウントする数をN、Nカウントするまでの時間をtとしたときに
カウントクロックに1/64を選択したときは、上のNも1/64となることに注意すること。
さらに、実際にTGRxに設定する値はN-1となることに、注意が必要である。
MTU20.TGRA = 20000 – 1;
④A/D変換器へのトリガ設定
ここではコンペアマッチが発生したときに、A/D変換器に対して変換開始信号(トリガ)を発行する設定を行う。
MTU2のチャネル0の場合、A/D変換器へトリガを発行する経路はいくつかあるが、ここでは最も簡単なTGRAのコンペアマッチによるトリガ発生を例に挙げる。
トリガ発行の設定はタイマインタラプトイネーブルレジスタ(MTU20.TIER)のビット7で行う。
図3 TIERレジスタ
このビットを1にすると、TCNTとTGRAのコンペアマッチが発生したときに、A/D変換器に対して変換開始要求を発行する。
MTU20.TIER.BIT.TTGE = 1; // TGRAのコンペアマッチでA/D変換要求する
⑤MTU2スタート(A/D変換器側の設定が完了していないので、まだMTU2をスタートしてはならない)
以上で必要な設定は終わっているので、続いてMTU2のカウントを開始すればよいのだが、実際にカウントを開始するのはA/D変換器側の設定が完了後にしなければならない。
図4 TSTRレジスタ
カウント開始はタイマスタートレジスタ(MTU2.TSTR)のビット0で行う。
MTU2.TSTR.BIT.CST0 = 1; // MTU2 CH0スタート
以上のような設定により、MTU2により一定周期で自動的にA/D変換開始要求が発行される。
ここまでの設定で、A/D変換開始要求は発行されるようになっているので、続いては開始要求を受け取る側(A/D変換器)の設定を行う。
A/D変換器側の設定
A/D変換器側は、以前学習した手順に加えて、変換開始信号をMTU2から受け取るような設定が必要になる。
復習もかねて、手順を説明する。
①動作モードの設定
SH7085のA/D変換器は、シングルモード、1サイクルスキャンモード、連続スキャンモードがある。
・シングルモードは、1つのチャネルを1回だけ変換する
・1サイクルスキャンモードは、指定されたチャネル全てを1回変換して終了する
・連続スキャンモードは、指定されたチャネルを変換し続ける
ここでは、MTU2から定期的に変換開始要求を受け取るので、シングルモード又は1サイクルスキャンモードを選択する。
図5 ADCSRレジスタ
動作モードの設定はA/Dコントロール/ステータスレジスタ(AD0.ADCSR)のビット4,5で行う。
MEMEsボードのジョイスティックに使用するには、AN0またはAN1単独のチャネルを変換する場合は[00]のシングルモード、AN0とAN1両方を変換する場合は[11]の2チャネルスキャンモードを指定する。
AD0.ADCSR.BIT.ADM = 0; // シングルモード AD0.ADCSR.BIT.ADM = 3: // 2チャネルスキャンモード
②A/D変換するチャネルの選択
変換するチャネルの選択はADCSRレジスタのCHビットで行うが、動作モードによって指定のしかたが違う。
–シングルモードの場合
–2チャネルスキャンモードの場合
MEMEsの場合、ジョイスティックの縦軸がAN0に、横軸がAN1に接続されているので、必要なチャネルを選択する。
AD0.ADCSR.BIT.ADM = 0; // シングルモードで AN0 を変換 AD0.ADCSR.BIT.ADM = 1: // 2チャネルスキャンモードで AN0とAN1を変換
③MTU2等の他の機能モジュールからのトリガイネーブル
MTU2等からのトリガを有効にするには、まずADCSRのTRGEビットを1にする。
AD0.ADCSR.BIT.TRGE = 1; // 他の機能モジュールからのトリガ有効
④トリガ選択
どの機能モジュールからのトリガで、A/D変換を開始するのかを選択する。SH7085のA/D変換器はMTU2の他に、MTU2Sや外部端子からも変換開始することができる。
図6 ADTSRレジスタ
トリガの選択はA/Dトリガセレクトレジスタ(AD0.ADTSR)のTRG0S[3:0]のビットで行う。
ここでは、MTU2のTRGAのコンペアマッチ(TRG0S[3:0] = [0001])を使用する。
AD0.ADTSR.BIT.TRG0S = 1; // MTU2のTRGAコンペアマッチによるトリガ
⑤MTU2スタート
以上の設定により、A/D変換器はMTU2からのトリガを受け取ることができるようになっている。ここでMTU2をスタートすると、設定した周期ごとにA/D変換が開始される。
ユーザプログラムにおいて、毎回A/D変換を開始する必要はなくなり、一定周期ごとに変換結果(ADDRレジスタ)が更新される。
⑥変換結果読み込み
A/D変換中は変換スタートビット(AD0.ADCR.BIT.ADST)が1になっているので、このビットが0の時に変換結果を読み込む。(実際は、変換中にADDRを読み込んでも不具合は生じないようである)
このように変換結果はいつでも読むことができるが、プログラムによっては最新の変換結果だけを読みたい場合もある。そのような場合は、ADFフラグを使用するとよい。
図7 ADSTフラグとADFフラグ
ADF=1を検出したら変換結果を読み込み、ADFをクリアしておくことにより、同じ変換結果を二度読んでしまうことを防ぐことができる。
下記よりワークスペースをダウンロードし、演習を行うこと。
mtu2_2.zip
演習問題
1. TGRAのコンペアマッチにより100ms周期でA/D変換器を起動して、変換結果をHTERMに表示するプログラムを例示する。実際に動作させて、設定や動作をよく理解し、以降の演習の参考にする。
2. ジョイスティックの縦軸(AN0)の変換結果をLCDに表示し続けるプログラムを作成せよ。
- A/D変換器はTGRAのコンペアマッチにより起動し、変換周期は100msとする
- A/D変換器はシングルモードとする
- LCD表示は0-255とする
3. 演習問題2を機能拡張し、AN0とAN1両方の変換結果をLCDに表示するプログラムを作成せよ。
- A/D変換器は2チャネルスキャンモードに設定する
4. TGRAのコンペアマッチによりA/D変換器を起動し、AN0の変換結果によりコンペアマッチ周期を変化させるプログラムを作成せよ。
- コンペアマッチ発生時に圧電スピーカーの出力を反転させて、音を鳴らす機能をつける
- 音の周波数は1kHzを基本とする
- AN0の変換結果をTGRAに加えることにより、周期を変化させる
- AN0の変換結果は10ビットで取得し、これを10倍したものをTGRAに加えるとよい
ヒント
文字コード
パソコンの画面やMEMEsのLCDなどに文字を表示する際に用いられ、各文字に1バイトの値が割り当てられている。
下の表は、文字コード表の一部である。
文字コード | 文字 | 文字コード | 文字 | 文字コード | 文字 | 文字コード | 文字 | 文字コード | 文字 |
---|---|---|---|---|---|---|---|---|---|
0x30 | 0 | 0x40 | @ | 0x50 | P | 0x60 | 0x70 | p | |
0x31 | 1 | 0x41 | A | 0x51 | Q | 0x61 | a | 0x71 | q |
0x32 | 2 | 0x42 | B | 0x52 | R | 0x62 | b | 0x72 | r |
0x33 | 3 | 0x43 | C | 0x53 | S | 0x63 | c | 0x73 | s |
0x34 | 4 | 0x44 | D | 0x54 | T | 0x64 | d | 0x74 | t |
0x35 | 5 | 0x45 | E | 0x55 | U | 0x65 | e | 0x75 | u |
0x36 | 6 | 0x46 | F | 0x56 | V | 0x66 | f | 0x76 | v |
0x37 | 7 | 0x47 | G | 0x57 | W | 0x67 | g | 0x77 | w |
0x38 | 8 | 0x48 | H | 0x58 | X | 0x68 | h | 0x78 | x |
0x39 | 9 | 0x49 | I | 0x59 | Y | 0x69 | i | 0x79 | y |
0x3a | : | 0x4a | J | 0x5a | Z | 0x6a | j | 0x7a | z |
0x3b | ; | 0x4b | K | 0x5b | [ | 0x6b | k | 0x7b | { |
0x3c | < | 0x4c | L | 0x5c | 0x6c | l | 0x7c | | | |
0x3d | = | 0x4d | M | 0x5d | ] | 0x6d | m | 0x7d | } |
0x3e | > | 0x4e | N | 0x5e | ^ | 0x6e | n | 0x7e | ~ |
0x3f | ? | 0x4f | O | 0x5f | _ | 0x6f | o | 0x7f |
LCD_putch(char)関数は、LCDに1文字表示する関数で、引数として表示する文字の文字コードを渡す。
LCD_putch(0x30)とすると、LCDに’0’が表示される。LCD_putch(‘0′)でも同じく’0’が表示される。C言語では、文字をシングルクォーテーションで囲むと、その値は文字の文字コードとなる。(’0’ == 0x30)
以上のことから、変数iが0~9のとき、LCD_putch()関数を使って’0’~’9’の数字を表示するにはLCD_putch(‘0’ + i)とすれば良いことがわかる。