定周期割り込みとは、文字通り一定の周期で繰り返し発生する割り込みのことです。
その用途は、例えばLEDの点滅やダイナミック点灯、キー入力のチャタリングキャンセル、時間の測定など、決められた周期で処理する必要がある場面で使用します。
ここでは、コンペアマッチタイマを使って、定周期割り込みを発生させる方法を説明します。
2.コンペマッチタイマの構成
まず、コンペアマッチタイマの構成を説明します。
RX220には、4本(4チャンネル)のコンペアマッチタイマ(CMT0,CMT1,CMT2,CMT3)があります。コンペアマッチタイマは、指定した時間経過後に割り込みを発生させるのが主な機能で、マルチファンクションタイマパルスユニット(MTU)のように複雑ではないので、使い方も簡単です。
4本のコンペアマッチタイマは、スタートレジスタを除き、それぞれが下記に示すレジスタで構成されています。('n'はコンペアマッチタイマの番号 0~3)。
- コンペアマッチタイマスタートレジスタ0/1(CMSTR0, CMSTR1)
- コンペアマッチタイマコントロールレジスタ(CMTn.CMCR)
- コンペアマッチタイマコンスタントレジスタ(CMTn.CMCOR)
- コンペアマッチタイマカウンタ(CMTn.CMCNT)
タイマカウンタ(CMTn.CMCNT)は、コントロールレジスタで指定したクロック(PCLK/8~PCLK/512の4種)でカウントする、16ビットのアップカウンタです。スタートレジスタ0/1の STRn が '1' となっている間は繰り返しカウントします。
コンスタントレジスタ(CMTn.CMCOR)は、コンペアマッチの周期、つまり割り込みの周期を決める16ビットのレジスタです。割り込み周期は「(CMCORの値 + 1)×クロックの周期」で決まります。
タイマカウンタはコンスタントレジスタと一致すると0x0000にクリアされ、その時コンペアマッチ割り込みが許可されていれば割り込みが発生します。
スタートレジスタ0/1(CMSTR0, CMSTR1)は、タイマカウンタを動作/停止させるレジスタです。下図のように、CMSTR0がCMT0とCMT1を、CMSTR1がCMT2とCMT3を担当します。
3.定周期割り込みの設定例
下記は、PCLK=20MHzでコンペアマッチタイマ0(CMT0)を使って、タイマクロックをPCLK/8(=2.5MHz,=400nS)とした定周期割り込み設定例です。
下記の例では、割り込み周期は CNTVALUE で決まります。例えば10mS周期で発生させたい場合、10mS÷400nS=25000なので、CNTVALUE は25000となります。
ただし、実際のコンペアマッチ割り込みは、タイマカウンタがコンスタントレジスタと一致した次のクロックで発生するので、1カウント少ない値、つまり24999をセットしておきます。
void init_CMT0(void)
{
SYSTEM.PRCR.WORD = 0xA502;
MSTP(CMT0) = 0;
SYSTEM.PRCR.WORD = 0xA500;
/* コンペアマッチタイマCMT0初期化 */
CMT.CMSTR0.BIT.STR0 = 0;
CMT0.CMCR.WORD = 0x0040;
CMT0.CMCNT = 0x0000;
CMT0.CMCOR = CNTVALUE-1;
IPR(CMT0, ) = 6;
IR(CMT0, CMI0) = 0;
IEN(CMT0, CMI0) = 1;
CMT.CMSTR0.BIT.STR0 = 1;
}
/* 以下は割り込み処理関数 */
#pragma interrupt (Int_CMT0_CMI0)
void Int_CMT0_CMI0(void)
{
/* ここにXXmS周期で実行する処理を記述 */
}
{
SYSTEM.PRCR.WORD = 0xA502;
MSTP(CMT0) = 0;
SYSTEM.PRCR.WORD = 0xA500;
/* コンペアマッチタイマCMT0初期化 */
CMT.CMSTR0.BIT.STR0 = 0;
CMT0.CMCR.WORD = 0x0040;
CMT0.CMCNT = 0x0000;
CMT0.CMCOR = CNTVALUE-1;
IPR(CMT0, ) = 6;
IR(CMT0, CMI0) = 0;
IEN(CMT0, CMI0) = 1;
CMT.CMSTR0.BIT.STR0 = 1;
}
/* 以下は割り込み処理関数 */
#pragma interrupt (Int_CMT0_CMI0)
void Int_CMT0_CMI0(void)
{
/* ここにXXmS周期で実行する処理を記述 */
}
注意:
・純正のC/C++コンパイラ使用で、統合開発環境CS+が生成するファイル“iodefine.h”によってI/Oレジスタが定義されているものとします。
・この例では、ファイル"iodefine.h"に定義されたマクロを使用しています。
"SYSTEM.PRCR"はプロテクトレジスタで、モジュールストップコントロールレジスタ(MSTPCAx)などの重要なレジスタへの書き込みを保護するものです。モジュールストップレジスタなどに書き込むためには、プロテクトレジスタで「書き込み許可」にしておかなければなりません。詳しくは
こちら を参照してください。・純正のC/C++コンパイラ使用で、統合開発環境CS+が生成するファイル“iodefine.h”によってI/Oレジスタが定義されているものとします。
・この例では、ファイル"iodefine.h"に定義されたマクロを使用しています。
モジュールストップとは、周辺機能を停止させて消費電力を抑える機能です。リセット直後はモジュールストップ状態になっているので、周辺機能の使用を始める前に解除しておく必要があります。CMT0の場合、モジュールストップコントロールレジスタA(MSTPCRA)の MSTPA15 ビットを '0' とすると解除になります。具体的には、統合開発環境CS+が生成するファイル"iodefine.h"にあるマクロを使って、
「SYSTEM.MSTPCRA.BIT.MSTPA15 = 0;」と書きますが、
「MSTP(CMT0) = 0;」と書くこともできます(MSTPA15はCMT0~CMT1共通)。
参考:IPR( ), IR( ), IEN( ) などもマクロを使った記述です。
タイマカウンタの動作をグラフで表すと下図のようになります。
4.プログラム例
4本(4チャンネル)のコンペアマッチタイマ(CMT0,CMT1,CMT2,CMT3)全てを使って、1mS, 10mS, 50mS, 100mSの定周期割り込みの発生を設定する、プログラムの例を下記に示します。
・定周期割り込み発生プログラムの例
プログラム例には、各コンペアマッチ割り込み(CMTn_CMIn)のベクタは含まれていません。下記のように、別途ベクタ番号28~31に割り込み処理関数がセットされた、割り込みベクタテーブルを作成する必要があります。
割り込みベクタテーブルの一部
~
Int_CMT0_CMI0,
Int_CMT1_CMI1,
Int_CMT2_CMI2,
Int_CMT3_CMI3,
~
~
Int_CMT0_CMI0,
Int_CMT1_CMI1,
Int_CMT2_CMI2,
Int_CMT3_CMI3,
~
/* 28 : CMT0のCMI0割り込み */
/* 29 : CMT1のCMI1割り込み */
/* 30 : CMT2のCMI2割り込み */
/* 31 : CMT3のCMI3割り込み */
/* 動作モードレジスタへの書き込みを許可する */
/* CMT0,CMT1のモジュールストップ解除 */
/* 動作モードレジスタへの書き込みを禁止する */
/* コンペアマッチタイマのカウント動作停止 */
/* クロック選択(PCLK/8→2.5MHz) ,コンペアマッチ割り込み(CMIn)を許可 */
/* コンペアマッチタイマカウンタクリア */
/* コンペアマッチタイマコンスタントレジスタセット */
/* 割り込み優先順位セット(順位6は例です) */
/* 割り込み要求ステータスフラグクリア */
/* コンペアマッチ割り込み許可 */
/* コンペアマッチタイマCMT0をスタート */