LoginSignup
0
0

More than 3 years have passed since last update.

Timer割り込み(コンペアマッチタイマー CMT)

Last updated at Posted at 2020-07-18

はじめに

コンペアマッチタイマー CMTで行うTimer割り込みの設定諸々についての記述.マイコンボードはGR-CITRUSとする.ハードウェアマニュアルの参考先はHM *.*.*と表記する(例:HM 3.3.4ならばハードウェアマニュアルの3.3.4節を参考).

資料(必需品)
RX63Nグループ、RX631グループ ユーザーズマニュアル
GR-CITRUS回路図

Timer割り込みとは

カウントダウンタイマーがクリアされる時に,任意のプログラムを実行する.

Timer(CMT)割り込み設定

CMTの初期化と割り込み関数の作成を行う.

初期化関数

流れ
1. CMT有効化
2. CMTの設定
3. 割り込み優先度の設定
4. 割り込み許可

"hwsetup.c"

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;
}

割り込み関数

icu_cmt.c
#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の中でやることになる.

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.PNG

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

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0