練習プログラム3

「練習プログラム3」の編集履歴(バックアップ)一覧はこちら

練習プログラム3」(2011/05/19 (木) 16:16:59) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

<p>前回のプログラムでは,wait()関数を用いてあまり正確でない遅延を行うプログ ラムを書きました.<br /> 今回は,マイコンのタイマ機能を使って,より正確な時間を待つプログラムを作成 します.</p> <p>H8/3694では,『タイマA』,『タイマV』,『タイマW』の三種類のタイマ機能が 存在します.<br /> 今回はその中でもインターバル/時計用のタイマである,『タイマA』を使います.<br /> なお,ブリーフケースに上がっているプログラムとは使い方が若干違いますが,基 本的にはやってることは同じです.</p> <h5>練習プログラム③ 『タイマAを使い,LEDを3秒間だけ全点灯』</h5> <pre> #include &lt;3694.h&gt; /*-----------------------------------------------*/ /* 指定ms待つ関数 */ /*-----------------------------------------------*/ void ms_wait(unsigned int ms) { //====指定msループ==== while(ms--) { //====TMA設定==== TA.TMA.BYTE = 0x1c; //Clear TCA TA.TMA.BYTE = 0x13; //PSS, 入力クロックφ/512 while(TA.TCA &lt; 39); //約1ms待つ. } } /*-----------------------------------------------*/ /* メイン関数 */ /*-----------------------------------------------*/ void main() { IO.PCR8 = 0xff; //Port8をすべて出力に設定. IO.PDR8.BYTE = 0x00; //LED全点灯. ms_wait(3000); //3秒待つ. IO.PDR8.BYTE = 0xff; //LED消灯. } </pre> <p> </p> <h5>・プログラムの解説</h5> <p>今回のプログラムでは,特にms_wait()関数が加わった他は分かるかと思います .<br /> この練習プログラムの題材どおり,LEDを始めに点灯させた後,3秒間だけms_wait() 関数を使って待ち,<br /> その後LEDを全消灯にします.</p> <p>このプログラムではタイマAのインターバル機能を使っています.<br /> 本来、正確に一秒待つなどの用途はタイマAの時計用タイムベース機能のほうが適し ているのでしょうが,このプログラムでは,<br /> マイクロマウスで使用するときに使いやすいインターバル機能を用いて解説します .<br /> (とはいえ,今回はそれによる割り込みや出力は行いません.)<br /> 余力があれば時計用タイムベース機能についても後述します.</p> <p>さて,ms_wait()関数の中を見て行きたいと思います.<br /> まず,(引数からもらった数値)回だけwhile構文で中の命令を繰り返すようになっ ています.<br /> つまり,while構文の中に約1[ms]待つようなプログラムが書かれており,それを whileで指定分だけ繰り返すことにより,<br /> 指定されたms待つことになります.</p> <p>whileの中について見ていきます.<br /> まず,最初にタイマカウンタA(TCA)をクリア(値を0に設定)します.<br /> TCAは,リード可能なレジスタであり,直接ライトすることが出来ないので,間接的 にクリアしなくてはなりません.<br /> そこで,ハードウェアマニュアルに書いてあるとおりにタイマモードレジスタA (TMA)を使いクリアします.<br /> TMAの3Bit目(TMA3)~2Bit目(TMA2)をそれぞれ1に設定することにより,TCAはク リアされます.<br /> また,4ビット目がリザーブビットで常に1を返すことから,一応書き込むときも1を 書き込んでおきましょう.</p> <pre> TA.TMA.BYTE = 0x1c; </pre> <p>これにより,TCAはH'00にクリアされるはずです.</p> <p>次に,タイマAの機能を設定していきたいと思います.<br /> 今回は,インターバル動作なので,TCAへの入力源をプリスケーラS(PSS)とし, φ/512としてカウントします.<br /> PSSとは,システムクロック(φ)を入力クロックとする13ビットカウンタで, その出力は周辺モジュールの内部クロックとしてしようされます.<br /> つまり,今回はシステムクロックφ(20MHz)を1/512に分周したクロックをTCAの 入力としてタイマのカウント動作を行います.<br /> さて,それではそのように動作するように設定を行います.設定にはTMAを用います .<br /> まず,今回はTMOW出力は使用しないので,TMAの上位3Bit(TMA7~TMA5)は0にしま す.<br /> 4Bit目はリザーブビットなので,1とします.<br /> プリスケーラSを使用するので,3Bit目(TMA3)は0とします.<br /> φ/512をTCAへの入力クロックとするので,2Bit目(TMA2)~0Bit目(TMA0)は B'011となります.<br /> 以上をまとめると,次のようになります.</p> <pre> TA.TMA.BYTE = 0x13; </pre> <p> これにより,周波数20/512[MHz]でTCAがカウントされていきます.</p> <p>さて,では1[ms]待つように少し計算しましょう.<br /> 20/512[MHz]を周期に直すと,2.56x10<sup>-5</sup>[s] = 2.56x10<sup>-2</sup> [ms]です.<br /> つまり,TCAは2.56x10<sup>-2</sup>[ms]周期でインクリメントされることになりま す.<br /> そのため,カウントを39回繰り返すと,<br /> 2.56x10<sup>-2</sup> x 39 = 0.9984[ms]<br /> となり,およそ1[ms]とすることが出来ます.<br /> 故に,TCAが39になるまで待てば,そこでおよそ1[ms]待つことができます.</p> <pre> while(TA.TCA &lt; 39); </pre> <p> これで,TCAが39になるまで待ち続けることができます.<br /> (設定次第では他の割り込み動作は当然入ります)</p> <h5>・レジスタ解説(詳細はハードウェアマニュアル参照)</h5> <p><strong>タイマモードレジスタA(TMA) アドレス:H'FFA6<br /></strong>タイマAの動作モードの選択,分周クロック出力,入力クロックの設定を 行います.<br /> TMA7~TMA5:アウトプットセレクト(TMOWからの出力設定)<br /> TMA3:インターナルクロックセレクト(タイマA動作モード選択≒プリスケーラ選択 )<br /> TMA2~TMA0:インターナルクロックセレクト(分周比,またはTCAオーバーフロー周 期選択)</p> <p><strong>タイマカウンタA(TCA) アドレス:H'FFA7</strong><br /> 8Bitのリード可能なアップカウンタです.ライトはできません.<br /> オーバーフロー時に割り込みフラグレジスタ(IRR1)のIRRTAがセット(1になる)さ れます.<br /> オーバーフローすると,TCAは値がH'00に戻り,再びカウントアップされていきます .<br /> TMAのTMA3及びTMA2をセットすることでTCAはH'00にクリアされます.</p> <p> </p> <p>課題プログラム③ 『LEDをきっちり1秒置きに全点滅させよ』</p>
<p>前回のプログラムでは,wait()関数を用いてあまり正確でない遅延を行うプログ ラムを書きました.<br /> 今回は,マイコンのタイマ機能を使って,より正確な時間を待つプログラムを作成 します.</p> <p>H8/3694では,『タイマA』,『タイマV』,『タイマW』の三種類のタイマ機能が 存在します.<br /> 今回はその中でもインターバル/時計用のタイマである,『タイマA』を使います.<br /> なお,ブリーフケースに上がっているプログラムとは使い方が若干違いますが,基 本的にはやってることは同じです.</p> <h5>練習プログラム③ 『タイマAを使い,LEDを3秒間だけ全点灯』</h5> <pre> #include &lt;3694.h&gt; /*-----------------------------------------------*/ /* 指定ms待つ関数 */ /*-----------------------------------------------*/ void ms_wait(unsigned int ms) { //====指定msループ==== while(ms--) { //====TMA設定==== TA.TMA.BYTE = 0x1c; //Clear TCA TA.TMA.BYTE = 0x13; //PSS, 入力クロックφ/512 while(TA.TCA &lt; 39); //約1ms待つ. } } /*-----------------------------------------------*/ /* メイン関数 */ /*-----------------------------------------------*/ void main() { IO.PCR5 = 0xff; //Port8をすべて出力に設定. IO.PDR5.BYTE = 0x00; //LED全点灯. ms_wait(3000); //3秒待つ. IO.PDR5.BYTE = 0xff; //LED消灯. } </pre> <p> </p> <h5>・プログラムの解説</h5> <p>今回のプログラムでは,特にms_wait()関数が加わった他は分かるかと思います .<br /> この練習プログラムの題材どおり,LEDを始めに点灯させた後,3秒間だけms_wait() 関数を使って待ち,<br /> その後LEDを全消灯にします.</p> <p>このプログラムではタイマAのインターバル機能を使っています.<br /> 本来、正確に一秒待つなどの用途はタイマAの時計用タイムベース機能のほうが適し ているのでしょうが,このプログラムでは,<br /> マイクロマウスで使用するときに使いやすいインターバル機能を用いて解説します .<br /> (とはいえ,今回はそれによる割り込みや出力は行いません.)<br /> 余力があれば時計用タイムベース機能についても後述します.</p> <p>さて,ms_wait()関数の中を見て行きたいと思います.<br /> まず,(引数からもらった数値)回だけwhile構文で中の命令を繰り返すようになっ ています.<br /> つまり,while構文の中に約1[ms]待つようなプログラムが書かれており,それを whileで指定分だけ繰り返すことにより,<br /> 指定されたms待つことになります.</p> <p>whileの中について見ていきます.<br /> まず,最初にタイマカウンタA(TCA)をクリア(値を0に設定)します.<br /> TCAは,リード可能なレジスタであり,直接ライトすることが出来ないので,間接的 にクリアしなくてはなりません.<br /> そこで,ハードウェアマニュアルに書いてあるとおりにタイマモードレジスタA (TMA)を使いクリアします.<br /> TMAの3Bit目(TMA3)~2Bit目(TMA2)をそれぞれ1に設定することにより,TCAはク リアされます.<br /> また,4ビット目がリザーブビットで常に1を返すことから,一応書き込むときも1を 書き込んでおきましょう.</p> <pre> TA.TMA.BYTE = 0x1c; </pre> <p>これにより,TCAはH'00にクリアされるはずです.</p> <p>次に,タイマAの機能を設定していきたいと思います.<br /> 今回は,インターバル動作なので,TCAへの入力源をプリスケーラS(PSS)とし, φ/512としてカウントします.<br /> PSSとは,システムクロック(φ)を入力クロックとする13ビットカウンタで, その出力は周辺モジュールの内部クロックとしてしようされます.<br /> つまり,今回はシステムクロックφ(20MHz)を1/512に分周したクロックをTCAの 入力としてタイマのカウント動作を行います.<br /> さて,それではそのように動作するように設定を行います.設定にはTMAを用います .<br /> まず,今回はTMOW出力は使用しないので,TMAの上位3Bit(TMA7~TMA5)は0にしま す.<br /> 4Bit目はリザーブビットなので,1とします.<br /> プリスケーラSを使用するので,3Bit目(TMA3)は0とします.<br /> φ/512をTCAへの入力クロックとするので,2Bit目(TMA2)~0Bit目(TMA0)は B'011となります.<br /> 以上をまとめると,次のようになります.</p> <pre> TA.TMA.BYTE = 0x13; </pre> <p> これにより,周波数20/512[MHz]でTCAがカウントされていきます.</p> <p>さて,では1[ms]待つように少し計算しましょう.<br /> 20/512[MHz]を周期に直すと,2.56x10<sup>-5</sup>[s] = 2.56x10<sup>-2</sup>[ms]です.<br /> つまり,TCAは2.56x10<sup>-2</sup>[ms]周期でインクリメントされることになりま す.<br /> そのため,カウントを39回繰り返すと,<br /> 2.56x10<sup>-2</sup>x 39 = 0.9984[ms]<br /> となり,およそ1[ms]とすることが出来ます.<br /> 故に,TCAが39になるまで待てば,そこでおよそ1[ms]待つことができます.</p> <pre> while(TA.TCA &lt; 39); </pre> <p> これで,TCAが39になるまで待ち続けることができます.<br /> (設定次第では他の割り込み動作は当然入ります)</p> <h5>・レジスタ解説(詳細はハードウェアマニュアル参照)</h5> <p><strong>タイマモードレジスタA(TMA) アドレス:H'FFA6<br /></strong>タイマAの動作モードの選択,分周クロック出力,入力クロックの設定を 行います.<br /> TMA7~TMA5:アウトプットセレクト(TMOWからの出力設定)<br /> TMA3:インターナルクロックセレクト(タイマA動作モード選択≒プリスケーラ選択 )<br /> TMA2~TMA0:インターナルクロックセレクト(分周比,またはTCAオーバーフロー周 期選択)</p> <p><strong>タイマカウンタA(TCA) アドレス:H'FFA7</strong><br /> 8Bitのリード可能なアップカウンタです.ライトはできません.<br /> オーバーフロー時に割り込みフラグレジスタ(IRR1)のIRRTAがセット(1になる)さ れます.<br /> オーバーフローすると,TCAは値がH'00に戻り,再びカウントアップされていきます .<br /> TMAのTMA3及びTMA2をセットすることでTCAはH'00にクリアされます.</p> <p> </p> <p>課題プログラム③ 『LEDをきっちり1秒置きに全点滅させよ』</p>

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。