はじめに
コンペアマッチタイマー CMTで行うTimer割り込みの設定諸々についての記述.マイコンボードはGR-CITRUSとする.ハードウェアマニュアルの参考先はHM *.*.*と表記する(例:HM 3.3.4ならばハードウェアマニュアルの3.3.4節を参考).
資料(必需品)
・ RX63Nグループ、RX631グループ ユーザーズマニュアル
・ GR-CITRUS回路図
Timer割り込みとは
カウントダウンタイマーがクリアされる時に,任意のプログラムを実行する.
Timer(CMT)割り込み設定
CMTの初期化と割り込み関数の作成を行う.
初期化関数
流れ
- CMT有効化
- CMTの設定
- 割り込み優先度の設定
- 割り込み許可
extern void HardwareSetup(void);
void GPIO_init(void);
void Clock_init(void);
void CMT0_init(void);
void HardwareSetup(void)
{
GPIO_init();
Clock_init();
CMT0_init();
}
/*=================================
* 関数名 : CMT0_init
* 機能 : CMT0の初期化
* 引数 : なし
* 戻り値 : なし
* 備考 :設定周期 :1ms 割り込み優先度:4
* ===============================*/
void CMT0_init(void)
{
/*=== プロテクト解除 ===*/
SYSTEM.PRCR.WORD = 0xA502;
/*=== CMTを有効化 ===*/
MSTP(CMT0) = 0;
/*=== プロテクト ===*/
SYSTEM.PRCR.WORD = 0xA500;
/*=== CMT動作停止 ===*/
CMT.CMSTR0.BIT.STR0 = 0;
/*=== CMT設定 ===
* クロック選択 : PCLK/8 = 6MHz
* CMT割り込み許可
* ===========*/
CMT0.CMCR.BIT.CKS =0;
CMT0.CMCR.BIT.CMIE = 1;
/*=== カウントリセット ===*/
CMT0.CMCNT = 0;
/*=== 周期カウント設定 ===
* 設定周期 : 1ms
* CMCOR = 設定周期[s]*PCLKB[Hz]/分周比-1
* ================*/
CMT0.CMCOR = 5999;
/*=== CMT動作開始 ===*/
CMT.CMSTR0.BIT.STR0 = 1;
/*=== 割り込み優先度設定 ===*/
IPR(CMT0,CMI0) = 4;
/*=== 割り込み許可 ===*/
IEN(CMT0,CMI0) = 1;
}
割り込み関数
# include"iodefine.h"
# include"vect.h"
# define LED PORTA.PODR.BIT.B0
# define LED_ON 1
# define LED_OFF 0
void LightLED(void)
{
if(PORTC.PIDR.BIT.B0 == 0)
{
LED = LED_ON;
}else{
LED = LED_OFF;
}
}
新たにファイルを作成して,割り込みによってやりたいことを記述した関数を作成する.この関数の宣言は既存のvect.hの中でやることになる.
// CMT0 CMI0
//#pragma interrupt (Excep_CMT0_CMI0(vect=28))
//void Excep_CMT0_CMI0(void);
# pragma interrupt (LightLED(vect=28))
void LightLED(void);
vect.hの//CMT0 CMI0直下の2行をコメントアウトして,自作した関数名に書き換える.割り込み関数を既存の Excep_CMT0_CMI0
にする場合は,/generate/intprg.cに用意されている関数内にプログラムを書く.
多重割り込みを行う場合は,enableを追加するらしい.
# pragma interrupt ((割り込み関数名)(vect=(ベクタ番号)),enable)
詳細
1. CMT有効化
SYSTEM.PRCR.WORD = 0xA502;
プロテクト解除
HM 13.1.1より,保護するレジスタへの書き込み許可を選択する.PRCR
は16bit構成で以下のような内容である.WORD
で一括で設定している.
b0 > 0 :クロック発生回路関連レジスタへの書き込み禁止
b1 > 1 :動作モード、消費電力低減機能、ソフトウェアリセット関連レジスタへの書き込み許可
b2 > 0 :予約ビット
b3 > 0 :LVD関連レジスタへの書き込み禁止
b7-4 > 0 :予約ビット
b15-8 > A5 : PRCキーコードビット
MSTP(CMT0) = 0;
モジュールストップ解除
HM 11.4より,レジスタの読み出し書き込みができる状態にする必要がある.=0
で解除となる.
SYSTEM.PRCR.WORD = 0xA500;
プロテクト
HM 13.1.1より,保護するレジスタへの書き込みを禁止する.
2. CMTの設定
CMT.CMSTR0.BIT.STR0 = 0;
CMT動作停止
HM 28.2.1より,CMT0.CMCNTカウンタのカウント動作を停止する.
CMT0.CMCR.BIT.CKS =0;
CMT0.CMCR.BIT.CMIE = 1;
CMT設定
HM 28.2.3より,CKS
レジスタで,周辺モジュールクロック(PCLK)を分周して得られる分周クロックからCMCNTカウンタに入力するカウントクロックを選択する.後述の周期設定に合わせて適切な分周を選ぶ.CMIE
レジスタで,割り込みの許可をする.
CMT0.CMCNT = 0;
カウントリセット
HM 28.2.4より,CMCNTの初期値を0にする.CMCNT カウンタの値が CMCOR レジスタの値と一致すると,CMCNT カウンタは “0000h” になる.このとき,コンペアマッチ割り込みが発生する.
CMT0.CMCOR = 5999;
周期カウントの設定
HM 28.2.5より,CMCORの値を指定して,割り込み周期を設定する.コンペアマッチタイマーは1/(PCLKB[Hz]/分周比)秒のタイミングでCMCNT カウンタをカウントアップをしていき,CMCOR レジスタの値と一致すると,CMCNT カウンタは “0000h” にする.このとき,コンペアマッチ割り込みが発生する.カウント数xカウントクロックの周期が割り込み周期となる.
CMCORの値は,以下の数式で値を決定する.
CMCOR = 設定周期[s]*PCLKB[Hz]/分周比-1
この時,16bitタイマーなので,CMCORに設定できる値は0xFFFFないである必要がある.設定周期に合わせて分周比を調整する.
CMT.CMSTR0.BIT.STR0 = 1;
CMT動作開始
HM 28.2.1より,CMT0.CMCNTカウンタのカウント動作を開始する.
3. 割り込み優先度の設定
IPR(CMT0,CMI0) = 4;
HM 15.2.3より,対応する割り込み要因の優先レベルを選択する.優先度は0から15まで指定できて,値が大きいほど優先度が高くなる.0は高速割り込みに設定している場合のみ割り込み可能である.
4. 割り込み許可
IEN(CMT0,CMI0) = 1;
HM 15.2.2より,割り込み要求先に割り込み要求を出力する.
端書き
割り込みを任意期間だけする場合は,setup.cで割り込み許可をしないでプログラム上で許可を行う.
# define CMT1_START IEN(CMT1,CMI1) = 1
# define CMT1_STOP IEN(CMT1,CMI1) = 0
参考文献
- RX220で1ms周期のタイマを作成してLチカ https://qiita.com/ekd/items/6015c1022411b23f15d1
- RX631開発 Timer割り込み - CCWO https://ccwo.hatenablog.jp/entry/2016/08/18/023400