320x240 TFT液晶 ILI9341
2.8" TFTインチ液晶ディスプレイ タッチパネルの液晶部分 240x320ドットの ILI9341です。
このTFT液晶は電源電圧は3.3~5V対応ですが、信号レベルは3.3Vなので
ArduinoUNOなどの5V系のマイコンで使用する場合にはレベルシフタが必要です。
私は 8Bit双方向ロジックレベルコンバータ を使用しました。
ロジックレベルを3.3Vに変更できるArduinoUNO互換機(KEYSTUDIO PLUS)や、M5Stamp、RaspberryPi PICOでは直接接続できます。
ArduinoUNOとの接続
信号名がシルク印刷されていますので分かり易いと思います。ハードウエアSPIを使用するために、ArduinoUNO側では13,12,11番ピンは固定ですが、それ以外は任意のピンに割り当てできます。
LCDモジュール | ArduinoUNO |
---|---|
VCC | 3.3V |
GND | GND |
CS | D10 |
RESET | D9 |
DC | D8 |
SDI(MOSI) | D11 |
CSK | D13 |
LED | 3.3V |
SDO(MISO) | D12 |
ILI9341のコマンド
動作 | COMAND | PARAMETA |
---|---|---|
Software Reset ソフトウエア・リセット |
0x01 | パラメタ - なし |
Memory Access Control メモリと画面の対応(表示方向の設定) |
0x36 | パラメタ - 1Byte 横(0xE8) or 縦(0x48) |
COLMOD: Pixel Format Set メモリと表示色の対応(色指定方法の設定) |
0x3A | パラメタ - 1Byte 16bit色(0x55) or 18bit色(0x66) |
Sleep Out スリープモードからの復帰 |
0x11 | パラメタ - なし 【重要】コマンド送信後、電源が安定するまで(5m秒以上)待つ必要がある。 |
Enter Sleep Mode スリープモードに設定 |
0x10 | |
Display ON 表示ON |
0x29 | パラメタ - なし |
Display OFF 表示OFF |
0x28 | |
Display Inversion OFF 表示色反転 OFF |
0x20 | パラメタ - なし |
Display Inversion ON 表示色反転 ON |
0x21 | パラメタ - なし |
Normal Display Mode On 全画面表示 |
0x13 | パラメタ - なし |
Partial Mode ON 部分表示 |
0x12 | パラメタ - なし 範囲はPartial Area command(0x30)で指定 |
Partial Area 部分表示範囲指定 |
0x30 | パラメタ - 2Bayte + 2Bayte |
Column Address Set ドットデータ書き込みカラム位置 |
0x2A | パラメタ - 2Bayte + 2Bayte |
Page Address Set ドットデータ書き込みページ位置 |
0x2B | パラメタ - 2Bayte + 2Bayte |
Memory Write ドットデータ書き込み |
0x2C | パラメタ - N Bayte |
Memory Read ドットデータ読み出し |
0x2E | パラメタ - N Bayte |
Vertical Scrolling Start Address スクロール開始アドレス |
0x37 | パラメタ - 2Bayte |
コマンドは1バイトでパラメタはデータ扱いになります
DCをLOWにしてコマンドを送信、DCをHIGHにしてパラメタを送信の手順で使用します
描画方向の設定
描画方向は、Memory Access Control(0x36)コマンドのパラメタで設定しますパラメタ設定は▼の通り
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |
---|---|---|---|---|---|---|---|---|
コマンド | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 |
パラメタ | MY (Y軸方向) |
MX (X軸方向) |
MV (XY軸入れ替え) |
ML (Y軸更新方向) |
RGB (色割り当て RGB or BGR) |
MH (X軸更新方向) |
- | - |
Dotの色指定
1Dot(ピクセル)の色を指定する方法(フォーマット)の指定は COLMOD: Pixel Format Set で行います。Memory Writeで書き込む値は 16Bitモードと18Bitモードで▼のようになります
描画手順
描画範囲を指定し、指定範囲を埋めるBitmapデータを送信する描画範囲 COLの指定 | 0X2A | SC,EC |
---|---|---|
描画範囲 ROWの指定 | 0x2B | SP,EP |
描画データ送信 | 0x2C | Bitmapデータ |
最小構成のスケッチ
ILI9341-DEMO2.zip ※参考動画で使用しているDEMOのスケッチ
ILI9341-DEMO-SIMPLE.zip
※ <>を全角<>に置き換えています。コピペの際は注意してください。
▼に表示しているのは、プログラムの一部です。全体はZIPファイルを解凍して参照してください。
// ILI9341 SPI Graphics TEST
#include <SPI.h>
#include "image2.h"
#include "font8x16.h"
#define TFT_CLK 13
#define TFT_MISO 12
#define TFT_MOSI 11
#define TFT_DC 8
#define TFT_RST 9
#define TFT_CS 10
// BackLightはHIGH固定にするのでソフトがらは制御しない
#define TFT_BL 7
// SPISettings settings = SPISettings(8000000, MSBFIRST, SPI_MODE0); // 8MHzで合ってるよね?変だと思ったら修正してください。
// ▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼
void setup() {
SPI.begin(); //SPIを初期化、SCK、MOSI、SSの各ピンの動作は出力、SCK、MOSIはLOW、SSはHIGH
SPI.setClockDivider(SPI_CLOCK_DIV2);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
// SPI.beginTransaction(settings); // M5StampやRaspberryPi PICOで使う時はコッチの設定でないとコンパイルが通らない
// --- ST3375 INITIAL
pinMode(TFT_CS, OUTPUT);
pinMode(TFT_DC, OUTPUT);
pinMode(TFT_RST, OUTPUT);
// --- HARDWARE Reset
digitalWrite(TFT_RST, LOW);
delay(20);
digitalWrite(TFT_RST, HIGH);
delay(20); // このdelayは必要
// --- ILI9341 動作設定
digitalWrite(TFT_CS, LOW); // TFTセレクト
digitalWrite(TFT_DC, LOW); // Command mode
SPI.transfer(0x01); //<< SOFTWARE RESET
delay(150); // ※このdelayはなくても大丈夫かも
SPI.transfer(0x13) ; //<< Normal Display Mode ON
SPI.transfer(0x36) ; //<< Memory Access Control
digitalWrite(TFT_DC, HIGH); // Data mode
SPI.transfer(0x48) ; // MX = ON , GBR = ON (縦画面,左から右に表示)
digitalWrite(TFT_DC, LOW); // Command mode
SPI.transfer(0x3a) ; //<< COLMOD: Pixel Format Set
digitalWrite(TFT_DC, HIGH); // Data mode
SPI.transfer(0x55) ; //<< 16Bits / 1Pixcel
digitalWrite(TFT_DC, LOW); // Command mode
SPI.transfer(0x11) ; //<< Sleep Out
delay(60); // 【重要】このdelayは絶対に必要:電源が不安定な場合は長めに(120ms位に)する
SPI.transfer(0x29) ; //<< Display ON
digitalWrite(TFT_CS, HIGH); // TFT解放
}
// ▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼▲▼
void loop() {
for (int i=0;i<5;i++) {
uint16_t color = 0x0000 ;
switch(i) {
case 0: color = 0x0000 ; break ;
case 1: color = 0xF800 ; break ;
case 2: color = 0x07E0 ; break ;
case 3: color = 0x001F ; break ;
case 4: color = 0xFFFF ; break ;
}
// --- 画面塗りつぶし
digitalWrite(TFT_CS, LOW); //TFTセレクト
digitalWrite(TFT_DC, LOW); // Command mode
SPI.transfer(0x2a); //<< Column Address Set
digitalWrite(TFT_DC, HIGH); // Data mode
SPI.transfer16(0); // 開始カラム 0
SPI.transfer16(239); // 終了カラム 239
digitalWrite(TFT_DC, LOW); // Command mode
SPI.transfer(0x2b); //<< Page Address Set
digitalWrite(TFT_DC, HIGH); // Data mode
SPI.transfer16(0); // 開始ページ 0
SPI.transfer16(319); // 終了ページ 319
digitalWrite(TFT_DC, LOW); // Command mode
SPI.transfer(0x2c); //<< Memory Write
digitalWrite(TFT_DC, HIGH); // Data mode
for (int y = 0 ; y < 320 ; y++) {
for (int x = 0 ; x < 240 ; x++) {
uint16_t data = color ;
SPI.transfer16(color);
}
}
digitalWrite(TFT_CS, HIGH); //TFT解放
delay(500) ;
}
}