インターバルタイマのプログラミング

インターバルタイマを使ったプログラミングでは、設定のため、幾つかのレジスタを設定する必要がある。レジスタとタイマの機能について、概観すると、以下のようになる。

 

  • タイマユニットのON/OFF(TSTR)

 H8/3052には5つのタイマユニット(ITU0~4)が内蔵されているが、デフォルトではOFFに設定されている。タイマユニットをONにしたい場合は、TSTR(タイマ・スタート・レジスタ)の該当するビットを1に設定する。

  • タイマの動作は、システムクロック(φ、もしくは外部クロック信号)を基準に動作する。システムクロックの周波数は25MHz(1秒間に2千5百万回の振動)なので、ゆっくりカウントしたい場合は、プリスケーラを使うことで、1/8まで周波数を落とす事が出来る。この場合は、ITU毎に設置されているTCRのTPSC1、TPSC0のビットを設定する。
    (外部クロックを使う場合は、TCRのビット2~TPSC2を1に設定する)
     
  • TCNTのカウント方法を設定する。プリスケーラで周波数を遅くした(これを分周という。逆に周波数を上げる場合は、逓倍)クロック信号について、どのようにカウントするかを設定する。これは、TCRのビット4と3(CKEG1、CKEG0)で設定する。
     
  • GRA、GRBの設定を行う。いずれもITU毎に1つずつ実装されている。インターバルタイマを使う場合のGRAとGRBの動作は、以下の通り。(TCNTとGRA、GRBのコンペアマッチで、TIOCAとTIOCBを反転出力させ、設定次第で割り込みも発生。GRBのコンペアマッチで、TCNTを0にリセット)

  1. TCNTの値は、プリスケーラで設定された周期でカウントアップされる。
  2. TCNTの値がGRAもしくはGRBに一致(コンペア・マッチ)した際、CCLR1およびCCLR0設定により、TCNTの値がリセットされる。(もしくは、リセットしない)
  3. TCNT=GRAの時、TIOCAの出力が反転、TSRのIMFAが1。TIERのIMIEAが1の時、割り込み発生
  4. TCNT=GRBの時、TIOCBの出力が反転、TSRのIMFBが1。TIERのIMIEBが1の時、割り込み発生

    ※ TIOCAとTIOCBは、コンペア・マッチなどのイベントが発生した事を、外部に通知する信号線。

  1. TSRの該当ビットを0にクリアする。
  • TCNT == GRA の時 IMFA = 1
  • TCNT == GRBの時  IMFB = 1
  • TCNTが0xFFFFを超えた時、もしくは、0x0000を下回った時 OVF = 1

   となるため、該当するビットをクリアする必要がある。割り込み許可状態(TIERの対応するビットが1)の状態だと、このビットをク
  リアしない限り、割り込みイベント(インターバルタイマの)が継続して発生しているとみなされてしまう。
 



○プログラミングの実際

(1) 割り込みを使わずにTSRのフラグをチェックする方法。(こういうのをポーリングと呼ぶ)
【main.c】

#define ITU_TSTR  (*(volatile unsigned char *)0xFFFF60)
#define ITU0_TCR  (*(volatile unsigned char *)0xFFFF64)
#define ITU0_TSR  (*(volatile unsigned char *)0xFFFF67)
#define ITU0_TIER  (*(volatile unsigned char *)0xFFFF66)
#define ITU0_GRA  (*(volatile unsigned int *)0xFFFF6A)
#define ITU0_GRB  (*(volatile unsigned int *)0xFFFF6C)

void timer_init()
{
    /* ITU0タイマーを初期化する
      * ITU0のTCRレジスタに以下の値を設定
      * プリスケール 1/8 => 0000 0011 (0x03)
      * 立ち上りエッジでカウント => 0000 0000 (0x00)
      * GRAコンペアマッチ => 0010 0000 (0x20)
      */
  ITU0_TCR = ( 0x03 | 0x00 | 0x20);
     /*
       * クロック1/8で1msecのカウントができるようにGRAを設定
       * 1秒間で25/8 M(10の6乗)回カウントする => 3.125M回
       * 3125回カウントすると1msec経過したことになる
       */
   ITU0_GRA = 3125;
      /*
        * ITU0のカウントアップを停止
        * TSTRレジスタの1ビット目がITU0の開始、停止をコントロール
        * 0なら停止、1なら開始
        */
   ITU_TSTR = 0x00;
}

int main()
{
    ....
    timer_init();  // インターバルタイマの初期設定
    ....
   ITU_TSTR |= 0x1;  // ITU0を起動

    while (1) {
        ....
        if (ITU0_TSR & 0x01)) { // IMFAビットが1(GRAとTCNTの値が一致)である時、
           ITU0_TSR = ITU0_TSR & 0xFE;  // IMFAビットを0にクリア


※ 割り込みを使わない場合は、ベクタテーブルは修正する必要はない。(monitor.hは、無修正で、そのまま使えば良い)


(2) 割り込みを使う場合は、

【main.c】

#define ITU_TSTR  (*(volatile unsigned char *)0xFFFF60)
#define ITU0_TCR  (*(volatile unsigned char *)0xFFFF64)
#define ITU0_TSR  (*(volatile unsigned char *)0xFFFF67)
#define ITU0_TIER  (*(volatile unsigned char *)0xFFFF66)
#define ITU0_GRA  (*(volatile unsigned int *)0xFFFF6A)
#define ITU0_GRB  (*(volatile unsigned int *)0xFFFF6C)

void timer_init()
{
    /* ITU0タイマーを初期化する
      * ITU0のTCRレジスタに以下の値を設定
      * プリスケール 1/8 => 0000 0011 (0x03)
      * 立ち上りエッジでカウント => 0000 0000 (0x00)
      * GRAコンペアマッチ => 0010 0000 (0x20)
      */
  ITU0_TCR = ( 0x03 | 0x00 | 0x20);
     /*
       * クロック1/8で1msecのカウントができるようにGRAを設定
       * 1秒間で25/8 M(10の6乗)回カウントする => 3.125M回
       * 3125回カウントすると1msec経過したことになる
       */
   ITU0_GRA = 3125;
      /*
        * ITU0のカウントアップを停止
        * TSTRレジスタの1ビット目がITU0の開始、停止をコントロール
        * 0なら停止、1なら開始
        */
   ITU_TSTR = 0x00;
}

#pragma interrupt(timer_imia_handler)   // 以下に続く関数が、割り込みハンドラである事を示す。
void timer_imia_handler()         // 割り込みハンドラの定義
{
    ITU0_TSR = ITU0_TSR & 0xFE;
    printf(".");
}

int main()
{
    ....
   set_imask_ccr(1); // 全ての割り込みを禁止
    timer_init();  // インターバルタイマの初期設定
    ....
   set_imask_ccr(0);  // 全ての割り込みを許可
   ITU0_TIER |= 0x1;  // ITU0_TSRのIMFAが1になった時に割り込み発生
   ITU_TSTR |= 0x1;  // ITU0を起動

    while (1) {
        ....
 


 

 【monitor.h】

.....

void timer_imia_handler();
.....

const fp VectorTable[] =     // ベクタテーブルの定義
{
    (fp)PowerON_Reset,       //  vector  0 Reset
    (fp)0L,                  //  vector  1 Reserved
    .....
    (fp)0L,                  //  vector 23 [reserved]
   (fp)timer_imia_handler,   //  vector 24 ITU0 IMIA0
    (fp)0L,                  //  vector 25 ITU0 IMIB0
    .....
 


さらなるステップアップ、エコな生活を実現したいあなたへ。(いささか大げさではあるが)
 

最終更新:2014年10月07日 16:08