======Exercise4 タイマー割り込み======
注意
タイマー割り込みを実行するためには**interrupt_handlers.c**の385行目あたりを以下のように書き換えてください(HEWであればintprg.cに載っています)
void interrupt_cmt0(void);
#pragma interrupt INT_CMT0_CMIO
void INT_CMT0_CMI0(void){
interrupt_cmt0();
}
ただし、e2studioを使っている場合は、次のとおり書き換えてください。
void interrupt_cmt0(void);
void INT_CMT0_CMI0(void){
interrupt_cmt0();
}
また、**reset_program.c**の21行目のSR_Initの0x000000F0を0x00000000にしましょう。
さて、**タイマー割り込み**とは何でしょう。
今まで書いてきたプログラムは、上から下まで順に実行する(サブルーチンはその通り飛ぶとして)ものです。
これが出来ればライントレースも大分近くなります。
頑張りましょう!
例えれば、 -Aさんと話す→(話し終わる)→Bさんと話す
というようなものです。とりあえずひとつづつ消化しなくてはいけません。
これが割り込みというシステムを使うと、
-Aさんと話す→Bさんが話しかけてくる→Aさんに待ってもらう→Bさんと話す→(話し終わる)→Aさんとの話の続きをする
と言う感じになります。
プログラム的には、main文で「Aさんと会話」、割り込み文で「Bさんと会話」と言う感じです。
つまり、同時に色々なことをしたいときに良く使うものです。
例のように「Bさんが話しかけてくる」というような
何かのアプローチがあって割り込みが入る場合もありますが
今回は、時間で割り込みをかけてみたいと思います。
1msごとに指定された割り込み文を実行する、などと言うことです。
まず、時間を使って割り込む事をタイマー割り込みといいます。
タイマー割り込みをつかうには、初期設定が必要です。
main文の上のほうに1msで割り込むCMTの初期設定を以下のように書きます。
void initCMT(void) //CMT割込の設定
{
STB.CR4.BIT._CMT = 0;//CMTスタンバイ解除
// (1)コンペアマッチタイマスタートレジスタ(CMSTR)
CMT.CMSTR.BIT.STR0=0;// ステータスレジスタ 0:カウント停止, 1:カウント開始
// (2)コンペアマッチタイマコントロール/ステータスレジスタ(CMCSR)
CMT0.CMCSR.BIT.CMIE = 1; //割り込みイネーブル許可
CMT0.CMCSR.BIT.CKS = 0; //1/8
CMT0.CMCSR.BIT.CMF = 0; //フラグをクリア
CMT0.CMCOR = 5000; //割り込み周期
INTC.IPRJ.BIT._CMT0 = 0xf;//割り込み優先度(15)
}
この初期設定は**initCMT**という関数に収められています。この関数をmain文の最初のほうで呼び出しましょう。\\
なぜ関数に初期設定を収めたというと、main文にまとめて初期化の文を書いてしまうと分かりにくくなってしまうためです。\\
実際にCMTを動かすためには割り込み時に実行するプログラムを書く必要があります。\\
では、割り込む関数を定義してみましょう。
void interrupt_cmt0(){//割り込む関数
CMT0.CMCSR.BIT.CMF = 0;//フラグクリア
//中身
}
これで、割り込む関数を定義することができました。\\
ここまでできたらCMT割り込みが使えると思います。\\
以前まではLEDの点滅をきっかり1秒にするということは難しかったと思います。\\
CMTを使用することで1秒きっちりを測れるようになります。\\
そこで、今回は**LEDが1秒置きに点滅を繰り返す**ということしてみましょう。\\
たぶん、最初は1秒置きには点滅してくれないかもしれません。\\
ヒントはCMTの初期設定のCMCORの部分です。\\
CMCORとはCMTの割り込み周期を変更できるレジスタで、式は以下のようになります。\\
**割り込み周波数:周辺動作クロック/CKSで設定した分周比**\\
これで割り込む周期を設定できます。1msくらいがいいと思います。\\
データシートを見たり、周期と周波数の関係を思い出しながら実際に計算をしてみましょう。\\