処理番号を使用した組み込み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

 なんでも、気軽に ご相談ください。
 担当:おの

マスコット
  えがおのでんし 案内