比較的長い時間の制御をおこないます。タイマ割り込みできっかけを作り処理自体は Loop()などのフォアグラウンド処理で行います。
◀ この記事の前に: タイマ割り込み
▶ この記事の次に: 可変タイマ割り込み
定時タイマ割り込みのしくみ
組み込みシステムは外部と直接関係を持つため、外部の状況を早く捉えたり、周辺回路が要求するタイミングに合わせたりする必要があります。それを実現するために時間(タイミング)を重視します。その時間を正確に管理するための機能がタイマです。
MCU には多くの場合、タイマを搭載しています。MCU内部の CPU はプログラムを逐次実行しています。プログラムの実行中に必要な時刻で処理を行う必要があります。そのときに使用する機能がタイマ割り込みです。タイマ割り込みはあらかじめ決めておいた時刻になると CPU に信号を発します。CPU はその信号を受けると逐次実行していたプログラムを一旦停止して、優先的にその信号に合わせた処理を実行します。その処理がタイマ割り込み処理です。処理が終了すると元々実行していた処理を再開します。
タイマの実際の動作は、カウンタにあらかじめ設定した値から一定の時間毎に1づつ減じて( カウントダウン )0になったときに割り込みを発生する場合と、カウンタに0を設定して一定の時間毎に1づつ増して( カウントアップ )あらかじめ設定した値になった場合に割り込みを発生する場合があります。この「一定の時間」をタイマのクロックと呼びます。クロックの周波数でタイマの分解能が決まります。クロックは MCU 内の各種の信号から選択します。
インターバルの生成
インターバルの生成は定時的にタイマで割り込みを発生する部分と、その割り込みをカウントして必要とするインターバルを作る部分で構成します。
タイマのクロックは多くの供給源から選択することができます。ここではシステムクロックにしました。プリスケーラはタイマの前段で分周を行いクロック周波数を変更する機能です。プリスケーラの値を変更することによりタイマの分解能を変更することができます。

タイマで割り込みを発生する部分は、 125 ms の定時割り込みを発生します。その割り込みをカウントして必要とするインターバルを作る部分は、複数あるフォアグラウンド処理が、それぞれの処理で必要なインターバルを生成しています。前者が基準となりますので、後者の処理分解能は 125 ms となります。
フォアグラウンド処理の変数は以下のとおりです。XXは対象とするフォアグラウンド処理の略称です。
- gTMXXloop: フォアグラウンド処理用のインターバル生成用カウンタ
- TM_XX_NUMBEROFTIMES: フォアグラウンド処理用のインターバル設置値( クロックは 125ms )
- gTMXXeventFlag: フォアグラウンド処理の実行フラグ
データの構造
データの構造は以下のとおりです。
グローバル定義
グローバル定義は以下のとおりです。個々のモジュールや関数に関わるグローバル定数は、それぞれの機能の説明に記載しています。
名 称 | 型 | 値 | 説 明 |
---|---|---|---|
TM_TI_PRESCALER | uint32_t | 800 | タイマのプレイスケーラ値 |
TM_TI_INIT_INTERVAL | uint32_t | 12500 | タイマのオーバーフロー値 |
TM_TI_NUMBEROFTIMES | #define | 8 | 1 s のインターバル生成 |
TM_TS_NUMBEROFTIMES | #define | 8 | BLE の送信間隔 |
TM_MS_NUMBEROFTIMES | #define | 4 | サーボモータの制御間隔 ( Motion Sequencer ) |
グローバル変数
名 称 | 型 | 初期値 | 説 明 |
---|---|---|---|
gTIintFlag | volatile bool * | false | 汎用タイマの割り込み発生時のフラグ |
gTIloop | uint8_t | 0 | 1秒間隔 発生用のカウンタ |
gTIeventFlag | bool | false | 1秒間隔 処理用フラグ |
gTSloop | uint8_t | 0 | BLE 送信用のカウンタ |
gTSeventFlag | bool | false | BLE 送信用の処理用のフラグ |
gMSloop | uint8_t | 0 | Motion Seauencer用のカウンタ |
gMSeventFlag | bool | false | Motion Seauencerの処理用のフラグ |
*:割り込みに関する変数は volatile を指定する場合があります。( 以下参照 )
Technical Considerations volatile 修飾子
割り込みは変数の値が意図しないタイミングで変化する可能性があります。コンパイラは最適化を行う際に変数の値が変化しないと判断すると、不要なメモリアクセスを削除したり、レジスタに値をキャッシュしたりすることにより、本来の変数でない場所へのアクセスを行う可能性が発生します。
volatile 修飾子が適用された変数は、対象とする変数へのアクセス(読み取りや書き込み)は毎回メモリから直接行われます。割り込みは不意に発生しますので、変数が不規則に変更される可能性があることをコンパイラに伝えます。そのため、アクセス(読み取りや書き込み)は毎回メモリから直接行われ、常に正しく変数にアクセスできます。
関数の概要
関数は以下のとおりです。
内部関数
外部から直接アクセスできずモジュール( 特定のスコープ内 )で使用する関数です。
コード
コードは以下のとおりです。
オブジェクト
ハードウエアタイマを使用します。STM32L4 は用途別に10本を超えるタイマを搭載しています。そのうち汎用タイマであるTIM2( タイマ2 )を使用します。
//---------------------------------------------------------------------
// object
//---------------------------------------------------------------------
//------------------------------
// Timer
//------------------------------
HardwareTimer *TItimer = new HardwareTimer( TIM2 );
内部関数
外部から直接アクセスできずモジュール( 特定のスコープ内 )で使用する関数です。
setupTMTIInt()
分 類:
初期化( setup() )
機 能:
汎用タイマ( TIM2 )を初期化する。
関係する関数:
上位関数: setup()
/*----------------------------------------------------------------------------*/
/* Initialize interval timer
/* param : -
/* return : -
/*----------------------------------------------------------------------------*/
void setupTMTCInt()
{
//.... Initialize Timer and Interrupt ....
TItimer->pause();
TItimer->setPrescaleFactor( TM_TI_PRESCALER );
TItimer->setOverflow( TM_TI_INIT_INTERVAL );
TItimer->attachInterrupt( intTimer );
TItimer->refresh();
TItimer->resume();
}
プリスケーラの設定( TM_TI_PRESCALER )、オーバーフロー値の設定( TM_TI_INIT_INTERVAL )、割り込み発生時に実行する関数( intTMtimer() )を登録します。その後、タイマを初期化して動作を始めます。
intTMtimer()
分 類:
割り込み
機 能:
フラグを介してフォアグラウンド処理に伝える。( 割り込み内の処理を低減しています。 )
関係する関数:
ありません。
//==============================================================================
// Interrupt
//==============================================================================
/*----------------------------------------------------------------------------*/
// Timer interrupt / Interval
// Timer interrupt setting for main loop
// param : -
// return : void
/*----------------------------------------------------------------------------*/
void intSVtimer(){
gTIintFlag = true;
}
loopCounter()
分 類:
フォアグラウンド処理
機 能:
タイマ割り込みに合わせて、各フォアグラウンド処理のインターバルを管理する。フォアグラウンド処理の実行可否をフラグを介して伝える。
関係する関数:
loop(): loop()からの呼び出し
//---------------------------------------------------------------------
// Counter
//---------------------------------------------------------------------
void loopCounter(){
//--------------------
// Time Interval period
//--------------------
gTIloop += 1;
if ( gTIloop >= TM_TI_NUMBEROFTIMES ){
gTIloop = 0;
gTIeventFlag = true;
}
//--------------------
// Send Data period
//--------------------
gSDloop += 1;
if ( gSDloop >= TM_TS_NUMBEROFTIMES ){
gSDloop = 0;
gSDeventFlag = true;
}
//--------------------
// SV period
//--------------------
gMSloop += 1;
if ( gMSloop >= TM_MS_NUMBEROFTIMES ){
gMSloop = 0;
gMSeventFlag = true;
}
}
loop()内
分 類:
フォアグラウンド処理( メインループ )
機 能:
タイミング(時間)に関係する各フォアグラウンド処理を実行する。
関係する関数:
loopCounter(): 各フォアグラウンド処理のインターバルを生成する。
各フォアグラウンドでタイミング(時間)に関係する処理
例) procMS(): Motion Sequencer
procBLEtx(): BLE送信
procSNS(): センサ
//=====================================================================
// Main loop
//=====================================================================
void loop(){
//-----------------------------------------------------
// Timer interval 125ms
//-----------------------------------------------------
if ( gTIintFlag == true ){
gTIintFlag = false;
loopCounter();
//--------------------------------------------
// Execute every 1 second.
//--------------------------------------------
if( gTIevent1sFlag == true ){
gTIevent1sFlag = false;
// Implement a process that executes every second.
}
//--------------------------------------------
// Execute every X second / or ms.
//--------------------------------------------
if( gMSeventFlag == true ){
gMSeventFlag = false;
procMS(); // Servomotor sequence control
}
}
//... Other functions
}
参考情報
参考になる情報は以下のとおりです。
このホームページ内
- 複数のMCUをつなぐ: このロボットには複数の MCUが搭載されています。その MCU間の接続の概要です。
他のWebサイト
- SN74LVC1G3157 SPDT アナログスイッチ Datasheet