演習課題のプログラム例

まず、どのカウントソースでカウントアップするか、また1秒間という長い周期なので、どのくらいの周期で割り込みを発生させるかを計算することから始めます。私の場合は200μsecごとに割り込みを発生させてみます。(この200μsecという周期はPUPPYのサンプルプログラムで使用しています。)

まず分周比を選びます。タイマB1は表1のように分周比を選択でき、タイマカウンタは システムクロック/分周比 でカウントアップします。

φ(20MHz) φ/ 8192 2441.406 Hz
φ/ 2048 9765.625 Hz
φ/ 512 39062.5 Hz
φ/ 256 78125 Hz
φ/ 64 312500 Hz
φ/ 16 1250000 Hz
φ/ 4 5000000 Hz

表1

タイマB1は8ビットのタイマですのでカウンタ値は0から255までカウントしてオーバフローします。このカウンタは0からカウントアップするだけではなくタイマロードレジスタ(TLB1)に値を入れると、その値からカウントアップさせることもできます。分周比とカウンタの初期値をさまざまに変化させることで比較的自由度の高い割り込み周期を作ることができます。

今回は分周比をφ/16にして

   20MHz / 16 = 1250kHz(カウントアップ周期0.8μsec)

これを200カウントすると

   0.8μsec × 250(カウント) = 200μsec

になります。200カウントさせるにはオーバフローが256なので

   256 - 250 = 6

タイマの初期値に6を入れるといいことになります。

上記の設定を踏まえてプログラム例をリスト1,リスト2に表示します。

リスト1 main.c(抜粋)

16行目: タイマモードレジスタ(TMB1)のビット7をセットして自動的にタイマロードレジスタ(TLB1)の値をタイマカウンタ(TCB1)に代入するようにする。ビット2〜0で分周比を設定する(φ/16→101)

17行目: タイマロードレジスタに6を入れる タイマロードレジスタとタイマカウンタは同一アドレスに割り当てられていて書込みはTLB1に、読み出しはTCB1から行われる。

20行目: 割り込みイネーブルレジスタ2(IENR2)のIENTB1ビットをセットしてタイマB1カウンタオーバフロー割り込み要求を発生させる。

22行目: すべての割り込み要求を受け付けるようにする。

26,29行目: 1秒ごとにセットされるフラグがセットされるまでループ

92行目: タイマB1オーバフロー割り込み時にはINT_Timerb1関数が呼び出される。タイマB1の設定により、今回の場合は200μsecごとに呼び出される。

96行目: 100行目で関数が呼び出されるごと(200μsecごと)にtb1_countがデクリメントされるので関数呼び出しの5000回に1回if文の中に入る。

98行目: main関数で使用するFlagをセットする。5000×200μ = 1秒でFlagがセットされる。

102行目: 割り込み要求をクリアする。クリアしないと割り込み要求が取り下げられないのでタイマB1オーバフロー割り込みが発生し続ける。

リスト2 init.c(抜粋)

一定周期を作る編 終了