TIMER0による周期タイマー割り込み

周期タイマーを利用する方法として、Tick Timer を用いるもの TIMER0/1/2 を用いるもの、Wakeup Timer を用いるものがありますが、ここでは TIMER0 の利用例を示します。以下の例では、プリスケーラを 2^14 = 16384 とし、16MHz クロックでは1周期約1msとなり、TIMER_TICK_MS周期ごとに割り込みを発生させます。

以下にAppQAPI による実行例およびvAHI_Timer0RegisterCallback()による割り込みハンドラ例を示します。

※DIOの出力 (PWM 出力) と割り込みを同時に使う事は出来ません。

※時間保証は有りません。vAHI_Timer0RegisterCallback() により直接コールバック関数を記述する事で改善はされますが、無線部 MAC 層などの処理などが優先される場合があり、非常に短い周期(1ms未満では顕著)での実行では、割り込みが飛ばされたり、ジッターが散見されます。

AppQAPI によるコード

AppQAPIは、割り込み遅延実行を行うため、割り込み時の処理には制限がありません(無線処理もここで行う)。反面、割り込みハンドラからメインループの処理まで待たされるため、遅延の影響が大きくなります。

#define TIMER_TICK_MS 5

PRIVATE void vTimerConfig(void)
{
    vAHI_TimerFineGrainDIOControl(0xFF); // disabple all DIOs for timer use

    vAHI_TimerEnable(E_AHI_TIMER_0,
                     14,      // プリスケーラ 2^14 (1.024ms)
                     FALSE,
                     TRUE,    // タイマーの終了区間で割り込み発生
                     FALSE); 

    vAHI_TimerClockSelect(E_AHI_TIMER_0,
                          FALSE,    // 内部の 16MHz クロックを利用する
                          TRUE);

    vAHI_TimerStartRepeat(E_AHI_TIMER_0,
                          0x0000,
                          TIMER_TICK_MS);         // タイマー期間
}

/* 以下は AppQAPI の場合 
 *   JenNet の場合は、同様に vJenie_CbHwEvent() が割り込み遅延実行処理として呼び出されます。
 */

PUBLIC void AppColdStart(void) {
  ...
	/* register hardware interrupt handler */
	(void)u32AppQApiInit(NULL, NULL, NULL); // 直接の割り込み処理は、AppQAPI 内部で処理される
  ...
  vMain();
}

PRIVATE void vMain(void)
{
    while(1)
    {
        vAHI_CpuDoze();
        vCheckEventQueues();
        
        ... そのほかの処理 ...
    }
}

PRIVATE void vCheckEventQueues(void)
{
  ...
    do
    {
        psAHI_Ind = psAppQApiReadHwInd();
        if (psAHI_Ind != NULL)
        {
            vProcessIncomingHwEvent(psAHI_Ind);
            vAppQApiReturnHwIndBuffer(psAHI_Ind);
        }
    } while (psAHI_Ind != NULL);
   ...
}

/* 割り込み遅延実行のハンドラ */
PRIVATE void vProcessIncomingHwEvent(AppQApiHwInd_s *psAHI_Ind)
{
    switch (psAHI_Ind->u32DeviceId) {
    case E_AHI_DEVICE_TIMER0:
		  {
			... タイマー割り込みの遅延実行 ...
		  }
	    break;
    }
}
  

vAHI_TimerXRegisterCallback()によるコード

vAHI_TimerXRegisterCallback() を用いた例です(Xは0,1,2)。ハードウェアからの割り込みハンドラですから、割り込み発生後最短で呼び出されるため、遅延が少ないことが特徴です。同時に、ハンドラ内の処理も最短で行います。

例えばIOピンの L/H を変更するといった単純なものは許容されますが、時間のかかる処理、IOも処理によっては動作しない事が考えられます。 また、スタックAPI(JenNet)の呼び出しや、無線に関連する処理(送信手続きなど)もここでは行いません。

ただし遅延が少ないとはいえ、MAC層(無線部)での処理は最優先され、その影響は免れません。目安として1KHz を超えるような高周期の場合、顕著になります。

#define TIME_PRESCALSE 0
#define TICK_PERIOD_COUNT 320

// タイマー割り込み開始
PUBLIC void vTime_Init(void)
{
  u32TimerTicks = 0;
  vAHI_TimerEnable(E_AHI_TIMER_0, TIMER_PRESCALE, FALSE, TRUE, FALSE);
  vAHI_TimerClockSelect(E_AHI_TIMER_0, FALSE, FALSE);
  vAHI_Timer0RegisterCallback(vTime_TimerISR);
  vAHI_TimerStartRepeat(E_AHI_TIMER_0, 0, TICK_PERIOD_COUNT);
  vAHI_TimerDIOControl(E_AHI_TIMER_0, FALSE);
}

// 割り込みハンドラ
PRIVATE void vTime_TimerISR(uint32 u32Device, uint32 u32ItemBitmap)
{
  u32TimerTicks++; // 簡単な処理のみ実施し、速やかに関数から抜ける。
}
TWELITE
TWELITE
DIP
DIP
UART
UART
CUE
CUE
ARIA
ARIA
PAL
PAL
STICK
STICK
spot
SPOT
R3
R3
STARTER KIT
STARTER KIT
アンテナ
アンテナ
製品一覧
製品一覧

モノをつなぐ無線

モノをつなぐ無線
モノの無線
導入事例
導入事例
選び方
選び方
小型
小型
省電力
省電力
多数接続
多数接続
コントロール
コントロール
モニタリング
モニタリング
ソフトウエア
ソフトウエア
親機
親機
中継機
中継機
子機
子機
始め方
始め方

評価開発環境

STAGE
STAGE
STAGE APP
STAGE APP
interactive
アプリ設定
アプリ書換
アプリ書換
プログラミング
プログラミング