処理番号を使用した組み込みCプログラミング
処理番号を使用した、
C言語による組み込みプログラム
について説明します。
目次
処理番号を使用したプログラムの説明
LED点滅処理のプログラムモジュール Blink_LED_ST を例に説明します。
1. 処理番号を使用したプログラムの書き方
2. Blink_LED_ST のプログラムコード
3. Blink_LED_ST の説明
4. モジュール内の変数について(重要)
処理番号を使用したプログラムの説明
処理番号を使用して、順番に個々の処理を実行することにより、
一連の動作を実現する方法について説明します。
以下、LED点滅処理のプログラムモジュール Blink_LED_ST を例に説明します。
1. 処理番号を使用したプログラムの書き方
処理番号を使用したプログラムの書き方について
LED点滅の場合を例に説明します。
処理番号を使用したプログラムは、
switch-case文を使用して記述します。
以下のように記述して処理番号によりプログラムを動作させます。
switch(処理番号)
{
case 0: // 処理番号 0
LED点滅処理用パラメータを初期化する。
処理番号を 1 にする。 // 次の処理番号(case 1:)に移行する。
break;
case 1: // 処理番号 1
LED接続ピンを初期化する。
LEDを点灯する。
待ち時間をセットする。
処理番号を 2 にする。 // 次の処理番号(case 2:)に移行する。
break;
case 2: // 処理番号 2
if(指定時間が経過したかを判定){
// 経過していない場合
break; // 指定時間が経過するまで、case 2: をループする。
}
LEDを消灯する。
待ち時間をセットする。
処理番号を 3 にする。 // 次の処理番号(case 3:)に移行する。
break;
case 3: // 処理番号 3
if(指定時間が経過したかを判定){
// 経過していない場合
break; // 指定時間が経過するまで、case 3: をループする。
}
LEDを点灯する。
待ち時間をセットする。
処理番号 2 にする。 // 次の処理番号(case 2:)に移行する。
break;
}
このプログラムは、処理番号 0 と 処理番号 1 を実行した後、
処理番号 2 と 処理番号 3 を繰り返し実行します。
その結果、消灯した後、指定時間の経過待ち と
点灯した後、指定時間の経過待ち を繰り返すので
LEDが点滅します。
2. Blink_LED_ST のプログラムコード
LED点滅の例 : Blink_LED_ST のプログラムコードを以下に示します。
//----------------------------------------------------------
// ST LED点滅
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// struct sParam_Blink_LED_ST *pstructParam_Blink_LED_ST :
// ST LED点滅用パラメータの構造体のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG
//----------------------------------------------------------
int16_t Blink_LED_ST(uint8_t *puint8_JobNum,
struct sParam_Blink_LED_ST *pstructParam_Blink_LED_ST)
{
//----------------------------------------------------
// 呼び出す関数の引数に使用する処理番号は、
// 必ず static の変数宣言をしてください。
//----------------------------------------------------
static uint8_t STC_uint8_JobNum_Time; // Time_Interval処理番号
//--------------------------------------------------------
// Time_Interval用パラメータの構造体の宣言は、
// 使用する関数内で、必ず static で宣言してください。
//--------------------------------------------------------
// Time_Interval用パラメータの構造体の宣言
//--------------------------------------------------------
static struct sParam_Time_Interval STC_structParam_Time_Interval;
int16_t int16_Return;
//--------------------------------------------------------
// ST LED再起動フラグチェック
//--------------------------------------------------------
if(pstructParam_Blink_LED_ST->int16_Restart_LED_ST == 1){
// ST LED再起動フラグONの場合
*puint8_JobNum = 1; // 処理番号を 1 にする。
pstructParam_Blink_LED_ST->int16_Restart_LED_ST = 0;
// ST LED再起動フラグOFF
}
//--------------------------------------------------------
switch(*puint8_JobNum)
{
case 0:
//--------------------------------------------------
// 1回だけ case 0: を実行します。
// その後は、case 2: ~ case 3: をループします。
//--------------------------------------------------
//----------------------------------------------------------
// ST LED点滅処理用パラメータ初期化
//----------------------------------------------------------
pstructParam_Blink_LED_ST->int16_LED_ST_Init_Done = 0;
// Status LED 初期化済みフラグ
pstructParam_Blink_LED_ST->int16_Restart_LED_ST = 0;
// Status LED再起動フラグ
pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON = 1000;
// Status LED点灯時間(mSec)
pstructParam_Blink_LED_ST->uint16_Time_LED_ST_OFF = 2000;
// Status LED消灯時間(mSec)
//----------------------------------------------------------
(*puint8_JobNum)++; // 次の処理番号に移行する。
int16_Return = -1; // 処理継続
break;
case 1:
//------------------------------------------------------
// 最初の 1回目は無条件で case 1: を実行します。
// その後は ST LED再起動フラグ が ON になった場合に
// 実行します。
//------------------------------------------------------
// ST LED 初期化済みフラグ判定
if(pstructParam_Blink_LED_ST->int16_LED_ST_Init_Done != 1){
// ST LED が初期化済みでない場合
//------------------------------------------------
// ST LEDのGPIO初期化
//------------------------------------------------
Initialize_LED_ST();
pstructParam_Blink_LED_ST->int16_LED_ST_Init_Done = 1;
// ST LED 初期化済み をセット
}
//----------------------------------------------
// ST LED点灯
//----------------------------------------------
LED_ST_ON();
STC_uint8_JobNum_Time = 0; // Time_Interval処理番号初期化
STC_structParam_Time_Interval.uint32_Interval
= (uint32_t)pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON;
// 待ち時間セット
(*puint8_JobNum)++; // 次の処理番号に移行する。
int16_Return = -1; // 処理継続
break;
case 2:
//----------------------------------------------------------
// 時間待ち : 単位 mSec
//----------------------------------------------------------
// 戻り値が -1 以外になるまで、繰り返し呼び出してください。
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// struct sParam_Time_Interval *pstructParam_Time_Interval :
// Time_Interval用パラメータの構造体のポインタ
// 戻り値:
// -1 : 処理中 : 時間が経過していない。
// 0 : OK終了 : 時間が経過した。
// 1 : NG終了
//----------------------------------------------------------
int16_Return = Time_Interval(&STC_uint8_JobNum_Time,
&STC_structParam_Time_Interval);
if(int16_Return == -1){
// 処理中 : 時間未経過
break; // 処理番号維持 : 処理継続 : 現在の処理番号をループ
}
//----------------------------------------------
// ST LED消灯
//----------------------------------------------
LED_ST_OFF();
STC_uint8_JobNum_Time = 0; // Time_Interval処理番号初期化
STC_structParam_Time_Interval.uint32_Interval
= (uint32_t)pstructParam_Blink_LED_ST->uint16_Time_LED_ST_OFF;
// 待ち時間セット
(*puint8_JobNum)++; // 次の処理番号に移行する。
int16_Return = -1; // 処理継続
break;
case 3:
//----------------------------------------------------------
// 時間待ち : 単位 mSec
//----------------------------------------------------------
// 戻り値が -1 以外になるまで、繰り返し呼び出してください。
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// struct sParam_Time_Interval *pstructParam_Time_Interval :
// Time_Interval用パラメータの構造体のポインタ
// 戻り値:
// -1 : 処理中 : 時間が経過していない。
// 0 : OK終了 : 時間が経過した。
// 1 : NG終了
//----------------------------------------------------------
int16_Return = Time_Interval(&STC_uint8_JobNum_Time,
&STC_structParam_Time_Interval);
if(int16_Return == -1){
// 処理中 : 時間未経過
break; // 処理番号維持 : 処理継続 : 現在の処理番号をループ
}
//------------------------------------------------
// ST LED点灯
//------------------------------------------------
LED_ST_ON();
STC_uint8_JobNum_Time = 0; // Time_Interval処理番号初期化
STC_structParam_Time_Interval.uint32_Interval
= (uint32_t)pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON;
// 待ち時間セット
*puint8_JobNum = 2; // 処理番号 2 に移行する。: case 2:
// case 2: ~ case 3: をループ
int16_Return = -1; // 処理継続
break;
default:
*puint8_JobNum = 0; // 処理番号初期化
int16_Return = 1; // NG終了
break;
}
return(int16_Return);
}
3. Blink_LED_ST の説明
*puint8_JobNum が処理番号です。この変数は呼び出し側で 0 に初期化します。
この switch case文のモジュールを繰り返し呼び出すことにより、
処理番号の処理を順次、実行します。
switch case文の、処理番号 *puint8_JobNum を使用して1個ずつ処理を進めていきます。
1個の処理が完了したら処理番号 *puint8_JobNum をインクリメント または セットして、
次の処理番号に移行します。
それぞれの case の処理を以下に記します。
1) case 0:
a) ST LED点滅処理用パラメータを初期化します。
b) 処理番号をインクリメントして次に実行する処理を case 1: にします。
2) case 1:
a) ST LED 初期化済みフラグを判定して、初期化済みでない場合、
ST LED接続ピンのGPIOを初期化します。
b) ST LED を点灯します。
c) 時間待ち処理モジュールのためのTime_Interval処理番号を初期化します。
d) 点灯時間をセットします。
e) 処理番号をインクリメントして次に実行する処理を case 2: にします。
3) case 2:
a) 時間待ちモジュール Time_Interval を呼び出し、
戻り値を判定します。
時間が経過していない場合、break して、case 2: を繰り返し実行します。
時間が経過したら以下の処理を実行します。
b) ST LEDを消灯します。
c) 時間待ち処理モジュールのためのTime_Interval処理番号を初期化します。
d) 消灯時間をセットします。
e) 処理番号をインクリメントして次に実行する処理を case 3: にします。
4) case 3:
a) 時間待ちモジュール Time_Interval を呼び出し、
戻り値を判定します。
時間が経過していない場合、break して、case 3: を繰り返し実行します。
時間が経過したら以下の処理を実行します。
b) ST LEDを点灯します。
c) 時間待ち処理モジュールのためのTime_Interval処理番号を初期化します。
d) 点灯時間をセットします。
e) 処理番号に 2 をセットして次に実行する処理を case 2: にします。
この後、プログラムは case 2: と case 3: を繰り返し実行します。
これにより、ST LEDは点滅します。
4. モジュール内の変数について(重要)
モジュール Blink_LED_ST 内では、
以下の2個の変数を static 宣言しています。
//----------------------------------------------------
// 呼び出す関数の引数に使用する処理番号は、
// 必ず static の変数宣言をしてください。
//----------------------------------------------------
static uint8_t STC_uint8_JobNum_Time; // Time_Interval処理番号
//--------------------------------------------------------
// Time_Interval用パラメータの構造体の宣言は、
// 使用する関数内で、必ず static で宣言してください。
//--------------------------------------------------------
// Time_Interval用パラメータの構造体の宣言
//--------------------------------------------------------
static struct sParam_Time_Interval STC_structParam_Time_Interval;
その理由は、一度、モジュールからリターンした後、
次にまた呼び出されたときに、変数の値が保持されている必要があるためです。
モジュール内で static 宣言した変数は値が保持されます。
処理番号を使用したプログラムの作成において、
非常に重要なことなので、覚えておいてください。
上記に示したLED点滅処理のモジュールは サンプルプログラム F4xxxx_LED_USW の
Shared_Lib/Handle_UI_Lib/Blink_LED_ST/Blink_LED_ST.cに記述されています。
このサンプルプログラム F4xxxx_LED_USW は、
USERスイッチを押すごとにLEDの点滅間隔が変化するという処理を行います。
LED点滅とスイッチ入力のプログラムが並列に動作します。
処理番号を使用して記述することにより、
複数のモジュールを並列に実行することが可能になります。
メールアドレス: apm2c.sumi@gmail.com
なんでも、気軽に ご相談ください。
担当:おの
えがおのでんし 案内