目次
1. 初めに
2. タイマー設定
3. 割り込み設定
4. 割り込み処理
5. 出力ポート測定
6. タイマー値変更
7. 終わりに
1. 初めに
今回のテーマはタイマー割り込みです。
以前説明しました EFM8BB3 Blinky プロジェクトを教材としていろいろやって行きます。
それから、マイコンを使いこなそうとするならば、そのマイコンのリファレンスマニュアルを読むことが肝要です。今回対象の基板に搭載しているEFM8マイコン(EFM8BB31F64G-A-QFN32)のリファレンスマニュアルは以下のホームページから入手できます。
2. タイマー設定
Hardware Configurator を用いてタイマー設定を確認します。
EFM8B3_Blinkey.hwconf を右クリックし、 Open を選択します。

DefaultMode Peripherals をクリックしてペリフェラル設定画面を表示します。

Timersのプロパティを表示します。赤枠の辺りを上下にドラッグしてプロパティ画面を拡げます。(画面を拡げないと次のタイマー設定毎のタブが表示されない模様。当方の環境だけでしょうか?)

タイマー設定毎のタブを表示します。 TIMER 2 をクリックします。

いくつか抜粋すると
| Property | Value | 備考 |
|---|---|---|
| Target Overflow Frequency | 5 | 周波数をHz単位で入力する |
| Timer Reload Overflow Frequency | 5.000 Hz | 入力した周波数と同じ値になる(入力不可) |
| Timer Reload Overflow Period | 200.002ms | 入力した周波数を周期に換算(入力不可) |
TIMER 2 は周期200msecでオーバーフローすることがわかります。
では、オーバーフローしたらどうなるのか、というと、割り込みが発生します。いわゆるタイマー割り込みですね。次は割り込みの設定を見て行きます。
3. 割り込み設定
先の画面からの続きです。
Interrupts をクリックします。

いくつか抜粋すると
| Property | Value | 備考 |
|---|---|---|
| Enable All Interrupts | Enabled | Enabled : 各割り込み許可に従って割り込み要求を受け付ける Disabled : 全割り込みを一括禁止する |
| Enable Timer 2 Interrupt | Enabled | Enabled : TIMER2割り込みを許可する Disabled : TIMER2割り込みを禁止する |
これで、TIMER 2 がオーバーフローすると TIMER 2 割り込み が発生することがわかります。では、 TIMER 2 割り込み が発生するとどうなるのか、というと、割り込み処理を実行します。次は割り込み処理を見て行きます。
4. 割り込み処理
割り込み処理は Interrupts.c に記述されています。

//=========================================================
// src/Interrupts.c: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
// USER INCLUDES
#include <SI_EFM8BB3_Register_Enums.h>
//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
int LEDCOUNT = 0;
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
SI_SBIT(LED0, SFR_P1, 4); // P1.4 LED0
SI_SBIT(LED1, SFR_P1, 5); // P1.5 LED1
SI_SBIT(LED2, SFR_P1, 6); // P1.6 LED2
//-----------------------------------------------------------------------------
// TIMER2_ISR
//-----------------------------------------------------------------------------
//
// TIMER2 ISR Content goes here. Remember to clear flag bits:
// TMR2CN::TF2H (Timer # High Byte Overflow Flag)
// TMR2CN::TF2L (Timer # Low Byte Overflow Flag)
//
// This routine changes the state of the LED whenever Timer2 overflows.
//
//-----------------------------------------------------------------------------
SI_INTERRUPT(TIMER2_ISR, TIMER2_IRQn)
{
TMR2CN0_TF2H = 0; // Clear Timer2 interrupt flag
switch (LEDCOUNT)
{
case 0:
LED0 = 1;
LED1 = 0;
LED2 = 0;
break;
case 1:
LED0 = 0;
LED1 = 1;
LED2 = 0;
break;
case 2:
LED0 = 0;
LED1 = 0;
LED2 = 1;
break;
case 3:
LED0 = 1;
LED1 = 1;
LED2 = 0;
break;
case 4:
LED0 = 0;
LED1 = 1;
LED2 = 1;
break;
case 5:
LED0 = 1;
LED1 = 0;
LED2 = 1;
break;
case 6:
LED0 = 1;
LED1 = 1;
LED2 = 1;
break;
}
if (LEDCOUNT <= 6) LEDCOUNT++;
else LEDCOUNT = 0;
}
SI_INTERRUPT(TIMER2_ISR, TIMER2_IRQn) は割り込み処理で実行する関数です。この関数が TIMER 2 オーバーフローの度に呼び出されます。
SI_INTERRUPT(TIMER2_ISR, TIMER2_IRQn)
switch~case文で点灯・消灯するLEDを切り替えています。
switch (LEDCOUNT)
{
case 0:
LED0 = 1;
LED1 = 0;
LED2 = 0;
break;
//以後省略
LED0 , LED1 , LED2 はそれぞれのLED出力ポートを示し、この文で定義しています。
SI_SBIT(LED0, SFR_P1, 4); // P1.4 LED0
SI_SBIT(LED1, SFR_P1, 5); // P1.5 LED1
SI_SBIT(LED2, SFR_P1, 6); // P1.6 LED2
この定義により、例えば
LED0 = 1 とすると P1.4 には 1:Hi を、
LED0 = 0 とすると P1.4 には 0:Low を出力します。
マイコン基板のLED周辺の回路図です。0:Low で点灯、1:Hi で消灯することが分かります

※SI_SBIT はsi_toolchain.hで定義されています。

main() に IE_EA = 1; の記述があります。これは割り込み設定をコードで記述しており、Enable All Interrupts の設定を Enabled:各割り込み許可に従って割り込み要求を受け付ける としています。仮にIE_EA = 0;とした場合、Disabled:全割り込みを一括禁止する となります
//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
void main (void)
{
enter_DefaultMode_from_RESET();
DISP_EN = DISP_BC_DRIVEN; // Display not driven by EFM8
IE_EA = 1; // Enable global interrupts
while (1) {} // Spin forever
}
5. 出力ポート測定
実際に設定通りの周期でタイマーが動作していることを確認します。LED出力ポートの波形をオシロスコープで測定します。

LED出力ポートの接続はスルーホール用テストワイヤを用いています。
波形を見ると、周期200msであることがわかります。設定通りですね。

6. タイマー値変更
タイマー値を変更してみます。
TIMER2設定画面の Target Overflow Frequency を5から10へ変更するとTimer Reload Overflow Frequency、Timer Reload Overflow Period が自動的に変化します。TIMER2 オーバーフロー周期が100msecになります。

| Property | Value |
|---|---|
| Target Overflow Frequency | 10 |
| Timer Reload Overflow Frequency | 10.000 Hz |
| Timer Reload Overflow Period | 100.001ms |
変更後のLED出力ポート波形です。周期100msであることがわかります。 
7. 終わりに
Hardware Configurator は大変便利ですね。こういった便利ツールはどんどん使って行きます。




