サンプルプログラム F4xxxx_USW_Beep の説明
マスコット   Beep発生の処理を
 行うプログラムです。

  スイッチを押すごとに、
 ”ぴっ”というBeepを発生します。


  F4xxxx は、
  F405RG, F405VG, F446RE のいずれかです。

  それぞれの種類に応じて、F4xxxx の部分を読み代えてください。
  プログラムの内容は共通です。

  サンプルプログラムの動作を確認するために
 えがおのでんし製の評価用基板 Base-F4xxxx
 STMicroelectronics社のfreeの開発ツール、
 STM32CubeIDE を使用しています。



目次

えがおのでんし製の評価用基板 Base-F4xxxx の説明
 1. Base-F405RG基板 の説明
 2. Base-F405VG基板 の説明
 3. Base-F446RE基板 の説明

サンプルプログラム F4xxxx_USW_Beep のプロジェクト
 1. サンプルプログラム F405RG_USW_Beep のプロジェクト
 2. サンプルプログラム F405VG_USW_Beep のプロジェクト
 3. サンプルプログラム F446RE_USW_Beep のプロジェクト

 既存のプロジェクトを開く

サンプルプログラム F4xxxx_USW_Beep の説明
 F4xxxx_USW_Beep の構成

 F4xxxx_USW_Beep の動作パラメータの定義
 ユーザープログラムの実行開始位置

 F4xxxx_USW_Beep の main() の説明
  1) 初期化の部分
  2) LED点滅 と USERスイッチ押下検出とBeep 処理の部分

 各モジュールの説明
  1) Blink_LED_ST
  2) Detects_Pressed_USW_and_Beep
  3) Detects_Pressed_USW
  4) Generate_Beep



えがおのでんし製の評価用基板 Base-F4xxxx の説明
  このサンプルプログラムは、
  えがおのでんし製の評価用基板 Base-F4xxxx を使用して動作を確認しています。


 1. Base-F405RG基板 の説明
Base_F405RG_Dim

  Base-F405RG基板については、
 Base-F405RG基板 の説明 をご覧ください。


 2. Base-F405VG基板 の説明
Base_F405VG_Dim

  Base-F405VG基板については、
 Base-F405VG基板 の説明 をご覧ください。


 3. Base-F446RE基板 の説明
Base_F446RE_Dim

  Base-F446RE基板については、
 Base-F446RE基板 の説明 をご覧ください。



サンプルプログラム F4xxxx_USW_Beep のプロジェクト
 STM32CubeIDE 1.17.0 を使用して作成しました。


1. サンプルプログラム F405RG_USW_Beep のプロジェクト
 ここからサンプルプログラム L_F405RG_USW_Beep.zip をダウンロードしてください。

  プロジェクト L_F405RG_USW_Beep は、
 フォルダ C:\Project_CubeIDE\Launch_F405RG\L_F405RG_USW_Beep のように配置して作成しました。

  フォルダ C:\Project_CubeIDE\Launch_F405RG を作成して、
 そのフォルダに L_F405RG_USW_Beep.zip を貼り付けて解凍し、
 プロジェクト作成時と同一に C:\Project_CubeIDE\Launch_F405RG\L_F405RG_USW_Beep と
 配置した場合は、普通にプロジェクトを開くことができます。


2. サンプルプログラム F405VG_USW_Beep のプロジェクト
 ここからサンプルプログラム L_F405VG_USW_Beep.zip をダウンロードしてください。

  プロジェクト L_F405VG_USW_Beep は、
 フォルダ C:\Project_CubeIDE\Launch_F405VG\L_F405VG_USW_Beep のように配置して作成しました。

  フォルダ C:\Project_CubeIDE\Launch_F405VG を作成して、
 そのフォルダに L_F405VG_USW_Beep.zip を貼り付けて解凍し、
 プロジェクト作成時と同一に C:\Project_CubeIDE\Launch_F405VG\L_F405VG_USW_Beep と
 配置した場合は、普通にプロジェクトを開くことができます。


3. サンプルプログラム F446RE_USW_Beep のプロジェクト
 ここからサンプルプログラム L_F446RE_USW_Beep.zip をダウンロードしてください。

  プロジェクト L_F446RE_USW_Beep は、
 フォルダ C:\Project_CubeIDE\Launch_F446RE\L_F446RE_USW_Beep のように配置して作成しました。

  フォルダ C:\Project_CubeIDE\Launch_F446RE を作成して、
 そのフォルダに L_F446RE_USW_Beep.zip を貼り付けて解凍し、
 プロジェクト作成時と同一に C:\Project_CubeIDE\Launch_F446RE\L_F446RE_USW_Beep と
 配置した場合は、普通にプロジェクトを開くことができます。



既存のプロジェクトを開く
  サンプルプログラムのプロジェクトを任意のフォルダに配置した場合に、
 STM32CubeIDEにより、そのプロジェクトを開く方法については
既存のプロジェクトを開く方法 をご覧ください。



サンプルプログラム F4xxxx_USW_Beep の説明
  Base-F4xxxx基板上の SP1 (基板取付用小型ダイナミックスピーカー UGCM0603APE)の
 Beepを発生させるサンプルプログラムです。

  UGCM0603APE は、直径 6.7mm、厚み 3.6mm の小さいスピーカーです。

  USERスイッチ SW1 を押下すると”ぴっ”と鳴ります。

 プロジェクトを最初に開いた画面は以下のようになります。

 以下に、F405RG の場合の画面を示します。

LED_USW_Scrn_First

 以下、サンプルプログラム F4xxxx_USW_Beep について説明していきます。

  F4xxxx は、F405RG, F405VG, F446RE のいずれかです。



 F4xxxx_USW_Beep の構成
  STM32CubeIDEの画面左側、Project Explorerの
 F4xxxx_USW_Beep を展開した画面は以下のようになります。

  F405RG_USW_Beep の場合の画面を以下にしまします。

F4xxxx_USW_Beep_Tree

  サンプルプログラム F4xxxx_USW_Beep の構成を以下に示します。
F4xxxx_USW_Beep
  |
  |- Includes
  |
  |- Core
  |    |- Inc
  |    |    |- main.h
  |    |    |- stm32f4xx_hal_conf.h
  |    |    |- stm32f4xx_it.h
  |    |
  |    |- Src
  |    |    |- main.c
  |    |    |- stm32f4xx_hal_msp.c
  |    |    |- stm32f4xx_it.c
  |    |    |- syscalls.c
  |    |    |- sysmem.c
  |    |    |- system_stm32f4xx.c
  |    |
  |    |- Startup
  |
  |- Drivers
  |
  |- Periph_Lib
  |    |- H_Common_STM32F4 : 周辺インターフェース共通処理
  |         |- H_Common_STM32F4_PWM_1CH : PWMハンドラ
  |              |- H_Common_STM32F4_PWM_1CH.c
  |              |- H_Common_STM32F4_PWM_1CH.h
  |
  |- Shared_Lib
  |    |- Handle_UI_Lib
  |    |    |- Blink_LED_ST : ST LED点滅処理
  |    |    |   |-Blink_LED_ST.c
  |    |    |   |-Blink_LED_ST.h
  |    |    |
  |    |    |- Detects_Pressed_USW : USERスイッチ押下検出処理
  |    |    |    |- Detects_Pressed_USW.c
  |    |    |    |- Detects_Pressed_USW.h
  |    |    |
  |    |    |- Generate_Beep : Beep発生処理
  |    |         |- Generate_Beep.c
  |    |         |- Generate_Beep.h
  |    |
  |    |- Time_Interval : 時間待ち処理
  |        |- Time_Interval.c
  |        |- Time_Interval.h
  |
  |- USW_Beep_Ope
  |    |- Detect_Pressed_USW_and_Beep : USERスイッチ押下検出とBeep発生処理
  |    |    |- Detect_Pressed_USW_and_Beep.c
  |    |    |- Detect_Pressed_USW_and_Beep.h
  |    |
  |    |- F4xxxx_USW_Beep_Config : 動作パラメータの定義
  |        |- Dev_Conf.h
  |
  |- F4xxxx_USW_Beep.launch
  |- STM32F4xxxxTX_FLASH.ld
  |- STM32F4xxxxTX_RAM.ld



 F4xxxx_USW_Beep の動作パラメータの定義
  サンプルプログラム F4xxxx_USW_Beep の動作パラメータの定義を
  LED_USW_Ope/F4xxxx_USW_Beep_Config/Dev_Conf.h に記述しています。

  使用する CPU の定義、ヘッダ名の定義、GPIO のポートとピンの定義、
 などを記述しています。



 ユーザープログラムの実行開始位置
  プログラムは、int main(void) から実行開始します。

  int main(void) は、フォルダ Core/Src/main.c にあります。

  F405RG_USW_Beep の場合の画面を以下にしまします。

F405RG_USW_Beep_main

  STM32CubeIDEでビルドされたプログラムは、自動的にCPUの初期化を
 行った後、int main(void) を呼び出します。

  ユーザーコード(記述したプログラム)は、
 int main(void) の先頭から実行されます。



 F4xxxx_USW_Beep の main() の説明
  サンプルプログラム F4xxxx_USW_Beep の main() の記述は、
 以下のとおりです。


/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  //-----------------------------------------------------------------
  // main関数内では、以下の処理番号の変数、
  // STC_uint8_JobNum_LED と
  // STC_uint8_JobNum_USW_Beep は

  // while(1){
  // }

  // の永久ループ内で使用しているので、
  // static宣言をする必要はない。

  // しかし、main関数以外の全ての関数内では
  // 処理番号をstatic宣言をする必要があるので、
  // 合わせるために、ここでも static宣言をしている。
  //-----------------------------------------------------------------
  static uint8_t STC_uint8_JobNum_LED;       // LED点滅処理番号
  static uint8_t STC_uint8_JobNum_USW_Beep;  // USW and Beep処理番号


  //------------------------------------------------------------
  // 呼び出す関数を case 0: から実行させるために
  // 処理番号に 0 をセットします。
  //------------------------------------------------------------
  STC_uint8_JobNum_LED = 0;       // LED点滅処理番号初期化
  STC_uint8_JobNum_USW_Beep = 0;  // USW and Beep処理番号初期化

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    //------------------------------------------------------
    // ST LED点滅
    //------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Blink_LED_ST *pstructParam_Blink_LED_ST :
    //              ST LED点滅用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //------------------------------------------------------
    Blink_LED_ST(&STC_uint8_JobNum_LED,
                 &GLB_structParam_Blink_LED_ST);


    //----------------------------------------------------------
    // USERスイッチ押下検出とBeep
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //----------------------------------------------------------
    Detects_Pressed_USW_and_Beep(&STC_uint8_JobNum_USW_Beep);
  }
  /* USER CODE END 3 */
}


 1) 初期化の部分

  a) CPUのPeripheral初期化
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
   により、CPUのPeripheralなどの基本的な初期化を行います。
  PeripheralとはCPUの周辺インターフェースなどのことを言います。

   プロジェクト構築時に自動的に組み込まれる、
  HAL Drivers(フォルダ Drivers/STM32F4xx_HAL_Drivers) 内に記述されています。


  b) CPU動作クロックの設定
  /* Configure the system clock */
  SystemClock_Config();

   CPUの動作クロックとPeripheralの動作クロックを設定します。

   SystemClock_Config(); の設定内容は、

int main(void)
{
         .
         .
         .
}
 の、すぐ下に記述されています。



 2) ST LED点滅 と USERスイッチ押下検出とBeep 処理の部分
   永久ループ部分の記述を以下に示します。


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    //------------------------------------------------------
    // ST LED点滅
    //------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Blink_LED_ST *pstructParam_Blink_LED_ST :
    //              ST LED点滅用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //------------------------------------------------------
    Blink_LED_ST(&STC_uint8_JobNum_LED,
                 &GLB_structParam_Blink_LED_ST);


    //----------------------------------------------------------
    // USERスイッチ押下検出とBeep
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //----------------------------------------------------------
    Detects_Pressed_USW_and_Beep(&STC_uint8_JobNum_USW_Beep);
  }
  /* USER CODE END 3 */


  ST LED点滅処理 Blink_LED_ST と
 USERスイッチ押下検出とBeep処理 Detects_Pressed_USW_and_Beep を
 呼び出しています。

  Detects_Pressed_USW_and_Beep では、
 Detects_Pressed_USW でスイッチの押下が検出された場合、
 Beep発生を行い、”ぴっ”という音を鳴らします。

  Blink_LED_ST と Detects_Pressed_USW_and_Beep は並列に実行されます。



 各モジュールの説明



 1) Blink_LED_ST
  ST LEDを点滅します。

  Shared_Lib/Handle_UI_Lib/Blink_LED_ST のフォルダに記述されています。

  以下に、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 1: を実行後、
    // case 2: ~ case 3: をループします。
    //--------------------------------------------------


    //----------------------------------------------------------
    // ST LED点滅処理用パラメータ初期化
    //----------------------------------------------------------
    pstructParam_Blink_LED_ST->int16_LED_ST_Init_Done = 0;
                            // ST LED 初期化済みフラグ

    pstructParam_Blink_LED_ST->int16_Restart_LED_ST = 0;
                            // ST LED再起動フラグ

    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON = 1000;
                            // ST LED点灯時間(mSec)
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_OFF = 2000;
                            // ST 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);
}

 a) case 0:
  i) ST LED点滅処理用パラメータを初期化します。
  ii) 処理番号をインクリメントして次に実行する処理を case 1: にします。

 b) case 1:
  i) ST LED 初期化済みフラグを判定して、初期化済みでない場合、    ST LED接続ピンのGPIOを初期化します。
  ii) ST LED を点灯します。
  iii) 時間待ち処理モジュールのためのTime_Interval処理番号を初期化します。
  iv) 点灯時間をセットします。
  v) 処理番号 *puint8_JobNum をインクリメントして
   次に実行する処理を case 2: にします。

 c) case 2:
  i) 時間待ちモジュール Time_Interval を呼び出し、
   戻り値を判定します。
   時間が経過していない場合、break します。
   *puint8_JobNumが 2 のまま抜けるので、次にモジュールが呼び出されると
   再び case 2: が実行されます。
   時間が経過するまで case 2: を繰り返し実行します。
   時間が経過したら以下の処理を実行します。
  ii) ST LEDを消灯します。
  iii) 時間待ち処理モジュールのためのTime_Interval処理番号を初期化します。
  iv) 消灯時間をセットします。
  v) 処理番号 *puint8_JobNum をインクリメントして
   次に実行する処理を case 3: にします。

 d) case 3:
  i) 時間待ちモジュール Time_Interval を呼び出し、
   戻り値を判定します。
   時間が経過していない場合、break します。
   *puint8_JobNumが 3 のまま抜けるので、次にモジュールが呼び出されると
   再び case 3: が実行されます。
   時間が経過するまで case 3: を繰り返し実行します。
   時間が経過したら以下の処理を実行します。
  ii) ST LEDを点灯します。
  iii) 時間待ち処理モジュールのためのTime_Interval処理番号を初期化します。
  iv) 点灯時間をセットします。
  v) 処理番号 *puint8_JobNum に 2 をセットして
   次に実行する処理を case 2: にします。


   この後、プログラムは case 2: と case 3: を繰り返し実行します。
   これにより、ST LEDは点滅します。



 2) Detects_Pressed_USW_and_Beep
  USERスイッチの押下検出を行い、押下を検出した場合、
 Beep発生を行い”ぴっ”という音を鳴らします。

  LED_USW_Ope/Detects_Pressed_USW_and_Beep のフォルダに記述されています。

  以下に、Detects_Pressed_USW_and_Beepのコードを示します。
//---------------------------------------------------------
// USERスイッチ押下検出とBeep
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ


// 戻り値:
//   -1 : 処理中
//    0 : OK終了
//    1 : NG
//----------------------------------------------------------
int16_t Detects_Pressed_USW_and_Beep(uint8_t *puint8_JobNum)
{
  //----------------------------------------------------
  // 呼び出す関数の引数に使用する処理番号は、
  // 必ず static の変数宣言をしてください。
  //----------------------------------------------------
  static uint8_t STC_uint8_JobNum_USW;   // USW処理番号
  static uint8_t STC_uint8_JobNum_Beep;  // Beep処理番号


  int16_t int16_Return;


  switch(*puint8_JobNum){
  case 0:
    STC_uint8_JobNum_USW = 0;   // USW処理番号初期化
    STC_uint8_JobNum_Beep = 0;  // Beep処理番号初期化


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 1:
    //-----------------------------------------------------------
    // USERスイッチ押下検出
    //-----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ


    // 戻り値:
    //   -1 : 検出なし
    //    0 : 検出あり
    //-----------------------------------------------------------
    int16_Return = def_M_Detect_USW(&STC_uint8_JobNum_USW);
    if(int16_Return == -1){
      // 検出なし
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 2:
    //----------------------------------------------------------
    // Beepを発生する。
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // int16_t int16_Time_Beep : Beepを発生する時間


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Generate_Beep(&STC_uint8_JobNum_Beep,
                                 (int16_t)def_Time_Beep);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    *puint8_JobNum = 1;  // USERスイッチ検出処理に移行する。: case 1:
                         // case 1: と case 2: を繰り返し実行する。
    int16_Return = 0;    // OK : 処理が1回終了
    break;

  default:
    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = 1;    // NG終了
    break;
  }

  return(int16_Return);
}

 a) case 0:
  i) USERスイッチ検出処理番号とBeep処理番号の初期化を行います。
  ii) 処理番号 *puint8_JobNum をインクリメントして、次に実行する処理を case 1: にします。

 b) case 1:
  i) USERスイッチ の押下検出を行います。
   押下検出がない場合、break します。
   *puint8_JobNumが 1 のまま抜けるので、次にモジュールが呼び出されると
   再び case 1: が実行されます。
   押下検出があるまで、case 1: を繰り返し実行します。
   USERスイッチの押下を検出したら以下の処理を実行します。

  ii) 処理番号 *puint8_JobNum をインクリメントして、次に実行する処理を case 2: にします。

 c) case 2:
  i) Beepを発生します。”ぴっ”という音が鳴ります。
   処理が終了するのを待ちます。
   終了でない場合、break します。
   *puint8_JobNumが 2 のまま抜けるので、次にモジュールが呼び出されると
   再び case 2: が実行されます。
   処理が終了するまで、case 2: を繰り返し実行します。
   処理が終了したら以下の処理を実行します。

  ii) 処理番号 *puint8_JobNum に 1 をセットして
   次に実行する処理を case 1: にします。


   この後、プログラムは case 1: と case 2: を繰り返し実行します。

   USERスイッチ を押下するごとに、
  Beepが発生して、”ぴっ”と鳴ります。



 3) Detects_Pressed_USW
  USERスイッチ の押下検出を行います。

  USERスイッチ が押下されたら、チャタリング防止処理を行って、
 チャタリングではないと判断した場合、USERスイッチ押下検出ありをセットします。

  Shared_Lib/Handle_UI_Lib/Detects_Pressed_USW のフォルダに記述されています。

  以下に、Detects_Pressed_USWのコードを示します。
//----------------------------------------------------------
// USERスイッチ押下検出
//----------------------------------------------------------
// 引数;
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ


// 戻り値;
//   -1 : 検出なし
//    0 : 検出あり
//----------------------------------------------------------
int16_t Detects_Pressed_USW(uint8_t *puint8_JobNum)
{
  //----------------------------------------------------
  // 呼び出す関数の引数に使用する処理番号は、
  // 必ず static の変数宣言をしてください。
  //----------------------------------------------------
  static uint8_t STC_uint8_JobNum_Time;  // Time_Interval処理番号

  //------------------------------------------------------
  // Time_Interval用パラメータの構造体の宣言は、
  // 使用する関数内で、必ず static で宣言してください。
  //------------------------------------------------------
  // Time_Interval用パラメータの構造体の宣言
  //------------------------------------------------------
  static struct sParam_Time_Interval STC_structParam_Time_Interval;


  GPIO_PinState gpio_PinState;

  int16_t int16_Return;


  switch(*puint8_JobNum)
  {
  case 0:
    //--------------------------------------------------
    // 1回だけ case 0: を実行します。

    // その後は、case 1: を実行後、
    // case 2: ~ case 7: をループします。
    //--------------------------------------------------


    GLB_int16_USW_Init_Done = 0;  // USERスイッチ 初期化済みフラグ 初期化


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 1:
    // USERスイッチ 初期化済みフラグ判定
    if(GLB_int16_USW_Init_Done == 0){
      // USERスイッチ 初期化済みフラグが OFF の場合

      //----------------------------------------------
      // USERスイッチ入力ピン初期化
      //----------------------------------------------
      def_M_Initialize_USW();

      GLB_int16_USW_Init_Done = 1;  // USERスイッチ 初期化済みフラグ ON
    }


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 2:
    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_OFF){
      // USERスイッチは押されていない。
      int16_Return = -1;  // 処理継続
      break;  // 処理番号維持 : 現在の処理番号をループ
    }


    STC_uint8_JobNum_Time = 0;  // Time_Interval処理番号初期化
    STC_structParam_Time_Interval.uint32_Interval
        = (uint32_t)def_Time_Cancel_Chatt;  // 待ち時間をセット


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 3:  // チャタリング検出 1回目
    //----------------------------------------------------------
    // 時間待ち : 単位 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;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_OFF){
      // USERスイッチは押されていない。
      *puint8_JobNum = 2;
                // USERスイッチの状態入力に戻る。 : case 2:
      int16_Return = -1;   // 処理継続
      break;
    }


    STC_uint8_JobNum_Time = 0;  // Time_Interval処理番号初期化
    STC_structParam_Time_Interval.uint32_Interval
        = (uint32_t)def_Time_Cancel_Chatt;  // 待ち時間をセット


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 4:  // チャタリング検出 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;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_OFF){
      // USERスイッチは押されていない。
      *puint8_JobNum = 2;
                // USERスイッチの状態入力に戻る。 : case 2:
      int16_Return = -1;   // 処理継続
      break;
    }


    STC_uint8_JobNum_Time = 0;  // Time_Interval処理番号初期化
    STC_structParam_Time_Interval.uint32_Interval
        = (uint32_t)def_Time_Cancel_Chatt;  // 待ち時間をセット


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 5:  // チャタリング検出 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;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_OFF){
      // USERスイッチは押されていない。
      *puint8_JobNum = 2;
                // USERスイッチの状態入力に戻る。: case 2:
      int16_Return = -1;   // 処理継続
      break;
    }


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 6:
    //----------------------------------------------------------
    // USERスイッチがOFFになるのを待つ。
    //----------------------------------------------------------
    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_ON){
      // USERスイッチは押されている。
      int16_Return = -1;
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    STC_uint8_JobNum_Time = 0;  // Time_Interval処理番号初期化
    STC_structParam_Time_Interval.uint32_Interval
        = (uint32_t)def_Time_Release_SW;  // 待ち時間をセット


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 7:
    //----------------------------------------------------------
    // USERスイッチがOFFになった後、少し待つ。
    //----------------------------------------------------------

    //----------------------------------------------------------
    // 時間待ち : 単位 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;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    *puint8_JobNum = 2;  // 処理番号 2 に移行する。: case 2:
                         // case 2: ~ case 7: をループ
    int16_Return = 0;    // USERスイッチ押下検出ありをセット
    break;

  default:
    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = -1;   // 処理継続
    break;
  }

  return(int16_Return);
}

 a) case 0:
  i) USERスイッチ 初期化済みフラグ を初期化します。
  ii) 処理番号 *puint8_JobNum をインクリメントして、次に実行する処理を case 1: にします。

 b) case 1:
  i) USERスイッチ 初期化済みフラグを判定して、初期化済みでない場合、    USERスイッチ接続ピンのGPIOを初期化します。
  ii) 処理番号 *puint8_JobNum をインクリメントして次に実行する処理を case 2: にします。

 c) case 2:
  i) USERスイッチ が押されるのを待ちます。
   USERスイッチ が押されていない場合、break します。
   *puint8_JobNumが 2 のまま抜けるので、次にモジュールが呼び出されると
   再び case 2: が実行されます。
   USERスイッチ が押されるまで case 2: を繰り返し実行します。
   USERスイッチ が押されたら以下の処理を実行します。

  ii) チャタリング検出時間をセットします。
  iii) 処理番号 *puint8_JobNum をインクリメントして
   次に実行する処理を case 3: にします。

 d) case 3:
   チャタリング検出 1回目を行います。

  i) 時間待ちモジュール Time_Interval を呼び出し、
   戻り値を判定します。
   時間が経過していない場合、break します。
   *puint8_JobNum が 3 のまま抜けるので、次にモジュールが呼び出されると
   再び case 3: が実行されます。
   時間が経過するまで case 3: を繰り返し実行します。
   時間が経過したら以下の処理を実行します。

  ii) USERスイッチ の状態をみて、押されていない場合、
   処理番号*puint8_JobNum を 2 にして、次に実行する処理を case 2: にします。

   USERスイッチ が押されたままなら、チャタリング検出時間をセットします。

  iii) 処理番号 *puint8_JobNum をインクリメントして
   次に実行する処理を case 4: にします。

 e) case 4:
   チャタリング検出 2回目を行います。

 f) case 5:
   チャタリング検出 3回目を行います。

 g) case 6:
  i) USERスイッチ がOFFになるのを待ちます。
   USERスイッチ が押されている場合、break します。
   *puint8_JobNumが 6 のまま抜けるので、次にモジュールが呼び出されると
   再び case 6: が実行されます。
   USERスイッチ がOFFになるまで case 6: を繰り返し実行します。
   USERスイッチ がOFFになったら以下の処理を実行します。

  ii) OFF待ち時間をセットします。

  iii) 処理番号 *puint8_JobNum をインクリメントして
   次に実行する処理を case 7: にします。

 h) case 7:
  i) 時間待ちモジュール Time_Interval を呼び出し、
   戻り値を判定します。
   時間が経過していない場合、break します。
   *puint8_JobNum が 7 のまま抜けるので、次にモジュールが呼び出されると
   再び case 7: が実行されます。
   時間が経過するまで case 7: を繰り返し実行します。
   時間が経過したら以下の処理を実行します。

  ii) 処理番号 *puint8_JobNum に 2 をセットして
   次に実行する処理を case 2: にします。

  iii) 戻り値を USERスイッチ 押下検出ありにします。


   この後、プログラムは case 2: ~ case 7: を繰り返し実行します。



 4) Generate_Beep
  Beepを発生します。”ぴっ”と鳴ります。

  Shared_Lib/Handle_UI_Lib/Generate_Beep/Generate_Beep.c に記述されています。

  以下に、Generate_Beepのコードを示します。

//----------------------------------------------------------
// Beepを発生する。
//----------------------------------------------------------
// 引数;
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

// int16_t int16_Time_Beep : Beepを発生する時間


// 戻り値;
//   -1 : 処理中
//    0 : OK終了
//    1 : NG終了
//----------------------------------------------------------
int16_t Generate_Beep(uint8_t *puint8_JobNum,
                      int16_t int16_Time_Beep)
{
  //----------------------------------------------------
  // 呼び出す関数の引数に使用する処理番号は、
  // 必ず 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;


  switch(*puint8_JobNum)
  {
  case 0:
    // Beep PWM初期化フラグチェック
    if(GLB_int16_Flag_Initialize_Beep_PWM <= 0){
      //------------------------------------------------
      // Beepに使用するPWMの初期化
      //------------------------------------------------
      Initialize_Beep_PWM();

      GLB_int16_Flag_Initialize_Beep_PWM = 1;
    }


    //-----------------------------------------------------------
    // Beep_PWM : 比率を50%に設定 : Beep ON
    //----------------------------------------------------------
    // CH1出力 : Beep_PWM
    Configure_PWM(&GLB_struct_TIM_Handle_Beep_PWM,
                  (TIM_TypeDef *)def_TIMx_Beep_PWM,
                  def_TIM_CHANNEL_x_Beep_PWM,
                  (uint32_t)500);
    //----------------------------------------------------------


    STC_uint8_JobNum_Time = 0;  // Time_Interval処理番号初期化

    // Beepを発生する時間をセット
    STC_structParam_Time_Interval.uint32_Interval
                                = (uint32_t)int16_Time_Beep;


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 1:
    //----------------------------------------------------------
    // 時間待ち : 単位 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;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    //----------------------------------------------------------
    // Beep_PWM : OFF
    //----------------------------------------------------------
    // CH1出力 : Beep_PWM
    Configure_PWM(&GLB_struct_TIM_Handle_Beep_PWM,
                  (TIM_TypeDef *)def_TIMx_Beep_PWM,
                  def_TIM_CHANNEL_x_Beep_PWM,
                  (uint32_t)0);
    //----------------------------------------------------------


    *puint8_JobNum = 0;  // 処理番号初期化 : case 0: に移行する。
    int16_Return = 0;    // OK終了
    break;

  default:
    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = 1;    // NG
    break;
  }

  return(int16_Return);
}

 a) case 0:
  i) Beep PWM 初期化済みフラグ をチェックして、
   初期化済みでない場合、Beepに使用するPWMを初期化します。

  ii) Beep PWM の比率を50%に設定し、BeepをONします。

  iii) Time_Interval処理番号を初期化し、Beep発生時間をセットします。

  iv) 処理番号 *puint8_JobNum をインクリメントして、次に実行する処理を case 1: にします。

 b) case 1:
  i) 時間待ちモジュール Time_Interval を呼び出し、
   戻り値を判定します。
   時間が経過していない場合、break します。
   *puint8_JobNum が 1 のまま抜けるので、次にモジュールが呼び出されると
   再び case 3: が実行されます。
   時間が経過するまで case 1: を繰り返し実行します。
   時間が経過したら以下の処理を実行します。

  ii) Beep PWMをOFFします。

  iii) 処理番号に 0 をセットして、
   次に実行する処理を case 0: にします。

   これで処理終了です。



A+-2C (ええ加減にC) のページに戻る




 メールアドレス: apm2c.sumi@gmail.com

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

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