サンプルプログラム F405xG_MSP2807_String の説明
タッチパネル付きグラフィックLCD
MSP2807のサンプルプログラムです。
ASCII文字 と 日本語 を表示するプログラムを紹介します。
16x16, 32x32, 48x48 のサイズの文字を
4方向の向きで表示することができます。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
文字表示モジュールの引数に
(uint8_t *)"ようこそ!" のように
直接、日本語を指定して、日本語表示を行うことができます。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
F405xG は、
F405RG か F405VG のいずれかです。
それぞれの種類に応じて、F405xG の部分を読み代えてください。
プログラムの内容は共通です。
サンプルプログラムの動作を確認するために
えがおのでんし製の評価用基板 Base-F405xG と
STMicroelectronics社のfreeの開発ツール、
STM32CubeIDE を使用しています。
MSP2807は秋月電子通商が販売している、
2.8インチのタッチパネル付きグラフィックLCDです。
目次
えがおのでんし製の評価用基板 Base-F405xG の説明
1. Base-F405RG基板 の説明
2. Base-F405VG基板 の説明
STM32CubeIDEの日本語設定について
サンプルプログラム F405xG_MSP2807_String のプロジェクト
1. サンプルプログラム F405RG_MSP2807_String のプロジェクト
2. サンプルプログラム F405VG_MSP2807_String のプロジェクト
既存のプロジェクトを開く
1. 使用しているASCIIフォント の説明
1) 8x8dot Font ASCII
2) 16x16dot Font ASCII
2. 使用している日本語フォント の説明
16x16dot Font UTF-16
サンプルプログラム F405xG_MSP2807_String の説明
F405xG_MSP2807_String の構成
F405xG_MSP2807_String の動作パラメータの定義
ユーザープログラムの実行開始位置
F405xG_MSP2807_String のmain()の説明
1) 初期化の部分
2) LED点滅 と MSP2807試験 の部分
MSP2807試験 MSP2807_Test_String の説明
1) MSP2807_Test_String のコード
2) 初期化
3) 起動画面表示
4) 数字表示
5) 時間待ちと数字のカウントアップ
文字表示モジュール の使用方法
1) 通常の使用方法
2) 並列動作がよくわからない場合
文字表示モジュール の説明
1) 描画Frameの構造体設定
2) 表示Frame設定 と 描画Bufferの設定
3) 1Line目の送信データ作成
4) ILI9341のレジスタ設定と表示Data送信
5) 残りの1Lineごとの送信データ作成
6) 残りの1Lineごとのデータ送信と終了判定
えがおのでんし製の評価用基板 Base-F405xG の説明
このサンプルプログラムは、
えがおのでんし製の評価用基板 Base-F405xG を使用して動作を確認しています。
1. Base-F405RG基板 の説明

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

Base-F405VG基板については、
Base-F405VG基板 の説明 をご覧ください。
STM32CubeIDEの日本語設定について
サンプルプログラム F405xG_MSP2807_String を実行するために
開発ツール STM32CubeIDE の設定において Colors and Fonts の
Text Font の文字設定を日本語にする必要があります。
STM32CubeIDE の日本語設定については、
STM32CubeIDEの日本語設定 をご覧ください。
サンプルプログラム F405xG_MSP2807_String のプロジェクト
STM32CubeIDE 1.18.0 を使用して作成しました。
1. サンプルプログラム F405RG_MSP2807_String のプロジェクト
ここからサンプルプログラム L_F405RG_MSP2807_String.zip をダウンロードしてください。
プロジェクト L_F405RG_MSP2807_String は、
フォルダ C:\Project_CubeIDE\Launch_F405RG\L_F405RG_MSP2807_String のように配置して作成しました。
フォルダ C:\Project_CubeIDE\Launch_F405RG を作成して、
そのフォルダに L_F405RG_MSP2807_String.zip を貼り付けて解凍し、
プロジェクト作成時と同一に C:\Project_CubeIDE\Launch_F405RG\L_F405RG_MSP2807_String と
配置した場合は、普通にプロジェクトを開くことができます。
2. サンプルプログラム F405VG_MSP2807_String のプロジェクト
ここからサンプルプログラム L_F405VG_MSP2807_String.zip をダウンロードしてください。
プロジェクト L_F405VG_MSP2807_String は、
フォルダ C:\Project_CubeIDE\Launch_F405VG\L_F405VG_MSP2807_String のように配置して作成しました。
フォルダ C:\Project_CubeIDE\Launch_F405VG を作成して、
そのフォルダに L_F405VG_MSP2807_String.zip を貼り付けて解凍し、
プロジェクト作成時と同一に C:\Project_CubeIDE\Launch_F405VG\L_F405VG_MSP2807_String と
配置した場合は、普通にプロジェクトを開くことができます。
既存のプロジェクトを開く
サンプルプログラムのプロジェクトを任意のフォルダに配置した場合に、
STM32CubeIDEにより、そのプロジェクトを開く方法については
既存のプロジェクトを開く方法 をご覧ください。
1. 使用しているASCIIフォント の説明
ASCII文字表示に、ASCII文字のフォント配列を使用しています。
フォントはプログラムに埋め込まれます。
ASCII文字を表示するときにASCII文字のコードからフォント配列の位置を算出して
その位置からフォントを抜き出して使用しています。
1) 8x8dot Font ASCII
8x8dot の ASCII文字のフォントです。
MSP2807_Lib/Font_Lib/Font_ASCII_A/Font_ASCII_8x8_A.c にフォントの配列が記述されています。
2) 16x16dot Font ASCII
16x16dot の ASCII文字のフォントです。
MSP2807_Lib/Font_Lib/Font_ASCII_A/Font_ASCII_16x16_A.c にフォントの配列が記述されています。
2. 使用している日本語フォント の説明
日本語文字表示に、UTF-16の日本語文字のフォント配列を使用しています。
フォントはプログラムに埋め込まれます。
日本語文字を表示するときに
UnicodeのUTF-8文字コードからUTF-16文字コードに変換して、
UTF-16文字コードからフォント配列の位置を算出して
その位置からフォントを抜き出して使用しています。
16x16dot Font UTF-16
Unicode の 16x16dot の UTF-16のフォント配列です。
MSP2807_Lib/Font_Lib/Font_UTF16_16x16_A/Font_UTF16_16x16_A.c に
フォントの配列が記述されています。
日本語表示に必要な部分のみ、記述しています。
サンプルプログラム F405xG_MSP2807_String の説明
タッチパネル付きLCD MSP2807 に ASCII と 日本語 の文字表示を行うプログラムです。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
文字表示モジュールの引数に
(uint8_t *)"ようこそ!" のように
直接、日本語を指定して、日本語表示を行うことができます。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
16x16, 32x32, 48x48 のサイズの文字を
いろいろな向きで、表示した後、
000 から 999 までカウントアップする
3桁の数字を表示します。
プロジェクトを最初に開いた画面は以下のようになります。

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

サンプルプログラム F405xG_MSP2807_String の構成を以下に示します。
F405xG_MSP2807_String
|- Includes
|
|- Core
| |- Inc
| | |- main.h
| | |- stm32l4xx_hal_conf.h
| | |- stm32l4xx_it.h : 割り込み処理モジュールのヘッダ
| |
| |- Src
| | |- main.c
| | |- stm32l4xx_hal_msp.c
| | |- stm32l4xx_it.c : 割り込み処理モジュール
| | |- syscalls.c
| | |- system.c
| | |- system_stm32l4xx.c
| |
| |- Startup
|
|- Drivers
|
|- MSP2807_Lib
| |- Calc_Address_Font : Font Address算出 : UTF-16
| | |- Calc_Address_Font_UTF16_16x16.c
| | |- Calc_Address_Font_UTF16_16x16.h
| |
| |- Color_Lib
| | |- Color_Code.h : Color Codeの定義
| |
| |- Draw_Buffer_Lib
| | |- Draw_Buffer_ASCII_8x8 : ASCII文字表示 : 8x8dot
| | | |- Draw_Buffer_ASCII_8x8.c
| | | |- Draw_Buffer_ASCII_8x8.h
| | |
| | |- Draw_Buffer_String : ASCII文字 と 日本語文字表示
| | |- Draw_Buffer_String_16x16.c : 文字列表示 : 16x16dot
| | |- Draw_Buffer_String_16x16.h
| | |- Draw_Buffer_String_Expand_32x32.c : 16x16dotの文字を 32x32dotに拡大する。
| | |- Draw_Buffer_String_Expand_32x32.h
| | |- Draw_Buffer_String_Expand_48x48.c : 16x16dotの文字を 48x48dotに拡大する。
| | |- Draw_Buffer_String_Expand_48x48.h
| |
| |-Font_Lib
| | |- Font_ASCII_A : ASCII文字Fontの配列
| | | |- Font_ASCII_16x16_A.c : ASCII文字Font 16x16dot の配列
| | | |- Font_ASCII_16x16_A.h
| | | |- Font_ASCII_8x8_A.c : ASCII文字Font 8x8dot の配列
| | | |- Font_ASCII_8x8_A.h
| | |
| | |- Font_UTF16_16x16_A : Unicode文字Fontの配列 : UTF-16(日本語)
| | |- Font_UTF16_16x16_A.c : UTF-16文字Font 16x16dot の配列
| | |- Font_UTF16_16x16_A.h
| |
| |- ILI9341_Lib
| |- ILI9341_Display
| | |- ILI9341_Display_Clear : 画面表示クリア
| | | |- ILI9341_Display_Clear.c
| | | |- ILI9341_Display_Clear.h
| | |
| | |- ILI9341_Display_String : ASCII文字 と 日本語文字表示
| | |- ILI9341_Display_String.c
| | |- ILI9341_Display_String.h
| |
| |- ILI9341_SPI_Lib : ILI9341の制御
| |- ILI9341_SPI_Draw.c : ILI9341のレジスタ設定とデータ送信
| |- ILI9341_SPI_Draw.h : Fontサイズ など各種パラメータの定義
| |- ILI9341_SPI_Init.c : ILI9341初期化
| |- ILI9341_SPI_Init.h
|
|- MSP2807_String_Ope
| |- F405xG_MSP2807_String_Config
| | |- Dev_Conf.h : 動作パラメータの定義
| |
| |- MSP2807_Startup_Screen_String : MSP2807起動画面表示 : ASCII文字 と 日本語
| | |- MSP2807_Startup_Screen_String.c
| | |- MSP2807_Startup_Screen_String.h
| |
| |- MSP2807_Test_String_A : MSP2807 文字表示試験
| |- MSP2807_Test_String_A.c
| |- MSP2807_Test_String_A.h
|
|- Periph_Lib
| |- H_Common_STM32F4 : 周辺インターフェースの共通ハンドラ
| | |- H_Common_STM32F4_SPI.c : SPIインターフェース共通ハンドラ
| | |- H_Common_STM32F4_SPI.h
| |
| |- H_STM32F4_SPI_1 : SPI1インターフェースのハンドラ
| |- H_STM32F4_SPI_1.c
| |- H_STM32F4_SPI_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
|
|- F405xG_MSP2807_String.launch
|- STM32F405xGTX_FLASH.ld
|- STM32F405xGTX_RAM.ld
F405xG_MSP2807_String の動作パラメータの定義
サンプルプログラム F405xG_MSP2807_String の動作パラメータの定義を
MSP2807_String_Ope/F405xG_MSP2807_String_Config/Dev_Conf.h に記述しています。
使用する CPU の定義、ヘッダ名の定義、GPIO のポートとピンの定義、動作パラメータ
などを記述しています。
ユーザープログラムの実行開始位置
プログラムは、int main(void) から実行開始します。
int main(void) は、フォルダ Core/Src/main.c にあります。

STM32CubeIDEでビルドされたプログラムは、自動的にCPUの初期化を
行った後、int main(void) を呼び出します。
ユーザーコード(記述したプログラム)は、
int main(void) の先頭から実行されます。
F405xG_MSP2807_String の main()の説明
サンプルプログラム F405xG_MSP2807_String の main() の記述は、
以下のとおりです。
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
//-----------------------------------------------------------------
// main関数内では、以下の処理番号の変数、
// STC_uint8_JobNum_LED と
// STC_uint8_JobNum_MSP2807 は
// while(1){
// }
// の永久ループ内で使用しているので、
// static宣言をする必要はない。
// しかし、main関数以外の全ての関数内では
// 処理番号をstatic宣言をする必要があるので、
// 合わせるために、ここでも static宣言をしている。
//-----------------------------------------------------------------
static uint8_t STC_uint8_JobNum_LED; // LED処理番号
static uint8_t STC_uint8_JobNum_MSP2807; // MSP2807処理番号
//------------------------------------------------------------
// 呼び出す関数を case 0: から実行させるために
// 処理番号に 0 をセットします。
//------------------------------------------------------------
STC_uint8_JobNum_LED = 0; // LED処理番号初期化
STC_uint8_JobNum_MSP2807 = 0; // MSP2807処理番号初期化
/* 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);
//------------------------------------------------------------
// MSP2807試験 : 文字表示 : Font配列使用 : プログラム埋め込み
//------------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG終了
//------------------------------------------------------------
MSP2807_Test_String(&STC_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/STM32L4xx_HAL_Drivers) 内に記述されています。
b) CPU動作クロックの設定
/* Configure the system clock */
SystemClock_Config();
CPUの動作クロックとPeripheralの動作クロックを設定します。
SystemClock_Config(); の設定内容は、
int main(void)
{
.
.
.
}
の、すぐ下に記述されています。
c) MSP2807の初期化
MSP2807試験のモジュール MSP2807_Test_String 内で
初期化処理 ILI9341_Initialize を呼びだしています。
2) LED点滅 と MSP2807試験 の部分
永久ループ部分の記述を以下に示します。
/* 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);
//------------------------------------------------------------
// MSP2807試験 : 文字表示 : Font配列使用 : プログラム埋め込み
//------------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG終了
//------------------------------------------------------------
MSP2807_Test_String(&STC_uint8_JobNum_MSP2807);
}
/* USER CODE END 3 */
ST LED点滅処理 Blink_LED_ST と
MSP2807試験 MSP2807_Test_String を呼び出しています。
MSP2807_Test_String では、起動時の初期画面表示を行います。
Blink_LED_ST と MSP2807_Test_String は並列に実行されます。
MSP2807試験 MSP2807_Test_String の説明
1) MSP2807_Test_String のコード
MSP2807_Test_String のコードは
MSP2807_String_Ope/MSP2807_Test_String/MSP2807_Test_String.c に
記述されています。
以下に、MSP2807_Test_String のコードを示します。
//--------------------------------------------------------------
// MSP2807試験 : 文字表示 : Font配列使用 : プログラム埋め込み
//--------------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号が格納された変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG終了
//--------------------------------------------------------------
int16_t MSP2807_Test_String(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;
static uint8_t STC_uint8_JobNum_MSP2807; // MSP2807処理番号
static uint16_t STC_uint16_Num; // 数字
static uint8_t STC_uint8_aString[4]; // 表示データの配列
int16_t int16_Return;
switch(*puint8_JobNum)
{
case 0:
STC_uint8_JobNum_MSP2807 = 0; // MSP2807処理番号初期化
STC_uint16_Num = 0; // 数字初期化
(*puint8_JobNum)++; // 次の処理番号に移行する。
int16_Return = -1; // 処理継続
break;
case 1:
//----------------------------------------------------------
// ILI9341初期化
//----------------------------------------------------------
// 戻り値:
// -1 : 処理中
// 0 : OK
// 1 : NG
//----------------------------------------------------------
int16_Return = ILI9341_Initialize(&STC_uint8_JobNum_MSP2807);
if(int16_Return == -1){
// 処理中
break; // 処理番号維持 : 処理継続 : 現在の処理番号をループ
}
if(int16_Return != 0){
// NG
break; // 処理番号維持 : 処理継続 : 現在の処理番号をループ
// 初期化が正常に終了しない場合、ここから下の処理に進まない。
}
(*puint8_JobNum)++; // 次の処理番号に移行する。
int16_Return = -1; // 処理継続
break;
case 2:
//----------------------------------------------------------
// MSP2807起動画面表示 : String
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG終了
//----------------------------------------------------------
int16_Return
= MSP2807_Startup_Screen_String(&STC_uint8_JobNum_MSP2807);
if(int16_Return == -1){
// 処理中
break; // 処理番号維持 : 処理継続 : 現在の処理番号をループ
}
// 数字の文字列を初期化
STC_uint8_aString[0] = (uint8_t)'0';
STC_uint8_aString[1] = (uint8_t)'0';
STC_uint8_aString[2] = (uint8_t)'0';
STC_uint8_aString[3] = 0;
(*puint8_JobNum)++; // 次の処理番号に移行する。
int16_Return = -1; // 処理継続
break;
case 3:
//----------------------------------------------------------
// font 32 x 32 : ASCII : 数字を表示する。
//----------------------------------------------------------
//--------------------------------------------------
// 横長表示 左
//--------------------------------------------------
//----------------------------------------------------------
// LCD文字表示 : Font選択 : ILI9341
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// int16_t int16_Check_Semaphore : セマフォチェック有無
// 0 : チェックなし
// 1 : チェックあり
// 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
// 4 : 16 x 16 font : Unicode
// 5 : 32 x 32 font : Unicode
// 6 : 48 x 48 font : Unicode
// 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_aData :
// 表示文字コードが格納されているBufferのポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG終了
//----------------------------------------------------------
int16_Return = ILI9341_SPI_Display_String(
&STC_uint8_JobNum_MSP2807,
1,
(uint16_t)def_Font_ASCII_Expand_32x32,
def_WidthwiseL, 0,
(uint32_t)def_Code_White,
132, 128,
3, STC_uint8_aString);
if(int16_Return == -1){
// 処理中
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 4:
//----------------------------------------------------------
// 時間待ち : 単位 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_uint16_Num++; // 数字をインクリメント
if(STC_uint16_Num > 999){
// 数字が 999 を越えたら 0 に戻す。 : 0 - 999 を繰り返す。
STC_uint16_Num = 0;
}
//--------------------------------------------------------------
// 数字を3桁の文字列に変換 : ASCII
//--------------------------------------------------------------
// 引数:
// uint16_t uint16_Num : 数字
// uint8_t *puint8_aString :
// 3桁の文字列に変換したデータを格納するバッファのポインタ
// 戻り値:
// なし
//--------------------------------------------------------------
Conv_Num_String_3_ASCII(STC_uint16_Num, STC_uint8_aString);
(*puint8_JobNum)--; // ひとつ前の処理番号に移行する。
int16_Return = -1; // 処理継続
break;
default:
*puint8_JobNum = 0; // 処理番号初期化
int16_Return = 1; // NG
break;
}
return(int16_Return);
}
2) 初期化
a) case 0:
MSP2807処理番号の初期化と1秒ごとに表示する数字の変数を初期化しています。
b) case 1:
モジュール ILI9341_Initialize を呼び出して
ILI9341 の初期化を行います。
3) 起動画面表示
case 2: では、MSP2807_Startup_Screen_String を呼び出して
起動画面の表示を行います。
以下の画面が表示されます。

4) 数字表示
case 3: では、3桁の数字を表示します。
上記の画面で 072 の部分です。
数字は case 4: でカウントアップされます。
5) 時間待ちと数字のカウントアップ
case 4: では、1000mSec の時間待ちをします。
1000mSec 経過したら、表示する数字をカウントアップします。
数字が 999 を超えたら、000 に戻します。
000 から 999 を繰り返しカウントアップします。
処理番号を 3 にします。
case 3: と case 4: を繰り返し実行します。
文字表示モジュール の使用方法
文字表示モジュール ILI9341_SPI_Display_String の使用方法を
簡単に説明します。
文字表示は、MSP2807_Lib/ILI_9341_Lib/ILI9341_Display/ILI9341_Display_String/ILI9341_Display_String.c 内の
モジュール ILI9341_SPI_Display_String に文字コードなどの引数を渡して行います。
引数に (uint8_t *)"ようこそ!" のように
直接、日本語を指定して、日本語表示を行うことができます。
1) 通常の使用方法
使用例として MSP2807_Startup_Screen_String/MSP2807_Startup_Screen_String.c 内の
MSP2807起動画面表示モジュール MSP2807_Startup_Screen_String で
"ようこそ!" を 16 x 16 のフォントで表示している部分を以下に示します。
case 4:
//-----------------------------------------------------------------------
// "ようこそ!" : 16 x 16 font : UTF-8
//-----------------------------------------------------------------------
//--------------------------------------------------
// 横長表示 左
//--------------------------------------------------
//----------------------------------------------------------------------------
// LCD文字表示 : Font選択 : ILI9341
//----------------------------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// int16_t int16_Check_Semaphore : セマフォチェック有無
// 0 : チェックなし
// 1 : チェックあり
// 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
// 4 : 16 x 16 font : Unicode
// 5 : 32 x 32 font : Unicode
// 6 : 48 x 48 font : Unicode
// 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_aData :
// 表示文字コードが格納されているBufferのポインタ
// 戻り値:
// -1 : 処理中
// 0 : OK終了
// 1 : NG終了
//--------------------------------------------------------------
int16_Return = ILI9341_SPI_Display_String(&STC_uint8_JobNum_LCD,
1,
(uint16_t)def_Font_Unicode_16x16,
def_WidthwiseL, 0,
(uint32_t)def_Code_Blue,
192, 0,
5, (uint8_t *)"ようこそ!");
if(int16_Return == -1){
// 処理中
break; // 処理番号維持 : 処理継続 : 現在の処理番号をループ
}
(*puint8_JobNum)++; // 次の処理番号に移行する。
int16_Return = -1; // 処理継続
break;
それぞれの引数に、目的の値をセットして呼び出しています。
戻り値が "処理中" でなくなるまで、case 4: をループして繰り返し呼び出します。
戻り値が "処理中" 以外になったら、次の処理番号に移行します。
case 5: では "電子工作" を 48 x 48dot に拡大表示しています。
MSP2807起動画面表示モジュール MSP2807_Startup_Screen_String では、
いろいろなサイズと向きで文字を表示しているので、参考にしてください。
2) 並列動作がよくわからない場合
以下のように、int16_Return が -1 以外の値になるまで繰り返し呼び出すことにより
文字列を表示することができます。
STC_uint8_JobNum_LCD = 0;
do{
//-----------------------------------------------------------------------
// "ようこそ!" : 16 x 16 font : UTF-8
//-----------------------------------------------------------------------
//--------------------------------------------------
// 横長表示 左
//--------------------------------------------------
//----------------------------------------------------------------------------
// LCD文字表示 : Font選択 : ILI9341
//----------------------------------------------------------------------------
int16_Return = ILI9341_SPI_Display_String(&STC_uint8_JobNum_LCD,
1,
(uint16_t)def_Font_Unicode_16x16,
def_WidthwiseL, 0,
(uint32_t)def_Code_Blue,
192, 0,
5, (uint8_t *)"ようこそ!");
}while(int16_Return == -1);
文字表示モジュール の説明
文字表示モジュール ILI9341_Display_String の説明を記します。
MSP9807_Lib/ILI9341_Lib/ILI9341_Display/ILI9341_Display_String/ILI9341_Display_String.c に
記述されています。
1) 描画Frameの構造体設定
case 0: では Set_structFrame_String を呼びだして
表示範囲を、描画Frame設定用の構造体にセットします。
case 0:
// セマフォチェック有無判定
if(int16_Check_Semaphore == 1){
// セマフォチェックありの場合
//------------------------------------------------
// セマフォチェック
//------------------------------------------------
if(GLB_int8_Semaphore_LCD != 0){
// 他のモジュールがセマフォを使用中
int16_Return = -1; // 処理継続
break; // 処理番号維持 : 現在の処理番号をループ
}
GLB_int8_Semaphore_LCD = 1; // セマフォ取得
//------------------------------------------------
}
STC_uint8_JobNum = 0; // 表示処理番号初期化
STC_uint16_Position = 0;
STC_uint16_SendCount = 0;
STC_uint16_Position_DrawBuffer = 0;
//----------------------------------------------------------
// 描画Frameの構造体設定 : String
//----------------------------------------------------------
// 引数;
// 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
// 8 : 16 x 16 font : Unicode
// 9 : 32 x 32 font : Unicode
// 10 : 48 x 48 font : Unicode
// 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_String(uint16_Font,
uint16_StartX,
uint16_StartY,
uint16_Length,
&STC_structFrame_LCD);
if(int16_Return != 0){
break; // NG終了
}
(*puint8_JobNum)++; // 次の処理番号に移行する。
int16_Return = -1; // 処理継続
break;
2) 表示Frame設定 と 描画Bufferの設定
case 1: では ILI9341_SPI_SetFrame を呼びだして、
描画Frame設定用の構造体 STC_structFrame_LCD の内容を
表示の向きと範囲を設定するための ILI9341 のレジスタに設定します。
表示Frame設定が終了したら、Set_DrawBuffer_String を呼び出して
表示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){
GLB_int8_Semaphore_LCD = 0; // セマフォ解放
*puint8_JobNum = 0; // 処理番号初期化
break; // NG終了
}
//----------------------------------------------------------
// 描画Buffer設定 : String
//----------------------------------------------------------
// 引数;
// 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
// 8 : 16 x 16 font : Unicode
// 9 : 32 x 32 font : Unicode
// 10 : 48 x 48 font : Unicode
// uint8_t uint8_Type : 表示選択
// 0 : 通常表示
// 1 : 反転表示
// 2 : 通常表示の上書き
// 3 : 反転表示の上書き
// uint16_t uint16_Length : 表示文字数
// uint8_t *puint8_aChar :
// 文字コードが格納されたBufferのポインタ
// uint8_t *puint8_aBuffer : 描画Bufferのポインタ
// uint16_t *puint16_Width : 文字の幅の変数のポインタ
// uint16_t *puint16_Height : 文字の高さの変数のポインタ
// 戻り値;
// なし
//----------------------------------------------------------
Set_Draw_Buffer_String(uint16_Font,
uint8_Type,
uint16_Length,
puint8_aData, GLB_uint8_aDrawBuffer_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_aBuffer_1Line_LCD[int16_I] = 0;
}
//--------------------------------------------------------
// LCD表示用送信データ作成(カラーコード指定) : RGB 2byte
//--------------------------------------------------------
// 引数:
// uint32_t uint32_ColorCode : カラーコード
// uint16_t uint16_Width : 表示領域の幅
// uint16_t uint16_Position : DrawDataの位置
// uint8_t *puint8_aDrawData :
// Drawデータが格納されたBufferのポインタ
// uint8_t *puint8_aSendData :
// 送信データを格納するBufferのポインタ
// 戻り値:
// なし
//--------------------------------------------------------
MakeSendData_1Line_ColorCode_2byte(uint32_ColorCode,
STC_uint16_Width,
STC_uint16_Position,
GLB_uint8_aDrawBuffer_LCD,
GLB_uint8_aBuffer_1Line_LCD);
}
else{
// 2 : 通常表示の上書き
// 3 : 反転表示の上書き
MakeSendData_1Line_ColorCode_2byte(uint32_ColorCode,
STC_uint16_Width,
STC_uint16_Position,
GLB_uint8_aDrawBuffer_LCD,
&GLB_uint8_aWork_1Line_LCD[
STC_uint16_Position_DrawBuffer]);
}
// 送信データ数セット
STC_uint16_SendLength = STC_uint16_Width * def_RGB_byte;
(*puint8_JobNum)++; // 次の処理番号に移行する。
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_aData :
// 送信データが格納されている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_aBuffer_1Line_LCD);
}
else{
// 2 : 通常表示の上書き
// 3 : 反転表示の上書き
int16_Return = ILI9341_SPI_SendData(&STC_uint8_JobNum,
1,
STC_uint16_SendLength,
&GLB_uint8_aWork_1Line_LCD[
STC_uint16_Position_DrawBuffer]);
}
if(int16_Return == -1){
// 処理中
break; // 処理番号維持 : 処理継続 : 現在の処理番号をループ
}
if(int16_Return != 0){
GLB_int8_Semaphore_LCD = 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)++; // 次の処理番号に移行する。
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_aSPI1_TxBuffer[int16_I] = 0;
}
//--------------------------------------------------------
// LCD表示用送信データ作成(カラーコード指定) : RGB 2byte
//--------------------------------------------------------
// 引数:
// uint32_t uint32_ColorCode : カラーコード
// uint16_t uint16_Width : 表示領域の幅
// uint16_t uint16_Position : DrawDataの位置
// uint8_t *puint8_aDrawData :
// Drawデータが格納されたBufferのポインタ
// uint8_t *puint8_aSendData :
// 送信データを格納するBufferのポインタ
// 戻り値:
// なし
//--------------------------------------------------------
MakeSendData_1Line_ColorCode_2byte(uint32_ColorCode,
STC_uint16_Width,
STC_uint16_Position,
GLB_uint8_aDrawBuffer_LCD,
GLB_uint8_aSPI1_TxBuffer);
}
else{
// 2 : 通常表示の上書き
// 3 : 反転表示の上書き
MakeSendData_1Line_ColorCode_2byte(uint32_ColorCode,
STC_uint16_Width,
STC_uint16_Position,
GLB_uint8_aDrawBuffer_LCD,
&GLB_uint8_aWork_1Line_LCD[
STC_uint16_Position_DrawBuffer]);
for(uint16_I = 0;
uint16_I < (STC_uint16_Width * def_RGB_byte);
uint16_I++){
GLB_uint8_aSPI1_TxBuffer[uint16_I]
= GLB_uint8_aWork_1Line_LCD[
STC_uint16_Position_DrawBuffer + uint16_I];
}
}
// 送信データ数セット
GLB_structParam_Handle_SPI1.int16_vSPI_TxNumber
= STC_uint16_Width * def_RGB_byte;
(*puint8_JobNum)++; // 次の処理番号に移行する。
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){
//----------------------------------------------------------
// SPIx Master送受信
//----------------------------------------------------------
// 引数;
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ
// SPI_HandleTypeDef *pHandle_SPIx : SPI handler declaration
// IRQn_Type DMA_Stream_IRQn_Transmit_SPIx : SPI DMA Transmit IRQn
// IRQn_Type DMA_Stream_IRQn_Receive_SPIx : SPI DMA Receive IRQn
// struct sParam_Handle_SPIx *pstructParam_Handle_SPIx :
// Handle SPI用パラメータの構造体のポインタ
// GPIO_TypeDef *pGPIOx_SPIx_NSS : SPIx_NSS のGPIOポート
// uint16_t uint16_GPIO_Pin_x_SPIx_NSS : SPIx_NSS のGPIOピン
// int16_t int16_Value_Wait_SPI_TxRx : SPI送受信待ちの値
// int16_t int16_NSS_OnOff : 送信終了時NSS ON/OFF選択
// 0 : 送信後 NSSをOFFにする。
// 1 : 送信後 NSSをONのままにする。
// 戻り値;
// -1 : 処理中
// 0 : OK
// 1 : NG
//----------------------------------------------------------
int16_Return = SPIx_Master_TxRxByte(&STC_uint8_JobNum,
&Handle_SPI1,
DMA2_Stream3_IRQn,
DMA2_Stream2_IRQn,
&GLB_structParam_Handle_SPI1,
def_GPIOx_SPI1_NSS,
def_GPIO_PIN_x_SPI1_NSS,
STC_int16_Value_Wait_SPI_TxRx,
0);
}
else{
int16_Return = SPIx_Master_TxRxByte(&STC_uint8_JobNum,
&Handle_SPI1,
DMA2_Stream3_IRQn,
DMA2_Stream2_IRQn,
&GLB_structParam_Handle_SPI1,
def_GPIOx_SPI1_NSS,
def_GPIO_PIN_x_SPI1_NSS,
STC_int16_Value_Wait_SPI_TxRx,
1);
}
if(int16_Return == -1){
// 処理中
break; // 処理番号維持 : 処理継続 : 現在の処理番号をループ
}
if(int16_Return != 0){
GLB_int8_Semaphore_LCD = 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);
//----------------------------------------------
// セマフォチェック有無判定
//----------------------------------------------
if(int16_Check_Semaphore == 1){
// セマフォチェックありの場合
GLB_int8_Semaphore_LCD = 0; // セマフォ解放
}
//----------------------------------------------
*puint8_JobNum = 0; // 処理番号初期化
int16_Return = 0; // OK終了
break;
A+-2C (ええ加減にC) のページに戻る
メールアドレス: apm2c.sumi@gmail.com
なんでも、気軽に ご相談ください。
担当:おの
えがおのでんし 案内