サンプルプログラム F4xxxx_AQM1602_I2C1 の説明
マスコット
  I2C 接続の LCD AQM1602 の
 表示を行うサンプルプログラムです。

  AQM1602 は秋月電子通商で販売しています。

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

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

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


目次

LCD AQM1602 の表示の様子

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

えがおのでんし製の評価用IF基板 IF-F4xxxx-I2C の説明

サンプルプログラム F4xxxx_AQM1602_I2C1 のプロジェクト
 1. サンプルプログラム F405RG_AQM1602_I2C1 のプロジェクト
 2. サンプルプログラム F405VG_AQM1602_I2C1 のプロジェクト
 3. サンプルプログラム F446RE_AQM1602_I2C1 のプロジェクト

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

サンプルプログラム F4xxxx_AQM1602_I2C1 の説明
 F4xxxx_AQM1602_I2C1 の構成
 F4xxxx_AQM1602_I2C1 の動作パラメータの定義
 ユーザープログラムの実行開始位置
 F4xxxx_AQM1602_I2C1 の main() の説明
  1) LED点滅 と AQM1602 の表示処理 の部分

 AQM1602 の表示試験 Test_AQM1602 の説明
  1) Test_AQM1602 のソース
  2) Test_AQM1602 の動作

 AQM1602 コマンド書き込み Write_Command_AQM1602 の説明
  1) Write_Command_AQM1602 のソース
  2) Write_Command_AQM1602 の動作

 AQM1602 データ書き込み Write_DataAQM1602 の説明
  1) Write_Data_AQM1602 のソース
  2) Write_Data_AQM1602 の動作



LCD AQM1602 の表示の様子
  AQM1602 を IF-N446RE-I2C 基板に接続して、表示を行っている様子を、
 以下に示します。

AQM1602_with_IF_F446RE_I2C



えがおのでんし製の評価用基板 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基板 の説明 をご覧ください。


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

IF_F4xxxx_I2C_Dim

  IF-F4xxxx-I2C基板については、
 IF_F4xxxx_I2C基板 の説明 をご覧ください。



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


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

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

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


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

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

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


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

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

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



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



サンプルプログラム F4xxxx_AQM1602_I2C1 の説明
  I2C接続のLCD AQM1602 の表示を行うサンプルプログラムです。

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

F405RG_AQM1602_I2C1_Scrn_First

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



サンプルプログラムの構成
  STM32CubeIDEの画面左側、Project Explorerの
 F4xxxx_AQM1602_I2C1を展開した画面は以下のようになります。

F405RG_AQM1602_I2C1_Tree

  サンプルプログラム F4xxxx_AQM1602_I2C1 の構成を以下に示します。

F4xxxx_AQM1602_I2C1
  |
  |- Includes
  |
  |- AQM1602_I2C1_Ope : AQM1602 の操作
  |    |- Control_AQM1602 : AQM1602 の制御
  |    |    |- Control_AQM1602.c
  |    |    |- Control_AQM1602.h
  |    |
  |    |- F405RG_AQM1602_I2C1_Config : 動作パラメータの定義
  |    |    |- Dev_Conf.h
  |    |
  |    |- Test_AQM1602 : AQM1602 の試験
  |         |- Test_AQM1602.c
  |         |- Test_AQM1602.h
  |
  |- Core
  |     |- Inc
  |     |  |- main.h
  |     |  |- stm32f4xx_hal_conf.h
  |     |  |- stm32f4xx_it.h : 割り込み処理モジュールのヘッダ
  |     |
  |     |- Src
  |     |  |- main.c
  |     |  |- stm32f4xx_hal_msp.c
  |     |  |- stm32f4xx_it.c : 割り込み処理モジュールの記述
  |     |  |- syscalls.c
  |     |  |- system.c
  |     |  |- system_stm32f4xx.c
  |     |
  |     |- Startup
  |
  |- Drivers
  |     |- CMSIS
  |     |- STM32F4xx_HAL_Driver
  |
  |- Periph_Lib : 周辺インターフェースのハンドラ
  |    |- H_Common_STM32F4 : 共通ハンドラ
  |    |    |- H_Common_STM32F4_I2C : I2Cの共通ハンドラ
  |    |         |- H_Common_STM32F4_I2C.c
  |    |         |- H_Common_STM32F4_I2C.h
  |    |
  |    |- H_STM32F4_I2C_1 : I2C1のハンドラ
  |         |- H_STM32F4_I2C_1.c
  |         |- H_STM32F4_I2C_1.h
  |
  |- Shared_Lib : 共有ライブラリ
  |    |- Handle_UI_Lib : ユーザーインターフェースのライブラリ
  |    |    |- Blink_LED_ST : ST LED点滅処理
  |    |    |   |-Blink_LED_ST.c
  |    |    |   |-Blink_LED_ST.h
  |    |
  |    |- Time_Interval : 時間待ち処理
  |        |- Time_Interval.c
  |        |- Time_Interval.h
  |
  |- F4xxxx_AQM1602_I2C1.launch
  |- STM32F4xxxxTX_FLASH.ld
  |- STM32F4xxxxTX_RAM.ld



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

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



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

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

F405RG_AQM1602_I2C1_main

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

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



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


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

  /* USER CODE BEGIN 1 */

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

  // while(1){
  // }

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

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


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

  /* 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);



    //----------------------------------------------------------
    // LCD AQM1602 の表示試験
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx :
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK
    //    1 : NG
    //----------------------------------------------------------
    Test_AQM1602(&STC_uint8_JobNum_LCD,
                 &GLB_structParam_Handle_I2C1);
  }
  /* 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_Init はプロジェクト構築時に自動的に組み込まれる、
  HAL Drivers(フォルダ Drivers/STM32F4xx_HAL_Drivers) 内に記述されています。


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

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

   SystemClock_Config(); の設定内容は、

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



 2) LED点滅 と AQM1602 の表示処理 の部分
   永久ループ部分の記述を以下に示します。


  /* 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);



    //----------------------------------------------------------
    // LCD AQM1602 の表示試験
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx :
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK
    //    1 : NG
    //----------------------------------------------------------
    Test_AQM1602(&STC_uint8_JobNum_LCD,
                 &GLB_structParam_Handle_I2C1);
  }
  /* USER CODE END 3 */

  Status LED点滅処理 Blk_LED_Stat と
  AQM1602 の表示試験 Test_AQM1602 を呼び出しています。

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



 AQM1602 の表示試験 Test_AQM1602 の説明


  1) Test_AQM1602 のソース
  モジュール Test_AQM1602 は
 AQM1602_I2C1_Ope/Test_AQM1602/Test_AQM1602.c 内に記述されています。

  モジュール Test_AQM1602 のソースを以下に示します。

//----------------------------------------------------------
// LCD AQM1602 の表示試験
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

// struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx :
//              Handle I2C用パラメータの構造体のポインタ


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

  static uint8_t STC_uint8_Address;       // 設定レジスタAddress
  static uint8_t STC_uint8_Number_TX;     // 送信データ数
  static uint8_t STC_uint8_aData_TX[16];  // 送信データを格納する配列


  int16_t int16_Return;


  switch(*puint8_JobNum)
  {
  case 0:
    //----------------------------------------------------------
    // Handle I2C用パラメータの構造体を初期化
    //----------------------------------------------------------
    // 引数:
    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //    なし
    //----------------------------------------------------------
    Initialize_Parameter_I2Cx(pstructParam_Handle_I2Cx);


    // 送信Bufferのポインタをセット
    pstructParam_Handle_I2Cx->puint8_aI2C_TxBuffer
                                = GLB_uint8_aI2C1_TxBuffer;

    // 受信Bufferのポインタをセット
    pstructParam_Handle_I2Cx->puint8_aI2C_RxBuffer
                                = GLB_uint8_aI2C1_RxBuffer;


    //----------------------------------------------------------
    // Addressing Mode指定
    //----------------------------------------------------------
    // AQM1602 の Addressing Mode
    // Specifies if 7-bit or 10-bit addressing mode is selected.
    //                        7bit : I2C_ADDRESSINGMODE_7BIT
    //                       10bit : I2C_ADDRESSINGMODE_10BIT
    pstructParam_Handle_I2Cx->uint32_AddressingMode
                        = (uint32_t)I2C_ADDRESSINGMODE_7BIT;
    //----------------------------------------------------------


    //----------------------------------------------------------
    // Slave Address指定
    //----------------------------------------------------------
    // AQM1602 の Slave Address
    pstructParam_Handle_I2Cx->uint16_vI2C_SlaveAddress
                        = (uint16_t)def_SlaveAddress_AQM1602;
    //----------------------------------------------------------


    //----------------------------------------------------------
    // Clock Speed指定
    //----------------------------------------------------------
    // AQM1602 の Clock Speed
    pstructParam_Handle_I2Cx->uint32_vI2C_Clock_Speed
                        = (uint32_t)def_I2C_CLOCK_SPEED_100k;
    //----------------------------------------------------------


    //----------------------------------------------------------
    // I2C初期化 : AQM1602
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


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

    if(int16_Return != 0){
      // NG終了
      HAL_I2C_DeInit(&Handle_I2C1);
      pstructParam_Handle_I2Cx->int16_vI2C_Initialize_Done = 0;

      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;
    }


    STC_uint8_JobNum_LCD = 0;  // LCD表示処理番号初期化


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

  case 1:
    //----------------------------------------------------------
    // AQM1602 の初期設定を行う。
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx :
    //              Handle I2C用パラメータの構造体のポインタ


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

    if(int16_Return != 0){
      // NG終了
      HAL_I2C_DeInit(&Handle_I2C1);
      pstructParam_Handle_I2Cx->int16_vI2C_Initialize_Done = 0;

      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;
    }


    STC_uint8_Address = 0x80;  // レジスタアドレスをセット

    // LCD表示データをセット
    STC_uint8_Number_TX = 16;
    memcpy(STC_uint8_aData_TX, "0123456789ABCDEF", 16);


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

  case 2:
    //----------------------------------------------------------
    // AQM1602 データ書き込み
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // uint8_t uint8_Address : データ書き込みアドレス

    // uint8_t uint8_Number_TX : 送信データ数
    // uint8_t *puint8_aData_TX : 送信データを格納するバッファのポインタ

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Write_Data_AQM1602(&STC_uint8_JobNum_LCD,
                                      STC_uint8_Address,
                                      STC_uint8_Number_TX,
                                      STC_uint8_aData_TX,
                                      pstructParam_Handle_I2Cx);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG終了
      HAL_I2C_DeInit(&Handle_I2C1);
      pstructParam_Handle_I2Cx->int16_vI2C_Initialize_Done = 0;

      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;
    }


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


    (*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;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    STC_uint8_Address = 0xC0;

    STC_uint8_Number_TX = 16;
    memcpy(STC_uint8_aData_TX, "GHIJKLMNOPQRSTUV", 16);


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

  case 4:
    //-------------------------------------------------------
    // AQM1602 データ書き込み
    //-------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // uint8_t uint8_Address : データ書き込みアドレス

    // uint8_t uint8_Number_TX : 送信データ数
    // uint8_t *puint8_aData_TX : 送信データを格納するバッファのポインタ

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //-------------------------------------------------------
    int16_Return = Write_Data_AQM1602(&STC_uint8_JobNum_LCD,
                                      STC_uint8_Address,
                                      STC_uint8_Number_TX,
                                      STC_uint8_aData_TX,
                                      pstructParam_Handle_I2Cx);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG終了
      HAL_I2C_DeInit(&Handle_I2C1);
      pstructParam_Handle_I2Cx->int16_vI2C_Initialize_Done = 0;

      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;
    }


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


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

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


    STC_uint8_Number_TX = 1;  // 送信データ数セット

    // コマンドセット
    STC_uint8_aData_TX[0] = 0x01;  // CLEAR DISPLAY


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

  case 6:
    //----------------------------------------------------------
    // AQM1602 コマンド書き込み
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // uint8_t uint8_Number_TX : 送信データ数
    // uint8_t *puint8_aData_TX : 送信データを格納するバッファのポインタ

    // uint32_t uint32_Interval : 待ち時間 (mSec)

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Write_Command_AQM1602(&STC_uint8_JobNum_LCD,
                                         STC_uint8_Number_TX,
                                         STC_uint8_aData_TX,
                                         (uint32_t)3,
                                         pstructParam_Handle_I2Cx);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG終了
      HAL_I2C_DeInit(&Handle_I2C1);
      pstructParam_Handle_I2Cx->int16_vI2C_Initialize_Done = 0;

      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;
    }


    STC_uint8_Address = 0x80;

    STC_uint8_Number_TX = 16;
    memcpy(STC_uint8_aData_TX, "Nice to meet you", 16);


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

  case 7:
    //----------------------------------------------------------
    // AQM1602 データ書き込み
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // uint8_t uint8_Address : データ書き込みアドレス

    // uint8_t uint8_Number_TX : 送信データ数
    // uint8_t *puint8_aData_TX : 送信データを格納するバッファのポインタ

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Write_Data_AQM1602(&STC_uint8_JobNum_LCD,
                                      STC_uint8_Address,
                                      STC_uint8_Number_TX,
                                      STC_uint8_aData_TX,
                                      pstructParam_Handle_I2Cx);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG終了
      HAL_I2C_DeInit(&Handle_I2C1);
      pstructParam_Handle_I2Cx->int16_vI2C_Initialize_Done = 0;

      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;
    }


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


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

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


    STC_uint8_Address = 0xC0;

    STC_uint8_Number_TX = 16;
    memcpy(STC_uint8_aData_TX, "Take it easy!   ", 16);


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

  case 9:
    //----------------------------------------------------------
    // AQM1602 データ書き込み
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // uint8_t uint8_Address : データ書き込みアドレス

    // uint8_t uint8_Number_TX : 送信データ数
    // uint8_t *puint8_aData_TX : 送信データを格納するバッファのポインタ

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Write_Data_AQM1602(&STC_uint8_JobNum_LCD,
                                      STC_uint8_Address,
                                      STC_uint8_Number_TX,
                                      STC_uint8_aData_TX,
                                      pstructParam_Handle_I2Cx);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG終了
      HAL_I2C_DeInit(&Handle_I2C1);
      pstructParam_Handle_I2Cx->int16_vI2C_Initialize_Done = 0;

      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;
    }


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


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

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


    STC_uint8_Number_TX = 1;  // 送信データ数セット

    // コマンドセット
    STC_uint8_aData_TX[0] = 0x01;  // CLEAR DISPLAY


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

  case 11:
    //----------------------------------------------------------
    // AQM1602 コマンド書き込み
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // uint8_t uint8_Number_TX : 送信データ数
    // uint8_t *puint8_aData_TX : 送信データを格納するバッファのポインタ

    // uint32_t uint32_Interval : 待ち時間 (mSec)

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Write_Command_AQM1602(&STC_uint8_JobNum_LCD,
                                         STC_uint8_Number_TX,
                                         STC_uint8_aData_TX,
                                         (uint32_t)3,
                                         pstructParam_Handle_I2Cx);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG終了
      HAL_I2C_DeInit(&Handle_I2C1);
      pstructParam_Handle_I2Cx->int16_vI2C_Initialize_Done = 0;

      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;
    }


    STC_uint8_Address = 0x80;

    STC_uint8_Number_TX = 16;
    memcpy(STC_uint8_aData_TX, "0123456789ABCDEF", 16);


    *puint8_JobNum = 2;  // 処理番号 2 に移行する。: case 2:
                         // case 2: ~ case 11: をループする。
    int16_Return = -1;   // 処理継続
    break;

  default:
    *puint8_JobNum = 0;
    int16_Return = 1;
    break;  // NG
  }

  return(int16_Return);
}


 2) Test_AQM1602 の動作

  a) case 0:
    AQM1602表示に使用する I2C1 を初期化します。

  b) case 1:
    AQM1602 の初期設定を行います。

  b) case 2:
    表示データ "0123456789ABCDEF" を AQM1602 の 1行目に書き込みます。

    表示結果は以下のようになります。
Disp_AQM1602_1

  c) case 3:
    1000mSec 待ちます。

  d) case 4:
    表示データ "GHIJKLMNOPQRSTUV" を AQM1602 の 2行目に書き込みます。

    表示結果は以下のようになります。
Disp_AQM1602_2

  e) case 5:
    1000mSec 待ちます。

  f) case 6:
    AQM1602 の表示をクリアします。

  g) case 7:
    表示データ "Nice to meet you" を AQM1602 の 1行目に書き込みます。

    表示結果は以下のようになります。
Disp_AQM1602_3

  h) case 8:
    1000mSec 待ちます。

  i) case 9:
    表示データ "Take it easy! " を AQM1602 の 2行目に書き込みます。

    表示結果は以下のようになります。
Disp_AQM1602_4

  j) case 10:
    1000mSec 待ちます。

  k) case 11:
    AQM1602 の表示をクリアします。

    クリア動作終了後、表示データバッファ STC_uint8_aData_TX に
   "0123456789ABCDEF" をセットして、処理番号に 2 をセットします。

    Test_AQM1602 の処理は、再び case 2: から実行されます。
    こうして、Test_AQM1602 の処理は、case 2: - case 11: をループします。



 AQM1602 コマンド書き込み Write_Command_AQM1602 の説明


  1) Write_Command_AQM1602 のソース
    モジュール Write_Command_AQM1602 は
    AQM1602_I2C1_Ope/Control_AQM1602/Control_AQM1602.c 内に記述されています。

    モジュール Write_Command_AQM1602 のソースを以下に示します。

//----------------------------------------------------------
// AQM1602 コマンド書き込み
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

// uint8_t uint8_Number_TX : 送信データ数
// uint8_t *puint8_aData_TX : 送信データを格納するバッファのポインタ

// uint32_t uint32_Interval : 待ち時間 (mSec)

// struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
//              Handle I2C用パラメータの構造体のポインタ


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

  static uint8_t STC_uint8_Count_TX;   // 送信回数カウンタ


  int16_t int16_Return;


  switch(*puint8_JobNum)
  {
  case 0:
    STC_uint8_JobNum_I2C = 0;  // I2C処理番号初期化
    STC_uint8_Count_TX = 0;    // 送信回数カウンタ初期化


    // I2C送信データセット
    pstructParam_Handle_I2Cx->puint8_aI2C_TxBuffer[0] = 0x00;
                                            // control bytee
    pstructParam_Handle_I2Cx->puint8_aI2C_TxBuffer[1]
                        = puint8_aData_TX[STC_uint8_Count_TX];
                                // data byte : Instruction

    pstructParam_Handle_I2Cx->uint16_vI2C_TxNumber
                                = (volatile uint16_t)2;


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

  case 1:
    //----------------------------------------------------------
    // I2Cx Master送信 :
    //          Register指定 1byte + 設定データ 1byteを送信
    //----------------------------------------------------------
    //引数 :
    // uint8_t *puint8_JobNum : 処理番号

    // I2C_HandleTypeDef *pHandle_I2Cx : I2C handler declaration

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    //戻り値 :
    //   -1 : 処理中
    //    0 : OK
    //    1 : NG
    //----------------------------------------------------------
    int16_Return = I2Cx_Master_TxByte(&STC_uint8_JobNum_I2C,
                                      &Handle_I2C1,
                                      pstructParam_Handle_I2Cx);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG終了
      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;
    }


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


    (*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;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    STC_uint8_Count_TX++;  // 送信回数カウンタ インクリメント

    // 送信回数判定
    if(STC_uint8_Count_TX < uint8_Number_TX){
      // 指定された送信回数に達していない。

      // I2C送信データセット
      pstructParam_Handle_I2Cx->puint8_aI2C_TxBuffer[1]
                        = puint8_aData_TX[STC_uint8_Count_TX];
                                    // data byte : Instructio

      *puint8_JobNum = 1;  // 処理番号 1 に戻る。: case 1:
                           // case 1: ~ case 2: をループする。
      int16_Return = -1;   // 処理継続
      break;
    }


    *puint8_JobNum = 0;  // 処理番号初期化
    // int16_Return : 結果
    break;  // 処理終了

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

  return(int16_Return);
}


  2) Write_Command_AQM1602 の動作

   a) case 0:
     I2C処理番号初期化 と 送信回数カウンタ初期化 を行い、
    送信データバッファ STC_uint8_aData_TX に
    control byte と Instruction をセットします。

   b) case 1:
     AQM1602 に control byte と Instruction を送信します。

   c) case 2:
     指定された時間を待ちます。

     時間待ち終了後、送信回数を判定します。

     送信回数に達していない場合
      STC_uint8_aI2C_TX[1] に次の Instruction をセットして、
     処理番号を 1 にします。

      送信回数に達するまで case 1: と case 2: をループします。

     送信回数に達した場合
      処理番号を 0 にして、処理を終了します。


 AQM1602 データ書き込み Write_Data_AQM1602 の説明


  1) Write_Data_AQM1602 のソース
    モジュール Write_Data_AQM1602 は
    AQM1602_I2C1_Ope/Control_AQM1602/Control_AQM1602.c 内に記述されています。

    モジュール Write_Data_AQM1602 のソースを以下に示します。

//----------------------------------------------------------
// AQM1602 データ書き込み
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

// uint8_t uint8_Address : データ書き込みアドレス

// uint8_t uint8_Number_TX : 送信データ数
// uint8_t *puint8_aData_TX : 送信データを格納するバッファのポインタ

// struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
//              Handle I2C用パラメータの構造体のポインタ


// 戻り値:
//   -1 : 処理中
//    0 : OK終了
//    1 : NG終了
//----------------------------------------------------------
int16_t Write_Data_AQM1602(uint8_t *puint8_JobNum,
                           uint8_t uint8_Address,
                           uint8_t uint8_Number_TX,
                           uint8_t *puint8_aData_TX,
            struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx)
{
  static uint8_t STC_uint8_JobNum_I2C;  // I2C処理番号

  static uint8_t STC_uint8_Count_TX;  // 送信回数カウンタ
  static uint8_t STC_uint8_aData_TX[4];  // 送信データを格納する配列


  int16_t int16_Return;


  switch(*puint8_JobNum)
  {
  case 0:
    STC_uint8_JobNum_I2C = 0;  // I2C処理番号初期化
    STC_uint8_Count_TX = 0;    // 送信回数カウンタ初期化

    // 送信データセット
    STC_uint8_aData_TX[0] = uint8_Address;  // 表示アドレス


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

  case 1:
    //-------------------------------------
    // 表示アドレスセット
    //-------------------------------------
    //----------------------------------------------------------
    // AQM1602 コマンド書き込み
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // uint8_t uint8_Number_TX : 送信データ数
    // uint8_t *puint8_aData_TX : 送信データを格納するバッファのポインタ

    // uint32_t uint32_Interval : 待ち時間 (mSec)

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Write_Command_AQM1602(&STC_uint8_JobNum_I2C,
                                         (uint8_t)1,
                                         STC_uint8_aData_TX,
                                         (uint32_t)2,
                                         pstructParam_Handle_I2Cx);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG終了
      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;  // 処理終了
    }


    // 送信データセット
    pstructParam_Handle_I2Cx->puint8_aI2C_TxBuffer[0] = 0x40;
                                            // control byte
    pstructParam_Handle_I2Cx->puint8_aI2C_TxBuffer[1]
                        = puint8_aData_TX[STC_uint8_Count_TX];
                                    // data byte ; 表示データ

    pstructParam_Handle_I2Cx->uint16_vI2C_TxNumber
                                    = (volatile uint16_t)2;


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

  case 2:
    //------------------------------------
    // 表示データ書き込み
    //------------------------------------
    //----------------------------------------------------------
    // I2Cx Master送信
    //----------------------------------------------------------
    //引数:
    // uint8_t *puint8_JobNum : 処理番号

    // I2C_HandleTypeDef *pHandle_I2Cx : I2C handler declaration

    // struct sParam_Handle_I2Cx  *pstructParam_Handle_I2Cx
    //              Handle I2C用パラメータの構造体のポインタ


    //戻り値 :
    //   -1 : 処理中
    //    0 : OK
    //    1 : NG
    //----------------------------------------------------------
    int16_Return = I2Cx_Master_TxByte(&STC_uint8_JobNum_I2C,
                                      &Handle_I2C1,
                                      pstructParam_Handle_I2Cx);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG終了
      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;  // 処理終了
    }


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

  case 3:
    //---------------------------------------------------
    // LCD AQM1602 のビジーチェック
    //---------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK
    //    1 : NG
    //---------------------------------------------------
    int16_Return = Check_Busy_AQM1602(&STC_uint8_JobNum_I2C);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : case 3: をループ
    }

    if(int16_Return != 0){
      // NG終了
      *puint8_JobNum = 0;  // 処理番号初期化
      // int16_Return : 結果
      break;  // 処理終了
    }


    STC_uint8_Count_TX++;  // 送信回数カウンタ インクリメント

    // 送信回数判定
    if(STC_uint8_Count_TX < uint8_Number_TX){
      // 指定された送信回数に達していない。

      // 送信データセット
      pstructParam_Handle_I2Cx->puint8_aI2C_TxBuffer[1]
                        = puint8_aData_TX[STC_uint8_Count_TX];
                                    // data byte ; 表示データ

      *puint8_JobNum = 2;  // 処理番号 2 に移行する。: case 2:
      int16_Return = -1;   // 処理継続
      break;
    }


    *puint8_JobNum = 0;  // 処理番号初期化
    // int16_Return : 結果
    break;  // 処理終了

  default:
    *puint8_JobNum = 0;
    int16_Return = 1;
    break;  // NG
  }

  return(int16_Return);
}


  2) Write_Data_AQM1602 の動作

   a) case 0:
     I2C処理番号初期化 と 送信回数カウンタ初期化 を行い、
    送信データバッファ STC_uint8_aData_TX[0] に
    指定された表示アドレスをセットします。

   b) case 1:
     モジュール Write_Command_AQM1602 により
    AQM1602 に 表示アドレスをセットします。

     Write_Command_AQM1602 の処理終了後、
    送信データバッファ STC_uint8_aData_TX に
    control byte と 表示データ および データ数 をセットします。

   c) case 2:
     I2C通信により送信データバッファのデータを送信します。

   d) case 3:
     モジュール Check_Busy_AQM1602 により、ビジーをチェックします。

     AQM1602 はI2Cインターフェースを使用する場合、ビジーフラグ BF を
    読み込むことができないため、時間待ちで対応しています。

     ビジーチェック終了後、送信回数を判定します。

     送信回数に達していない場合
      STC_uint8_aI2C_TX[1] に次の 表示データ をセットして、
     処理番号を 2 にします。

      送信回数に達するまで case 2: と case 3: をループします。

     送信回数に達した場合
      処理番号を 0 にして、処理を終了します。


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




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

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

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