まず、どのカウントソースでカウントアップするか、また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(抜粋)