INT命令割り込みを使う
R8C/M12Aにはいろいろな割り込み機能が用意されています。それらの1つに、INT命令割り込みがあります。INT命令割り込みは、外部からの信号の立ち上がりエッジ(0から1へ変化した瞬間)、立ち下がりエッジ(1から0へ変化した瞬間)で割り込みを発生させる機能です。割り込みとは、プログラムの実行中に、実行を中断して他の機能のプログラムを実行させることです。決まった順番通りにしか実行できないプログラムの場合、何か必要な事態が生じたときに、その事態への対処プログラムがその順番がくるまで実行できないのでは不都合です。すぐに、実行を中断して、その対処をするプログラムを実行するようになっていなければなりません。それが、割り込み機能です。 R8C/M12AのINT命令割り込みには、INT0〜INT3の4つがあります。
(1) INT割り込みの端子構成
INT割り込みに使える端子は次のようになっていますが、1つのINT割り込みで使える端子は1つだけです。外部入力許可レジスタ(INTiEN)、ポート機能マッピングレジスタ(PML、PMH)を使って選択します。
外部入力許可レジスタとポート機能マッピングレジスタの設定
| 割り込み |
外部入力許可レジスタ |
選択端子 |
ポート機能マッピングレジスタ |
| INT0 |
int0en=1 |
p1_4 |
p14sel2=0 |
p14sel1=1 |
p14sel0=1 |
| p4_5 |
p45sel1=0 |
p45sel0=1 |
|
| INT1 |
int1en=1 |
p1_5 |
p15sel2=0 |
p15sel1=1 |
p15sel0=1 |
| p1_7 |
p17sel1=0 |
p17sel0=1 |
|
| p4_6 |
p46sel2=0 |
p4sel1=1 |
p46sel0=1 |
| INT2 |
int2en=1 |
p3_4 |
p34sel1=1 |
p34sel0=0 |
|
| p4_7 |
p47sel1=0 |
p47sel0=1 |
|
| INT3 |
int3en=1 |
p3_3 |
p33sel1=1 |
p33sel0=0 |
|
(2) INTi(i=0〜3)入力フイルタの設定
割り込みをチェックする時間間隔を設定します。INTi入力フィルタ選択レジスタi(INTiF0〜1)を使って設定します。
| ビット |
シンボル名 |
ビット名 |
設 定 内 容 |
| 7 |
INT0F0 |
INT0入力フィルタ選択ビット |
00:フィルタなし
01:フィルタあり、f1 でサンプリング
10:フィルタあり、f8 でサンプリング
11:フィルタあり、f32でサンプリング |
| 6 |
INT0F1 |
| 5 |
INT1F0 |
INT1入力フィルタ選択ビット |
00:フィルタなし
01:フィルタあり、f1 でサンプリング
10:フィルタあり、f8 でサンプリング
11:フィルタあり、f32でサンプリング |
| 4 |
INT1F1 |
| 3 |
INT2F0 |
INT2入力フィルタ選択ビット |
00:フィルタなし
01:フィルタあり、f1でサンプリング
10:フィルタあり、f8でサンプリング
11:フィルタあり、f32でサンプリング |
| 2 |
INT2F1 |
| 1 |
INT3F0 |
INT3入力フィルタ選択ビット |
00:フィルタなし
01:フィルタあり、f1 でサンプリング
10:フィルタあり、f8 でサンプリング
11:フィルタあり、f32でサンプリング |
| 0 |
INT3F1 |
f1 : 20 MHz( 5ns毎)でサンプリング
f8 : 2.5 MHz( 400ns毎)でサンプリング
f32: 0.625 MHz(1600ns毎)でサンプリング
サンプリングは、上記で設定したクロック毎に3回サンプリングを行い、一致した時点でIRR3レジスタのIRliビットが1になり、割り込みが生じます。
(3) INT入力エッジ選択レジスタ0(ISCR0)の設定
割り込み要求のタイミングを、信号が0から1になった瞬間(立ち上がり)、信号が1から0になった瞬間(立ち下がり)、立ち上がり立ち下がり両方、どれで行うかを選択するレジスタです。
| ビット |
シンボル名 |
ビット名 |
設 定 内 容 |
| 7 |
INT3SB |
INT3入力エッジ選択ビット |
00:立ち下がりエッジで割り込み要求発生
01:立ち上がりエッジで割り込み要求発生
11:立ち上がり立ち下がりで割り込み要求発生 |
| 6 |
INT3SA |
| 5 |
INT2SB |
INT2入力エッジ選択ビット |
〃 |
| 4 |
INT2SA |
| 3 |
INT1SB |
INT1入力エッジ選択ビット |
〃 |
| 2 |
INT1SA |
| 1 |
INT0SB |
INT0入力エッジ選択ビット |
〃 |
| 0 |
INT0SA |
(4) 割り込み優先レベルレジスタi(ILVLi)
ILVLiレジスタは、、マスカラブル割り込みの優先レベル(1〜2)を設定します。複数の割り込みが同時に発生したとき、どの割り込み(レベル1高 → レベル2低)を優先するかを設定します。レベルが同じ時はどちらを優先するかはマニュアルに記載されています。
◎ILVLE(割り込み優先レベルレジスタE)・・・INT0の割り込み優先レベルを設定するレジスタです
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
0 0 ・・・ レベル0(割り込み禁止)
0 1 ・・・ レベル1
1 0 ・・・ レベル2
ビットの名称:ILVLE5 ILVLE4
◎ILVLC(割り込み優先レベルレジスタC)・・・INT1の割り込み優先レベルを設定するレジスタです
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
0 0 ・・・ レベル0(割り込み禁止)
0 1 ・・・ レベル1
1 0 ・・・ レベル2
ビットの名称:ILVLC5 ILVLC4
◎ILVLA(割り込み優先レベルレジスタA)・・・INT2の割り込み優先レベルを設定するレジスタです
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
0 0 ・・・ レベル0(割り込み禁止)
0 1 ・・・ レベル1
1 0 ・・・ レベル2
ビットの名称:ILVLA5 ILVLA4
◎ILVLD(割り込み優先レベルレジスタD)・・・INT3の割り込み優先レベルを設定するレジスタです
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
0 0 ・・・ レベル0(割り込み禁止)
0 1 ・・・ レベル1
1 0 ・・・ レベル2
ビットの名称:ILVLD5 ILVLD4
(5)割り込み処理関数
割り込みが生じたときの処理内容は、#pragma interrupt で宣言した関数内に記述します。
#pragma interrupt intINT3(vect=26){ ・・・・ }
関数名、intINT3は任意でかまいません。(vect=26)の値は、マニュアルの可変ベクタテーブルの欄に記載されています。
INT0 ・・・ 29
INT1 ・・・ 25
INT2 ・・・ 21
INT3 ・・・ 26
(6) プログラムの作成
外部割り込み INT2(p3_4)、INT3(p3_3)を使ったプログラムを作成してみます。基盤上のポート1のLEDが0xaaと0x55 のパターンで1秒毎に交互に点滅を繰り返します。ディップスイッチをポート3に繋いでいます。ポート3のビット3に
INT3割り込み、ポート3のビット4にINT2割り込みを割り当てています。INT2を発生すると、ポート1のビット4のLEDを0.5秒毎に10回点滅します。INT3割り込みを発生するとポート1のビット3のLEDを0.5秒毎に10回点滅します。INT3割り込み中に、INT2割り込みが発生すると、割り込み優先レベル1が優先し、INT2レベルが発生し、ポート1のビット4が0.5秒毎に5回点滅します。
ポート3 bit3 ・・・ INT3、割り込み要因:立ち上がり立ち下がり、割り込み優先レベル:2
ポート3 bit4 ・・・ INT2、割り込み要因:立ち上がり立ち下がり、割り込み優先レベル:1
/*======================================*/
/* インクルード */
/*======================================*/
#include "sfr_r8m12a.h"
#define CLOCK 20000
void init(void);
void wait_us(unsigned long usec);
void wait_ms(unsigned long msec);
void timer(unsigned long timer_set);// タイマRB割り込み使用
int flag_int2;
int flag_int3;
unsigned long cnt_rb;
void main(void)
{
int i,j;
init();
while(1){
p1=0xaa;
wait_ms(1000);
p1=0x55;
wait_ms(1000);
if(flag_int2 ==1){
flag_int2 = 0;
for(i=0;i<10;i++){
p1_4=0;
timer(500);
p1_4=1;
timer(500);
}
}
else if(flag_int3 ==1){
flag_int3=0;
for(i=0;i<10;i++){
p1_3=0;
timer(500);
p1_3=1;
timer(500);
if(flag_int2 ==1){
flag_int2 = 0;
for(j=0;j<5;j++){
p1_4=0;
timer(100);
p1_4=1;
timer(100);
}
}
}
}
}
}
/****************************************************/
/* I/O 初期化関数 */
/****************************************************/
void init(void)
{
int i;
prc0 = 1; // プロテクトレジスタ解除
hocoe = 1; // 高速オンチップオシレータ発振開始
for(i=0;i<50;i++); // 発振安定まで待つ
hscksel = 1; // 高速オンチップオシレータ選択ビットを1にする
scksel = 1; // システム基準クロックを高速にする
prc0 = 0; // プロテクトレジスタ禁止
pd1 = 0xff; // p1_0〜p1_7 出力設定
pd3 = 0xa7; // p3_3,p3_4入力,p3_5
pd4 = 0xe4; // p4_2,5,6,7 出力設定
pur3 = 0xb8; // p3_3,p3_4のプルアップ設定
/* タイマRBの設定 1ms毎に割り込み発生 */
msttrb = 0;// タイマRBスタンバイビット タイマRBを有効
trbmr = 0x00;// タイマRBモードレジスタ タイマー動作モード 分周比20MHzに設定(50ns毎にカウントダウン)
trbpre = 200-1;// タイマRBプリスケーラレジスタ設定 50ns X 200 = 10us毎に1パルス出力
trbpr = 100-1;// タイマRBプライマリレジスタ設定 100 X 10 us = 1ms毎に割り込み発生
trbir = 0xc0;// タイマRB割り込み制御レジスタ 割り込み要求 1100 0000
ilvlc = 0x03;// 割り込み優先レベル2に設定
trbcr = 0x01;// タイマRB制御レジスタ カウント開始許可
p33sel1 = 1;// p3_3をINT3端子にする
p33sel0 = 0;
int3en = 1;// 外部入力許可レジスタ
int3f1 = 1;// f32(1600ns単位)
int3f0 = 1;
int3sb = 1;// INT入力エッジ選択レジスタ
int3sa = 1;// 立ち上がり、立ち下がり両方で割り込み要求
ilvld1 = 1;// 割り込み優先レベル設定ビット
ilvld0 = 0;// 割り込み優先レベル2に設定
p34sel1 = 1;// p3_4をINT2端子にする
p34sel0 = 0;
int2en = 1;// 外部入力許可レジスタ
int2f1 = 1;// f32(1600ns単位)
int2f0 = 1;
int2sb = 1;// 入力エッジ選択レジスタ
int2sa = 1;// 立ち上がり、立ち下がり両方で割り込み要求
ilvla5 = 0;// 割り込み優先レベル設定ビット
ilvla4 = 1;// 割り込み優先レベル1に設定
asm(" fset I ");// 割り込み許可
// admod =0x08;// A/D動作 0x08:繰り返しモード 0x00:単発モード
}
/****************************************************/
/* タイマ本体 us単位のwait関数 */
/****************************************************/
void wait_us(unsigned long usec)
{
usec = (usec * CLOCK) / 45000;
while(usec --);{}
}
/****************************************************/
/* タイマ本体 ms単位のwait関数 */
/****************************************************/
void wait_ms(unsigned long msec)
{
unsigned int i;
for(i=0;i<msec;i++){
wait_us(1000);
}
}
/****************************************************/
/* INT2割り込み処理関数 */
/****************************************************/
#pragma interrupt intINT2(vect=21)
void intINT2(void)
{
flag_int2=1;
}
/****************************************************/
/* INT3割り込み処理関数 */
/****************************************************/
#pragma interrupt intINT3(vect=26)
void intINT3(void)
{
flag_int3=1;
}
/****************************************************/
/* タイマRB2割り込み使用 */
/****************************************************/
void timer(unsigned long timer_set)
{
cnt_rb = 0;
while(cnt_rb<timer_set);
}
/****************************************************/
/* RB2割り込み処理関数 */
/****************************************************/
#pragma interrupt intTRB(vect=24)
void intTRB(void)
{
trbif_trbir = 0;// 割り込み制御レジスタの割り込み要求フラグをクリア
cnt_rb ++;
}
プロジェクトファイルのダウンロード
メニューに戻る