STM32F401でST7789液晶を使う

#はじめに
ST7789を使用した240x240のIPS液晶モジュールが500円程で購入可能です。Arduinoではライブラリが容易されているようですがSTM32にはありません(自分が知らないだけかもですが)。今回STM32F401での駆動が出来ましたので、忘備録として記録しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/8c87e062-e345-728c-5561-724a025a3912.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/cc6ec579-e417-4e97-408b-92a14432519e.png)

#ライブラリ
[Floyd-Fish](https://github.com/Floyd-Fish)氏の[ST7789-STM32](https://github.com/Floyd-Fish/ST7789-STM32)を使用します。

画像を表示するには16Bit(RGB565)でテキストデータを用意する必要があります。こちらは[afiskon](https://github.com/afiskon)氏が公開されている[stm32-st7735](https://github.com/afiskon/stm32-st7735)ライブラリに有る`image-to-mem.py`で作成する事が可能です。使用方法は(自分のメモのためにも)後述します。

#STM32F401の設定
STM32CubeMXで生成しています。
SPI1を使用しPA2-PA4にRST, DC, CS(未使用)を出力として設定しています。

##Pin out
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/dd43979f-a967-6e3f-429b-13809ef763c6.png)

##SPI1
SPIの通信設定はデフォルトですが、動作しない場合は`Pull-up`にしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/2a4cbba2-c45b-e844-c116-d8cf184f1ed0.png)

##clock
最高速となるように設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/260f2cdd-534a-9341-9fa6-e26271ed28a2.png)

#結線
今回使用した液晶にはCSピンがありません。そのため結線は不要ですがライブラリにCS結線のコードがあるためSTMではピンアサインを行なっておきます。
BLKはバックライトのON-OFF制御信号です。OpenでON、GNDでOFFとなるため、結線無しでOKです。画面On-OFFを制御したい場合はピンに接続します。

	Pin connection
	LCD Pin		STM32 pin			DESC.
	GND			GND
	VCC			3.3V
	SCL			SPI1_SCK(PA5)		**MUST BE SOFT PULL UP
	SPA			SPI1_MOSI(PA7)		**MUST BE SOFT PULL UP
	RES			ST7789_RST(PA2)		Reset signal
	DC			ST7789_DC(PA3)		DATA, command
	BLK			No connection		Back light, float:ON, GND:OFF
	CS			ST7789_CS(PA4)		CS in N/A. This is for software compatibility.

#コード
STM32CubeMXにてコード生成した後、`Src`の下に`st7789`フォルダを作成し、4つのファイルをインポートします。実際の作業はエクスプローラでフォルダ毎コピーすればインポートされます。
includeパス等必要な部分を環境に合せて修正します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/ffcb1b8b-e929-848b-39ff-386a28347282.png)

##サンプル表示
`main.c`の下記部分を修正してサンプル表示をさせます。

###include
ヘッダーをIncludeします。

```
/* USER CODE BEGIN Includes */
#include "st7789\\st7789.h"
/* USER CODE END Includes */
```

###サンプルコード
Initializeして、テスト関数を呼びます。

```
  /* USER CODE BEGIN 2 */

  ST7789_Init();
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
	  ST7789_Test();
  }
  /* USER CODE END 3 */
```

###st7789.h
ご使用のTFTの解像度に対してヘッダーのこのへんを修正します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/260c7ed0-cbc0-24d2-8453-79fe656ebd83.png)


#実行
コンパイルして実行します。表示できたら成功です。

#画像データの作成
`image-to-mem.py`を使用して、16bitRGBの画像データを用意する方法を記載します。

##pythonソース
前述の通りこちらより入手します。[stm32-st7735](https://github.com/afiskon/stm32-st7735)

##pythonソース修正
オリジナルは128x128のファイル専用になっていますので、画像サイズに合せて変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/170b0b3f-bf57-4c2f-4ad8-aa624368b4b0.png)

##pythonで実行
私の環境はWindowsですので、CMDプロンプトで下記を実行します。出力はout.hに出力されます。

`>python -m image-to-mem.py Clipboard01.png > out.h`

###エラーが発生する場合
下記の用なエラーが発生する場合はPIL(Pillow)という画像ライブラリがインストールされていません。

```
Traceback (most recent call last):
  File "image-to-mem.py", line 5, in <module>
    from PIL import Image
ImportError: No module named PIL
```

おまじないコードを実行してから
`>python -m pip install --upgrade pip`

Pillowをインストールします。
`>python -m pip install Pillow`


うまく実行できれば変換データがout.hファイルに出力されますので、プロジェクトにインポートしてst7789_DrawImage()で表示します。

```
	ST7789_DrawImage(0, 0, 240, 240, (uint16_t *)image);
```

#最後に
IPS液晶はあざかやですね。
あと思った以上に遅いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/7cac942c-97b9-7783-cb20-4c86cbc8f82c.png)