鳥の巣箱

ネトゲしたり、機械いじったり、ソフト書いたり、山篭ったり、ギャンブルしたりする人

KPIT GNU H8ツールチェイン 割り込み操作のなんたらかんたら

H8マイコンで割り込み操作を実行するためにあれこれ試行錯誤していたものの

なぜか割り込みが入らない。

 

ネットで色々調べてみるもツールチェインがGCCだったりでKPITを使った情報が極端に少ない。

てか見つからねぇ。

 

とりあえず動かすための手順だけ殴り書き。

 

「inthandler.h」割り込みベクタテーブル。

「inthandler.c」上記のヘッダファイルに対応する割り込みハンドラが記述されてる。

「intrinsic.h」KPITがあらかじめ用意してくれてる関数群。

 

重要なのはこの辺。inthandler.hとintrinsic.hは編集不要。

ただ、それぞれ必要に応じて各ファイルにIncludeはする。

 

「inthandler.c」に手を加える。

~~前略~~

// vector 32 IMIA2
void INT_IMIA2(void) { count_up(); }
// vector 33 IMIB2
void INT_IMIB2(void) { }
// vector 34 OVI2
void INT_OVI2(void) { }

~~後略~~

今回は内部割り込みで、ITUのチャンネル2 GRAコンペアマッチをフラグに使った。

割り込みフラグが立つと関数「count_up」を呼び出す。

よって上のように記述。

 
メイン関数そのほか諸々。intrinsic.hはInclude必須。

int cnt;                      // 割り込み回数カウンタ

void int_timer(void);
void count_up(void);

#define   _di()   set_imask_ccr(1)         // 全割込み禁止
#define   _ei()   set_imask_ccr(0)         // 全割込み許可

int main(void){
    _di();
    PB.DDR = 0xFF;
    PB.DR.BYTE = 0xFF;

    time_init();
    int_timer();
    _ei();

    char *str;

    ITU.TSTR.BIT.STR2 = 1;    // ITU2 TCNTカウント開始

    while (1) {
      PB.DR.BIT.B0 = 1;
      timer_msec(500);
      PB.DR.BIT.B0 = 0;
      timer_msec(500);
    }
    return 0;

}

void count_up(void){
    
    cnt++;

    PB.DR.BIT.B1 = 1;

    if(cnt == 100){
        cnt = 0;
        PB.DR.BIT.B1 = 0;
    }

    ITU2.TSR.BIT.IMFA = 0;    // 検知フラグクリア
    //PB.DR.BIT.B1 = 1;
}

void int_timer(void){
  ITU2.TCR.BYTE = 0x23;       // プリスケーラφ/8
  ITU2.GRA = 0x7A11;          // 10[ms]でTCNTクリア
  ITU2.TIER.BIT.IMIEA = 1;    // ITU2 GRAコンペアマッチ割り込み許可
  ITU.TSTR.BIT.STR2 = 0;      // ITU2 カウント停止
  cnt = 0;
}


で、何がいけなかったのか。


#define   _di()   set_imask_ccr(1)         // 全割込み禁止
#define   _ei()   set_imask_ccr(0)         // 全割込み許可

これがなかったからダメだったみたい。


「intrinsic.h」で「set_imask_ccr」の中身が記されているが、その中身ってのが

extern __inline__ void set_imask_ccr(unsigned char mask)
{
    if(mask==1) 
	    /* mask = 1, sets the Interrupt mask bit, this will disable interrupts except NMI */
	  asm("orc.b #0x80, ccr"); 
	else
	  /* mask = 0, resets the Interrupt mask bit, this will enable interrupts*/
	  asm("andc.b #0x7f, ccr"); 
}
extern __inline__ void sleep(void){
     asm("sleep");
}

これ。CCR(コンディションコードレジスタ)のUEビットを操作できる。
初期設定は1でNMI以外の割り込み操作を禁止している状態だった。なんてこったい\(^o^)/。


で、この「set_imask_ccr」を利用して、引数1を「_di」に引数0を「_ei」をそれぞれDefineした。
そんでもってメイン関数。
各種初期設定をする前に一旦割り込み全禁止にする。
設定が終わったタイミングで割り込み許可。
そっからITU2のカウントスタート。


はい。動いた。


「intrinsic.h」の中身、いろいろと使えそうなものが入ってる感じだから今度じっくりと読み解いてみないとダメそうね。。。
ちょいちょいアセンブラ混じってるから読むのだるいよ