サンプルプログラム F446RE_MSP2807_ASCII_A の説明
MSP2807_Startup_Screen_ASCII   タッチパネル付きグラフィックLCD
 MSP2807のサンプルプログラムです。

  ASCII文字表示のプログラムを紹介します。

  8x8, 16x16, 32x32, 48x48 のサイズの文字を
 4方向の向きで表示することができます。

  STMicroelectronics社製の評価用基板、NUCLEO-F446RE と
 freeの開発ツール、STM32CubeIDE を使用しています。

  MSP2807は秋月電子通商が販売している、
 2.8インチのタッチパネル付きグラフィックLCDです。



目次

サンプルプログラム F446RE_MSP2807_ASCII_A のプロジェクト

使用しているASCIIフォント の説明
 1) 8x8dot Font ASCII
 2) 16x16dot Font ASCII

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

 F446RE_MSP2807_ASCII_A の動作パラメータの定義
 ユーザープログラムの実行開始位置
 F446RE_MSP2807_ASCII_A のmain()の説明
  1) 初期化の部分
  2) LED点滅 と MSP2807試験 の部分

 MSP2807試験 MSP2807_Test_ASCII_A の説明
  1) MSP2807_Test_ASCII_A のコード
  2) ILI9341 の初期化
  3) 起動画面表示
  4) 数字表示
  5) 時間待ちと数字のカウントアップ

 ASCII文字表示モジュール の使用方法
  1) 通常の使用方法
  2) 並列動作がよくわからない場合

 ASCII文字表示モジュール の説明
  1) 描画Frameの構造体設定
  2) 表示Frame設定 と 描画Bufferの設定
  3) 1Line目の送信データ作成
  4) ILI9341のレジスタ設定と表示Data送信
  5) 残りの1Lineごとの送信データ作成
  6) 残りの1Lineごとのデータ送信と終了判定



  このサンプルプログラムは、
  えがおのでんし製の試験用基板 Base-NUCLEO-64 を使用して動作を確認しています。

Base-NUC64-V1_Dim

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



サンプルプログラム F446RE_MSP2807_ASCII_A のプロジェクト
 STM32CubeIDE 1.10.1 を使用して作成しました。
 ここからサンプルプログラムのプロジェクト R_F446RE_MSP2807_ASCII_A.zip をダウンロードしてください。

  サンプルプログラムのプロジェクトの圧縮ファイルを解凍した後、
 STM32CubeIDEで、そのプロジェクトを開く方法については
既存のプロジェクトを開く方法 をご覧ください。



使用しているASCIIフォント の説明
  このサンプルプログラムでは、ASCII文字のフォント配列を使用しています。
  フォントはプログラムに埋め込まれます。

  ASCII文字を表示するときにASCII文字のコードからフォント配列の位置を算出して
 その位置からフォントを抜き出して使用しています。

1) 8x8dot Font ASCII
   8x8dot の ASCII文字のフォントです。

   Font_ASCII_A/Font_8x8_ASCII_A.c にフォントの配列が記述されています。

2) 16x16dot Font ASCII
   16x16dot の ASCII文字のフォントです。

   Font_ASCII_A/Font_16x16_ASCII_A.c にフォントの配列が記述されています。



サンプルプログラム F446RE_MSP2807_ASCII_A の説明
  タッチパネル付きLCD MSP2807 のASCII文字表示を行うプログラムです。

MSP2807_Startup_Screen_ASCII
  8x8, 16x16, 32x32, 48x48 のサイズの文字を
 いろいろな向きで、表示した後、
 000 から 999 までカウントアップする
 3桁の数字を表示します。


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

F446RE_MSP2807_ASCII_A_Scrn_First

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



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

F446RE_MSP2807_ASCII_A_Tree

  サンプルプログラム F446RE_MSP2807_ASCII_A の構成を以下に示します。
F446RE_MSP2807_ASCII_A
  |- Includes
  |
  |- Blk_LED_Stat : Status LED点滅処理
  |    |- Blk_LED_Stat.c
  |    |- Blk_LED_Stat.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
  |
  |- F446RE_MSP2807_ASCII_A_Config
  |    |- Dev_Conf.h : 動作パラメータの定義
  |
  |- Font_ASCII_A : ASCII文字Fontの配列
  |    |- Font_16x16_ASCII_A.c : ASCII文字Font 16x16dot の配列
  |    |- Font_16x16_ASCII_A.h
  |    |- Font_8x8_ASCII_A.c : ASCII文字Font 8x8dot の配列
  |    |- Font_8x8_ASCII_A.h
  |
  |- Handle_Common : 周辺インターフェースのハンドラ
  |    |- H_Common_GPIO.c
  |    |- H_Common_GPIO.h
  |
  |- Handle_F4 : 周辺インターフェースのハンドラ
  |    |- H_F4_SPI.c
  |    |- H_F4_SPI.h
  |
  |- ILI9341_Display_String_ASCII : ASCII文字表示
  |    |- ILI9341_Display_String_ASCII.c
  |    |- ILI9341_Display_String_ASCII.h
  |
  |- ILI9341_SPI_Lib : ILI9341の制御
  |    |- ILI9341_SPI_Clear_Display.c : 画面表示クリア
  |    |- ILI9341_SPI_Clear_Display.h
  |    |- ILI9341_SPI_Draw.c : ILI9341のレジスタ設定とデータ送信
  |    |- ILI9341_SPI_Draw.h
  |    |- ILI9341_SPI_Init.c : ILI9341初期化
  |    |- ILI9341_SPI_Init.h
  |
  |- ILI9341_Send_RGB : RGBデータの制御
  |    |- ILI9341_Send_RGB.c : 描画のためのRGBデータ送信
  |    |- ILI9341_Send_RGB.h : Color Code, Fontサイズ など各種パラメータの定義
  |
  |- MSP2807_Startup_Screen_ASCII : MSP2807起動画面表示 : ASCII文字
  |    |- MSP2807_Startup_Screen_ASCII.c
  |    |- MSP2807_Startup_Screen_ASCII.h
  |
  |- MSP2807_Test_ASCII_A : MSP2807試験
  |    |- MSP2807_Test_ASCII_A.c
  |    |- MSP2807_Test_ASCII_A.h
  |
  |- String_ASCII : ASCII文字表示
  |    |- String_16x16_ASCII.c : ASCII文字列表示 : 16x16dot
  |    |- String_16x16_ASCII.h
  |    |- String_8x8_ASCII.c : ASCII文字列表示 : 8x8dot
  |    |- String_8x8_ASCII.h
  |
  |- String_Expand_ASCII : ASCII文字拡大表示
  |    |- String_32x32_ASCII.c : 16x16dotのASCII文字を 32x32dotに拡大する。
  |    |- String_32x32_ASCII.h
  |    |- String_48x48_ASCII.c : 16x16dotのASCII文字を 48x48dotに拡大する。
  |    |- String_48x48_ASCII.h
  |
  |- Wait_Interval : 時間待ち処理
  |    |- Wait_Interval.c
  |    |- Wait_Interval.h
  |
  |- F446RE_MSP2807_ASCII_A.launch
  |- STM32F446RETX_FLASH.ld
  |- STM32F446RETX_RAM.ld


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

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



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

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

F446RE_MSP2807_ASCII_A_main

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

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



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



int main(void)
{
  /* USER CODE BEGIN 1 */

  uint8_t uint8_JobNum_LED = 0;
  uint8_t uint8_JobNum_MSP2807 = 0;

  /* 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 */
    //------------------------------------------------------
    // Status LED点滅 : 初期化内蔵
    //------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
    // uint16_t uint16_Time_ON  : 点灯時間
    // uint16_t uint16_Time_OFF : 消灯時間

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //------------------------------------------------------
    Blk_LED_Stat_with_Init(&uint8_JobNum_LED,
                           GLB_uint16_Time_LED_Stat_ON, GLB_uint16_Time_LED_Stat_OFF);


    //------------------------------------------------------------
    // MSP2807試験 : ASCII文字表示 : Font配列使用 : プログラム埋め込み
    //------------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //------------------------------------------------------------
    MSP2807_Test_ASCII_A(&uint8_JobNum_MSP2807);
  }
  /* 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)
{
         .
         .
         .
}
 の、すぐ下に記述されています。


  c) MSP2807の初期化
   MSP2807試験のモジュール MSP2807_Test_ASCII_A 内で
  初期化処理 ILI9341_Initialize を呼びだしています。



 2) LED点滅 と MSP2807試験 の部分
   永久ループ部分の記述を以下に示します。


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

    /* USER CODE BEGIN 3 */
    //------------------------------------------------------
    // Status LED点滅 : 初期化内蔵
    //------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
    // uint16_t uint16_Time_ON  : 点灯時間
    // uint16_t uint16_Time_OFF : 消灯時間

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //------------------------------------------------------
    Blk_LED_Stat_with_Init(&uint8_JobNum_LED,
                           GLB_uint16_Time_LED_Stat_ON, GLB_uint16_Time_LED_Stat_OFF);


    //------------------------------------------------------------
    // MSP2807試験 : ASCII文字表示 : Font配列使用 : プログラム埋め込み
    //------------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //------------------------------------------------------------
    MSP2807_Test_ASCII_A(&uint8_JobNum_MSP2807);
  }
  /* USER CODE END 3 */
  Status LED点滅処理 Blk_LED_Stat_with_Init と  MSP2807試験 MSP2807_Test_ASCII_A を呼び出しています。
  MSP2807_Test_ASCII_A では、起動時の初期画面表示を行います。

  Blk_LED_Stat_with_Init と MSP2807_Test_ASCII_A は並列に実行されます。



 MSP2807試験 MSP2807_Test_ASCII_A の説明

 1) MSP2807_Test_ASCII_A のコード
  以下に、MSP2807_Test_ASCII_A のコードを示します。
//-----------------------------------------------------------
// MSP2807試験 : ASCII文字表示 : Font配列使用 : プログラム埋め込み
//-----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ

// 戻り値:
//   -1 : 処理中
//    0 : OK終了
//    1 : NG終了
//-----------------------------------------------------------
int16_t MSP2807_Test_ASCII_A(uint8_t *puint8_JobNum)
{
  static uint8_t STC_uint8_JobNum_MSP2807;  // MSP2807処理番号

  static uint16_t STC_uint16_Num;  // 数字
  static uint8_t STC_uint8_String[4];  // 表示データ

  static uint8_t STC_uint8_JobNum_Wait;  // 時間待ちの処理番号
  static uint32_t STC_uint32_tikstart;   // 時間待ち開始時のカウント数
  static uint32_t STC_uint32_Interval;   // 待ち時間

  int16_t int16_Return;


  switch(*puint8_JobNum)
  {
  case 0:
    // ILI9341初期化済みを判定
    if(GLB_uint8_Flag_Init_ILI9341 == 0){
      // ILI9341初期化済みでない場合、初期化する。
      //------------------------------------------------------------
      // ILI9341初期化
      //------------------------------------------------------------
      ILI9341_Initialize();

      GLB_uint8_Flag_Init_ILI9341 = 1;  // ILI9341初期化済みをセット
    }

    STC_uint8_JobNum_MSP2807 = 0;  // MSP2807処理番号初期化

    STC_uint16_Num = 0;  // 数字初期化


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

  case 1:
    //------------------------------------------------------------
    // MSP2807起動画面表示 : ASCII
    //------------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //------------------------------------------------------------
    int16_Return = MSP2807_Startup_Screen_ASCII(&STC_uint8_JobNum_MSP2807);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続
    }


    // 数字の文字列を初期化
    STC_uint8_String[0] = (uint8_t)'0';
    STC_uint8_String[1] = (uint8_t)'0';
    STC_uint8_String[2] = (uint8_t)'0';
    STC_uint8_String[3] = 0;


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

  case 2:
    //-----------------------------------------------------------------------
    // font 32 x 32 : ASCII : 数字を表示する。
    //-----------------------------------------------------------------------

    //--------------------------------------------------
    // 横長表示 左
    //--------------------------------------------------
    //---------------------------------------------------------------------------
    // LCD文字表示 : Font選択 : ILI9341 : ASCII
    //---------------------------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // uint16_t uint16_Font : font指定
    //    0 : 8 x 8 font : ASCII
    //    1 : 16 x 16 font : ASCII
    //    2 : 32 x 32 font : ASCII
    //    3 : 48 x 48 font : ASCII

    // uint8_t uint8_Oblong : 縦長/横長
    //    0 : Lengthwise : 縦長 左
    //    1 : Lengthwise : 縦長 右
    //    2 : WidthwiseL : 横長 左
    //    3 : WidthwiseR : 横長 右

    // uint8_t uint8_Type : 表示選択
    //      0 : 通常表示
    //      1 : 反転表示
    //      2 : 通常表示の上書き
    //      3 : 反転表示の上書き

    // uint32_t uint32_ColorCode : カラーコード

    // uint16_t uint16_StartX : 表示開始位置X
    // uint16_t uint16_StartY : 表示開始位置Y

    // uint16_t uint16_Length : 表示文字数
    // uint8_t *puint8_Data : 表示文字コードが格納されているBufferのポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //---------------------------------------------------------------------------
    int16_Return = ILI9341_SPI_Display_String_ASCII(&STC_uint8_JobNum_MSP2807,
                                                    (uint16_t)def_Font_32x32_ASCII,
                                                    def_WidthwiseL, 0,
                                                    (uint32_t)def_Code_White,
                                                    132, 128,
                                                    3, STC_uint8_String);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続
    }


    STC_uint8_JobNum_Wait = 0;  // 時間待ちの処理番号初期化
    STC_uint32_Interval = (uint32_t)1000;  // 待ち時間 : 1000mSec


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

  case 3:
    //------------------------------------------------------
    // mSec待ちシーケンス : 処理番号使用 : 複数呼び出し用
    //------------------------------------------------------
    // 戻り値が -1 以外になるまで、繰り返し呼び出してください。
    //------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号が格納される変数のポインタ

    // uint32_t *puint32_tikstart : 時間待ち開始時のカウント数
    // uint32_t uint32_mSec : 待ち時間(mSec)

    // 戻り値:
    //   -1 : 処理中 : 時間が経過していない。
    //    0 : OK終了 : 時間が経過した。
    //    1 : NG終了
    //------------------------------------------------------
    int16_Return = Wait_mSec_Seq(&STC_uint8_JobNum_Wait,
                                 &STC_uint32_tikstart,
                                 STC_uint32_Interval);
    if(int16_Return == -1){
      // 処理中 : 時間未経過
      break;  // 処理番号維持 : 処理継続 : case 1: をループ
    }


    STC_uint16_Num++;  // 数字をインクリメント
    if(STC_uint16_Num > 999){
      // 数字が 999 を越えたら 0 に戻す。 : 0 - 999 を繰り返す。
      STC_uint16_Num = 0;
    }

    //-------------------------------------------------------------------
    // 数字を3桁の文字列に変換 : ASCII
    //-------------------------------------------------------------------
    // 引数:
    // uint16_t uint16_Num : 数字

    // uint8_t *puint8_String : 3桁の文字列に変換したデータを格納するバッファのポインタ

    // 戻り値:
    //    なし
    //-------------------------------------------------------------------
    Conv_Num_String_3_ASCII(STC_uint16_Num, STC_uint8_String);


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

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

  return(int16_Return);
}

 2) ILI9341 の初期化
   case 0: では、初期化済みフラグ GLB_uint8_Flag_Init_ILI9341 を判定して、
  初期化済みでない場合は、モジュール ILI9341_Initialize を呼び出して
  ILI9341 の初期化を行います。


 3) 起動画面表示
   case 1: では、MSP2807_Startup_Screen_ASCII を呼び出して
  起動画面の表示を行います。

   以下の画面が表示されます。

MSP2807_Startup_Screen_ASCII


 4) 数字表示
   case 2: では、3桁の数字を表示します。
   上記の画面で 562 の部分です。

   数字は case 3: でカウントアップされます。


 5) 時間待ちと数字のカウントアップ
   case 3: では、1000mSec の時間待ちをします。

   1000mSec 経過したら、表示する数字をカウントアップします。
   数字が 999 を超えたら、000 に戻します。
   000 から 999 を繰り返しカウントアップします。

   処理番号を 2 にします。
   case 2: と case 3: を繰り返し実行します。



 ASCII文字表示モジュール の使用方法
  ASCII文字表示モジュール ILI9341_SPI_Display_String_ASCII の使用方法を
 簡単に説明します。

  ASCII文字表示は、ILI9341_Display_String_ASCII/ILI9341_Display_String_ASCII.c 内の
 モジュール ILI9341_SPI_Display_String_ASCII に文字コードなどの引数を渡して行います。


 1) 通常の使用方法
  使用例として MSP2807_Startup_Screen_ASCII/MSP2807_Startup_Screen_ASCII.c 内の
 MSP2807起動画面表示モジュール MSP2807_Startup_Screen_ASCII で
 "Welcom!" を 8 x 8 のフォントで表示している部分を以下に示します。
  case 2:
    //-----------------------------------------------------------------------
    // font 8 x 8 : ASCII : "Welcome!"
    //-----------------------------------------------------------------------

    //--------------------------------------------------
    // 横長表示 左
    //--------------------------------------------------
    //---------------------------------------------------------------------------
    // LCD文字表示 : Font選択 : ILI9341 : ASCII
    //---------------------------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // uint16_t uint16_Font : font指定
    //    0 : 8 x 8 font : ASCII
    //    1 : 16 x 16 font : ASCII
    //    2 : 32 x 32 font : ASCII
    //    3 : 48 x 48 font : ASCII

    // uint8_t uint8_Oblong : 縦長/横長
    //    0 : Lengthwise : 縦長 左
    //    1 : Lengthwise : 縦長 右
    //    2 : WidthwiseL : 横長 左
    //    3 : WidthwiseR : 横長 右

    // uint8_t uint8_Type : 表示選択
    //      0 : 通常表示
    //      1 : 反転表示
    //      2 : 通常表示の上書き
    //      3 : 反転表示の上書き

    // uint32_t uint32_ColorCode : カラーコード

    // uint16_t uint16_StartX : 表示開始位置X
    // uint16_t uint16_StartY : 表示開始位置Y

    // uint16_t uint16_Length : 表示文字数
    // uint8_t *puint8_Data : 表示文字コードが格納されているBufferのポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //---------------------------------------------------------------------------
    int16_Return = ILI9341_SPI_Display_String_ASCII(&STC_uint8_JobNum_LCD,
                                                    (uint16_t)def_Font_8x8_ASCII,
                                                    def_WidthwiseL, 0,
                                                    (uint32_t)def_Code_White,
                                                    0, 0,
                                                    8, (uint8_t *)"Welcome!");
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続
    }

    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;
  それぞれの引数に、目的の値をセットして呼び出しています。

  戻り値が "処理中" でなくなるまで、case 2: をループして繰り返し呼び出します。
  戻り値が "処理中" 以外になったら、次の処理番号に移行します。

 case 3: では "Welcom!" を 16 x 16 のフォントで表示しています。

  MSP2807起動画面表示モジュール MSP2807_Startup_Screen_ASCII では、
 いろいろなサイズと向きでASCII文字を表示しているので、参考にしてください。

 2) 並列動作がよくわからない場合
  以下のように、int16_Return が -1 以外の値になるまで繰り返し呼び出すことにより
 文字列を表示することができます。
  STC_uint8_JobNum_LCD = 0;


  do{
    //-----------------------------------------------------------------------
    // font 8 x 8 : ASCII : "Welcome!"
    //-----------------------------------------------------------------------

    //--------------------------------------------------
    // 横長表示 左
    //--------------------------------------------------
    //---------------------------------------------------------------------------
    // LCD文字表示 : Font選択 : ILI9341 : ASCII
    //---------------------------------------------------------------------------
    int16_Return = ILI9341_SPI_Display_String_ASCII(&STC_uint8_JobNum_LCD,
                                                    (uint16_t)def_Font_8x8_ASCII,
                                                    def_WidthwiseL, 0,
                                                    (uint32_t)def_Code_White,
                                                    0, 0,
                                                    8, (uint8_t *)"Welcome!");
  }while(int16_Return == -1);


 ASCII文字表示モジュール の説明
  ASCII文字表示モジュール ILI9341_Display_String_ASCII の説明を記します。
  ILI9341_Display_String_ASCII/ILI9341_Display_String_ASCII.c に
 記述されています。

 1) 描画Frameの構造体設定
  case 0: では Set_structFrame_ASCII を呼びだして
 表示範囲を、描画Frame設定用の構造体にセットします。
  case 0:
    STC_uint8_JobNum = 0;  // 表示処理番号初期化

    STC_uint16_Position = 0;
    STC_uint16_SendCount = 0;

    STC_uint16_Position_DrawBuffer = 0;


    //----------------------------------------------------------------------------
    // 描画Frameの構造体設定 : ASCII
    //----------------------------------------------------------------------------
    // 引数:
    // uint16_t uint16_Font : font指定
    //    0 : 8 x 8 font : ASCII
    //    1 : 16 x 16 font : ASCII
    //    2 : 32 x 32 font : ASCII
    //    3 : 48 x 48 font : ASCII

    // uint16_t uint16_StartX : 表示開始位置X
    // uint16_t uint16_StartY : 表示開始位置Y

    // uint16_t uint16_Length : 表示文字数

    // struct sFrame_LCD *pstructFrame_LCD : 表示パラメータ構造体のポインタ

    // 戻り値:
    //    0 : OK
    //    1 : NG
    //----------------------------------------------------------------------------
    int16_Return = Set_structFrame_ASCII(uint16_Font,
                                         uint16_StartX, uint16_StartY,
                                         uint16_Length,
                                         &STC_structFrame_LCD);
    if(int16_Return != 0){
      break;  // NG終了
    }


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

 2) 表示Frame設定 と 描画Bufferの設定
  case 1: では ILI9341_SPI_SetFrame を呼びだして、
 描画Frame設定用の構造体 STC_structFrame_LCD の内容を
 表示の向きと範囲を設定するための ILI9341 のレジスタに設定します。

  表示Frame設定が終了したら、Set_DrawBuffer_ASCII を呼び出して
 表示Frame に書き込むための文字列データを
 描画Bufferにセットします。
  case 1:
    //---------------------------------------------------------------------------
    // 表示Frame設定
    //---------------------------------------------------------------------------
    // 表示する向きと表示位置を設定する。
    //---------------------------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // uint16_t uint16_Oblong : 縦長/横長 選択
    //    0 : Lengthwise : 縦長 左
    //    1 : Lengthwise : 縦長 右
    //    2 : WidthwiseL : 横長 左
    //    3 : WidthwiseR : 横長 右

    // struct sFrame_LCD *pstructFrame_LCD : 表示パラメータ構造体のポインタ

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK
    //    1 : NG
    //---------------------------------------------------------------------------
    int16_Return = ILI9341_SPI_SetFrame(&STC_uint8_JobNum,
                                        (uint16_t)uint8_Oblong,
                                        &STC_structFrame_LCD);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続
    }

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


    //----------------------------------------------------------------------------
    // 描画Buffer設定 : ASCII
    //----------------------------------------------------------------------------
    // 引数:
    // uint16_t uint16_Font : font指定
    //    0 : 8 x 8 font : ASCII
    //    1 : 16 x 16 font : ASCII
    //    2 : 32 x 32 font : ASCII
    //    3 : 48 x 48 font : ASCII

    //  uint8_t uint8_Type : 表示選択
    //      0 : 通常表示
    //      1 : 反転表示
    //      2 : 通常表示の上書き
    //      3 : 反転表示の上書き

    // uint16_t uint16_Length : 表示文字数

    // uint8_t *puint8_Char : 文字コードが格納されたBufferのポインタ
    // uint8_t *puint8_Buffer : 描画Bufferのポインタ

    // uint16_t *puint16_Width : 文字の幅の変数のポインタ
    // uint16_t *puint16_Height : 文字の高さの変数のポインタ
    //----------------------------------------------------------------------------
    Set_DrawBuffer_ASCII(uint16_Font,
                         uint8_Type,
                         uint16_Length,
                         puint8_Data, GLB_uint8_DrawBuffer_LCD,
                         &STC_uint16_Width, &STC_uint16_Height);


    STC_uint16_DataSize = STC_uint16_Width / 8;
    if((STC_uint16_Width % 8) > 0){
      STC_uint16_DataSize++;
    }


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

 3) 1Line目の送信データ作成
  case 2: では 1Line目の送信データの作成を行います。
  case 2:
    //----------------------------------------------------------------------
    // 表示Data送信 : case 2: - case 5: で、送信データの作成と送信を行う。
    //----------------------------------------------------------------------
    if(uint8_Type < 0x02){
      // 0 : 通常表示
      // 1 : 反転表示
      for(int16_I = 0; int16_I < (int16_t)(STC_uint16_Width * def_RGB_byte); int16_I++){
        GLB_uint8_Buffer_1Line_LCD[int16_I] = 0;
      }

      //-------------------------------------------------------------------
      // LCD表示用送信データ作成(カラーコード指定)  : RGB 2byte
      //-------------------------------------------------------------------
      //  uint32_t uint32_ColorCode : カラーコード

      //  uint16_t uint16_Width : 表示領域の幅
      // uint16_t uint16_Position : GraphDataの位置
      //  uint8_t *puint8_GraphData : Graphicデータが格納されたBufferのポインタ
      //  uint8_t *puint8_SendData : 送信データを格納するBufferのポインタ
      //-------------------------------------------------------------------
      MakeSendData_1Line_ColorCode_2byte(uint32_ColorCode,
                                         STC_uint16_Width,
                                         STC_uint16_Position,
                                         GLB_uint8_DrawBuffer_LCD,
                                         GLB_uint8_Buffer_1Line_LCD);
    }
    else{
      // 2 : 通常表示の上書き
      // 3 : 反転表示の上書き
      MakeSendData_1Line_ColorCode_2byte(uint32_ColorCode,
                                         STC_uint16_Width,
                                         STC_uint16_Position,
                                         GLB_uint8_DrawBuffer_LCD,
                                         &GLB_uint8_Work_1Line_LCD[STC_uint16_Position_DrawBuffer]);
    }

    // 送信データ数セット
    STC_uint16_SendLength = STC_uint16_Width * def_RGB_byte;


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

 4) ILI9341のレジスタ設定と表示Data送信
  case 3: では ILI9341のレジスタ設定と1Line目の送信データの送信を行います。
  case 3:
    //-----------------------------------------------------------------------
    // ILI9341のレジスタ設定と表示Data送信
    //-----------------------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // int16_t int16_NSS_OnOff : 設定データ送信終了時NSS ON/OFF選択
    //    0 : 送信後 NSSをOFFにする。
    //    1 : 送信後 NSSをONのままにする。

    // uint16_t uint16_Length : 送信データ数
    // uint8_t *puint8_Data : 送信データが格納されているBufferのポインタ

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK
    //    1 : NG
    //-----------------------------------------------------------------------
    if(uint8_Type < 0x02){
      // 0 : 通常表示
      // 1 : 反転表示
      int16_Return = ILI9341_SPI_SendData(&STC_uint8_JobNum,
                                          1,
                                          STC_uint16_SendLength,
                                          GLB_uint8_Buffer_1Line_LCD);
    }
    else{
      // 2 : 通常表示の上書き
      // 3 : 反転表示の上書き
      int16_Return = ILI9341_SPI_SendData(&STC_uint8_JobNum,
                                          1,
                                          STC_uint16_SendLength,
                                          &GLB_uint8_Work_1Line_LCD[STC_uint16_Position_DrawBuffer]);
    }
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続
    }

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


    STC_uint16_SendCount++;  // 送信カウントをインクリメント
    STC_uint16_Position += STC_uint16_DataSize;  // 次のデータ位置をセット
    STC_uint16_Position_DrawBuffer += STC_uint16_SendLength;
                                                 // 描画Bufferの位置を更新


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

 5) 残りの1Lineごとの送信データ作成
  case 4: では 残りの1Lineごとの送信データの作成を行います。
  case 4:
    if(uint8_Type < 0x02){
      // 0 : 通常表示
      // 1 : 反転表示
      for(int16_I = 0; int16_I < (int16_t)(STC_uint16_Width * def_RGB_byte); int16_I++){
        GLB_uint8_SPI1_TxBuffer[int16_I] = 0;
      }

      //-------------------------------------------------------------------
      // LCD表示用送信データ作成(カラーコード指定)  : RGB 2byte
      //-------------------------------------------------------------------
      //  uint32_t uint32_ColorCode : カラーコード

      //  uint16_t uint16_Width : 表示領域の幅
      // uint16_t uint16_Position : GraphDataの位置
      //  uint8_t *puint8_GraphData : Graphicデータが格納されたBufferのポインタ
      //  uint8_t *puint8_SendData : 送信データを格納するBufferのポインタ
      //-------------------------------------------------------------------
      MakeSendData_1Line_ColorCode_2byte(uint32_ColorCode,
                                         STC_uint16_Width,
                                         STC_uint16_Position,
                                         GLB_uint8_DrawBuffer_LCD,
                                         GLB_uint8_SPI1_TxBuffer);
    }
    else{
      // 2 : 通常表示の上書き
      // 3 : 反転表示の上書き
      MakeSendData_1Line_ColorCode_2byte(uint32_ColorCode,
                                         STC_uint16_Width,
                                         STC_uint16_Position,
                                         GLB_uint8_DrawBuffer_LCD,
                                         &GLB_uint8_Work_1Line_LCD[STC_uint16_Position_DrawBuffer]);

      for(uint16_I = 0; uint16_I < (STC_uint16_Width * def_RGB_byte); uint16_I++){
        GLB_uint8_SPI1_TxBuffer[uint16_I]
            = GLB_uint8_Work_1Line_LCD[STC_uint16_Position_DrawBuffer + uint16_I];
      }
    }


    // 送信データ数セット
    GLB_int16_vSPI1_TxNumber = STC_uint16_Width * def_RGB_byte;


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

 6) 残りの1Lineごとのデータ送信と終了判定
  case 5: では 残りの1Lineごとのデータ送信と終了判定を行います。
  終了でない場合、case 4: に戻ります。
  終了するまで、case 4: と case 5: を繰り返します。
  case 5:
    // SPI送信 : データのみ送信
    if(STC_uint16_SendCount == STC_uint16_Height - 1){
      int16_Return = SPI1_Master_TxRxByte(&STC_uint8_JobNum, 0);
    }
    else{
      int16_Return = SPI1_Master_TxRxByte(&STC_uint8_JobNum, 1);
    }
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続
    }

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

    // 終了判定
    STC_uint16_SendCount++;  // 送信カウントをインクリメント
    if(STC_uint16_SendCount < STC_uint16_Height){
      STC_uint16_Position += STC_uint16_DataSize;  // 次のデータ位置をセット
      STC_uint16_Position_DrawBuffer += STC_uint16_SendLength;
                                                   // 描画Bufferの位置を更新

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


    // End : NSS OFF
    HAL_GPIO_WritePin(def_GPIOx_LCD_SPI_NSS, def_GPIO_PIN_x_LCD_SPI_NSS,
                GPIO_PIN_SET);


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


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




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

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

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