この文書の現在のバージョンと選択したバージョンの差分を表示します。
exercise4_タイマー割り込みcmt [2015/02/28 06:16] member |
exercise4_タイマー割り込みcmt [2016/03/08 18:58] (現在) member |
||
---|---|---|---|
ライン 1: | ライン 1: | ||
+ | ======Exercise4 タイマー割り込み====== | ||
+ | |||
注意 | 注意 | ||
- | タイマー割り込みを実行するためにはinterrupt_handlers.cの385行目あたりを以下のように書き換えてください(HEWであればintprg.cに載っています) | + | タイマー割り込みを実行するためには**interrupt_handlers.c**の385行目あたりを以下のように書き換えてください(HEWであればintprg.cに載っています) |
<code c> | <code c> | ||
void interrupt_cmt0(void); | void interrupt_cmt0(void); | ||
- | #pragma interrupt INT_CMT_CMTO | + | #pragma interrupt INT_CMT0_CMIO |
void INT_CMT0_CMI0(void){ | void INT_CMT0_CMI0(void){ | ||
interrupt_cmt0(); | interrupt_cmt0(); | ||
ライン 11: | ライン 13: | ||
</code> | </code> | ||
- | さて、タイマー割り込みとは何でしょう。 | + | ただし、e2studioを使っている場合は、次のとおり書き換えてください。 |
+ | |||
+ | <code c> | ||
+ | void interrupt_cmt0(void); | ||
+ | void INT_CMT0_CMI0(void){ | ||
+ | interrupt_cmt0(); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | また、**reset_program.c**の21行目のSR_Initの0x000000F0を0x00000000にしましょう。 | ||
+ | |||
+ | |||
+ | さて、**タイマー割り込み**とは何でしょう。 | ||
今まで書いてきたプログラムは、上から下まで順に実行する(サブルーチンはその通り飛ぶとして)ものです。 | 今まで書いてきたプログラムは、上から下まで順に実行する(サブルーチンはその通り飛ぶとして)ものです。 | ||
ライン 27: | ライン 42: | ||
何かのアプローチがあって割り込みが入る場合もありますが | 何かのアプローチがあって割り込みが入る場合もありますが | ||
今回は、時間で割り込みをかけてみたいと思います。 | 今回は、時間で割り込みをかけてみたいと思います。 | ||
- | 1sごとに指定された割り込み文を実行する、などと言うことです。 | + | 1msごとに指定された割り込み文を実行する、などと言うことです。 |
- | 実際にやってみる | + | |
まず、時間を使って割り込む事をタイマー割り込みといいます。 | まず、時間を使って割り込む事をタイマー割り込みといいます。 | ||
+ | |||
タイマー割り込みをつかうには、初期設定が必要です。 | タイマー割り込みをつかうには、初期設定が必要です。 | ||
- | Coming soon. | + | main文の上のほうに1msで割り込むCMTの初期設定を以下のように書きます。 |
+ | |||
+ | <code c> | ||
+ | |||
+ | 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) | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | この初期設定は**initCMT**という関数に収められています。この関数をmain文の最初のほうで呼び出しましょう。\\ | ||
+ | |||
+ | なぜ関数に初期設定を収めたというと、main文にまとめて初期化の文を書いてしまうと分かりにくくなってしまうためです。\\ | ||
+ | |||
+ | 実際にCMTを動かすためには割り込み時に実行するプログラムを書く必要があります。\\ | ||
+ | |||
+ | では、割り込む関数を定義してみましょう。 | ||
+ | |||
+ | <code c> | ||
+ | |||
+ | void interrupt_cmt0(){//割り込む関数 | ||
+ | CMT0.CMCSR.BIT.CMF = 0;//フラグクリア | ||
+ | //中身 | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | これで、割り込む関数を定義することができました。\\ | ||
+ | |||
+ | ここまでできたらCMT割り込みが使えると思います。\\ | ||
+ | |||
+ | 以前まではLEDの点滅をきっかり1秒にするということは難しかったと思います。\\ | ||
+ | |||
+ | CMTを使用することで1秒きっちりを測れるようになります。\\ | ||
+ | |||
+ | そこで、今回は**LEDが1秒置きに点滅を繰り返す**ということしてみましょう。\\ | ||
+ | |||
+ | たぶん、最初は1秒置きには点滅してくれないかもしれません。\\ | ||
+ | ヒントはCMTの初期設定のCMCORの部分です。\\ | ||
+ | |||
+ | CMCORとはCMTの割り込み周期を変更できるレジスタで、式は以下のようになります。\\ | ||
+ | |||
+ | **割り込み周波数:周辺動作クロック/CKSで設定した分周比**\\ | ||
+ | |||
+ | これで割り込む周期を設定できます。1msくらいがいいと思います。\\ | ||
+ | |||
+ | データシートを見たり、周期と周波数の関係を思い出しながら実際に計算をしてみましょう。\\ |