之前使用的 單色LCD 或 多段顯示器 實際只是 1位元的方式顯示,即是使用開或關的方式顯示
雖然曾經使用電子紙總有 3種顏色 ,但在下使用的電子紙並非使用調色方法設定顏色
因此使用 TFT LCD 測試效果
雖然曾經使用電子紙總有 3種顏色 ,但在下使用的電子紙並非使用調色方法設定顏色
因此使用 TFT LCD 測試效果
TFT IPS LCD 熒幕
LCD熒幕的正面
模組底部會寫著型號,例如在下使用
- 尺寸為 1.54寸
- 像素為 240x240
- 顏色顯示為 RGB
模組頂部寫著引腳的功能
(最左為第1引腳)
(最左為第1引腳)
LCD熒幕的背面
寫著驅動晶片名稱(ST7789)及介面類型(SPI)
背面還有一些焊接用的焊墊,可以用作焊接 SD卡模組
TFT IPS LCD 操作訊號
CD | RW | Data | DEC | HEX | 說明 | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||||
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0x01 | 軟件重設 執行重設後,需要等待最少5毫秒才完成 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | # | 16 | 0x10 | 設定休眠模式
|
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | # | 32 | 0x20 | 設定負片模式
|
0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 38 | 0x26 | 設定Gamma修正 (1位元組設定值) |
1 | 0 | # | # | # | # | # | # | # | # | # | # | |
0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | # | 40 | 0x28 | 設定熒幕狀態
|
0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 43 | 0x2A | 設定寫入欄的範圍 第1位元組 第15位元 至 第8位元 欄開始位置 第2位元組 第7位元 至 第0位元 欄開始位置 第3位元組 第15位元 至 第8位元 欄結束位置 第4位元組 第7位元 至 第0位元 欄結束位置 (4位元組設定值) |
1 | 0 | S | S | S | S | S | S | S | S | # | # | |
1 | 0 | S | S | S | S | S | S | S | S | # | # | |
1 | 0 | E | E | E | E | E | E | E | E | # | # | |
1 | 0 | E | E | E | E | E | E | E | E | # | # | |
0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 42 | 0x2B | 設定寫入列的範圍 第1位元組 第15位元 至 第8位元 列開始位置 第2位元組 第7位元 至 第0位元 列開始位置 第3位元組 第15位元 至 第8位元 列結束位置 第4位元組 第7位元 至 第0位元 列結束位置 (4位元組設定值) |
1 | 0 | S | S | S | S | S | S | S | S | # | # | |
1 | 0 | S | S | S | S | S | S | S | S | # | # | |
1 | 0 | E | E | E | E | E | E | E | E | # | # | |
1 | 0 | E | E | E | E | E | E | E | E | # | # | |
0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 44 | 0x2C | 寫入內容 位元組數量與 寫入欄及列的範圍相應 如果設定寫入: 欄的範圍為 0 至 9 ,列的範圍為 0 至 4 便需要寫入 10欄 x 5列 共 50個位元組資料 (多位元組設定值) |
1 | 0 | # | # | # | # | # | # | # | # | # | # | |
0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 51 | 0x33 | 設定捲動範圍 第1位元組 第15位元 至 第8位元 固定的頂部高度 第2位元組 第7位元 至 第0位元 固定的頂部高度 第2位元組 第15位元 至 第8位元 捲動的內容高度 第2位元組 第7位元 至 第0位元 捲動的內容高度 第3位元組 第15位元 至 第8位元 固定的底部高度 第3位元組 第7位元 至 第0位元 固定的底部高度 T + S + B = 320 ,否則無效,會重設 (6位元組設定值) |
1 | 0 | T | T | T | T | T | T | T | T | # | # | |
1 | 0 | T | T | T | T | T | T | T | T | # | # | |
1 | 0 | S | S | S | S | S | S | S | S | # | # | |
1 | 0 | S | S | S | S | S | S | S | S | # | # | |
1 | 0 | B | B | B | B | B | B | B | B | # | # | |
1 | 0 | B | B | B | B | B | B | B | B | # | # | |
0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | # | 52 | 0x34 | 設定畫面撕裂模式
|
0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 55 | 0x37 | 設定捲動列數 第1位元組 為 第15位元 至 第8位元 第2位元組 為 第7位元 至 第0位元 (2位元組設定值) |
1 | 0 | # | # | # | # | # | # | # | # | # | # | |
1 | 0 | # | # | # | # | # | # | # | # | # | # | |
0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | # | 56 | 0x38 | 設定閒置模式
|
0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 58 | 0x3A | 設定記憶體用量及顏色深度 R 為使用記憶體用量
B 為使用顏色深度
(1位元組設定值)
|
1 | 0 | 0 | R | R | R | 0 | B | B | B | # | # | |
0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 81 | 0x51 | 設定光度數值 (1位元組設定值) |
1 | 0 | B | B | B | B | B | B | B | B | # | # |
同樣還有很多功能及設定,但這些功能便可以在熒幕上繪製出圖案,其他功能可以在資料表上找出及嘗試
ST7789 引腳功能
編號 | 名稱 | 方向 | 功能 |
---|---|---|---|
1 | GND | LCD 熒幕 接地 (TFT IPS LCD 引腳) |
|
2 | VCC | LCD 熒幕 電源,接受 5V (TFT IPS LCD 引腳) |
|
3 | SCL | 輸入 | 序列時脈,資料由高至低取值 每8位元資料為1週期 |
4 | SDA | 輸入 | 序列資料 |
5 | RES | 輸入 | 低電壓時,重置所有控制模式的設定值 若果不需要重置,保持高電壓 (TFT IPS LCD 引腳) |
6 | DC | 輸入 | 低電壓時,為控制模式 高電壓時,為資料模式 (TFT IPS LCD 引腳) |
7 | CS | 輸入 | 低電壓時,為啟動狀態 高電壓時,為閒置狀態 |
8 | BLK | LED 背光 電源,接受 5V (TFT IPS LCD 引腳) |
ST7789 是使用 最高有效位 (Most Significant Bit (MSB)) 次序發送訊號
引腳 | 初始化 | 開始 | 1位元組 控制 週期 | n位元組 資料 週期 (選用) | 結束 | ||
---|---|---|---|---|---|---|---|
延遲 | 1微秒 | ||||||
RES | 高 | ||||||
CS | 高 | 低 | 高 | ||||
DC | 低 | 高 | |||||
SCL | 高 | 低 | 高 | 低 | |||
SDA | 高/低 | 高/低 |
訊號波紋時序圖
線路接駁
如果使用 Arduino SPI引腳 及 SPI.h 函式庫,可以使用這種接駁方式
Arduino引腳 | ST7789引腳 |
---|---|
GND | GND |
5V | VCC |
13 (SCK) | SCL |
11 (MOSI) | SDA |
9 | RES |
8 | DC |
10 (SS) | CS |
5V | BLK |
今次在下接駁線路,使用預設的 SPI.h 的 API
接駁 電源 及 LCD背光 , TFT IPS LCD 仍未顯示畫面
要讓熒幕顯示畫面,最少需要
要讓熒幕顯示畫面,最少需要
- 取消休眠狀態
- 顯示畫面
- 設定顏色
起動 TFT IPS LCD 後,會顯示雜訊是正常情況
填色
要在 TFT IPS LCD 上填色,要先設定欄列開始及結束位置,再將顏色寫入到 Display Data RAM (DDRAM)
例如在下的 TFT IPS CDL 欄列各有240像素,即是如果要填滿整個畫面,欄列的開始及結束位置分別是 0 及 239
例如在下的 TFT IPS CDL 欄列各有240像素,即是如果要填滿整個畫面,欄列的開始及結束位置分別是 0 及 239
在下使用紅綠藍三原色測試顏色
捲動效果
雖然在下使用的 TFT IPS LCD 實際上能夠支援 240x320 ,但顯示範圍只有 240x240
能夠透過捲動功能,顯示 240 之後的內容
能夠透過捲動功能,顯示 240 之後的內容
列數範圍 | 預設顯示範圍 | 可讀寫範圍 |
---|---|---|
0 ~ 239 | 是 | 是 |
240 ~ 319 | 否 | 是 |
320 ~ 511 | 否 | 否 |
捲動的內容為循環顯示
捲動值為 320, 832, 1344 (512倍數 - 192) 等數值都是相同
捲動值為 511, 1023, 1535 (512倍數 - 1) 等數值後,都會出現撕裂畫面,這個範圍是無法讀寫
捲動值為 320, 832, 1344 (512倍數 - 192) 等數值都是相同
捲動值為 511, 1023, 1535 (512倍數 - 1) 等數值後,都會出現撕裂畫面,這個範圍是無法讀寫
捲動範圍
例如只使用預設顯示範圍,設定 T = 0, S = 240, B = 80 ,捲動範圍為 0 ~ 239
設定 T = 60, S = 120, B = 140 ,便可以模擬標頭、註腳、內容的捲動效果
但當改變捲動範圍後,要製作循環效果,捲動的數值範圍都要改變
以 T = 60, S = 120, B = 140 為例,捲動的數值範圍 是 60 ~ 179 ,而不是 0 至 119
以方程式表示可以寫成
但當改變捲動範圍後,要製作循環效果,捲動的數值範圍都要改變
以 T = 60, S = 120, B = 140 為例,捲動的數值範圍 是 60 ~ 179 ,而不是 0 至 119
以方程式表示可以寫成
L = 0; // L = L % S + T;
便可以修正捲動數值
顏色深度
數碼顏色深度,在現今的電子工具上,通常都使用 24位元 ,即是以 紅、綠、藍 三原色為基礎,各使用 8位元,甚至更高顏色深度
雖然 ST7789 可以設定使用 24位元顏色深度 ,實際上記憶體未能支援
ST7789 還有 12位元 、 16位元 、 18位元 顏色深度,預設是使用 16位元顏色深度
雖然 ST7789 可以設定使用 24位元顏色深度 ,實際上記憶體未能支援
ST7789 還有 12位元 、 16位元 、 18位元 顏色深度,預設是使用 16位元顏色深度
12位元顏色深度
12位元顏色深度 共有4096種顏色,能夠讓紅、綠、藍平均分配,各使用4位元
D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|---|
紅 | 紅 | 紅 | 紅 | 綠 | 綠 | 綠 | 綠 | 藍 | 藍 | 藍 | 藍 |
分配顏色時,以 3位元組 控制 2組顏色
第1位元組 的 第7位元 至 第4位元 控制 第1組紅色
第1位元組 的 第3位元 至 第0位元 控制 第1組綠色
第2位元組 的 第7位元 至 第4位元 控制 第1組藍色
第2位元組 的 第3位元 至 第0位元 控制 第2組紅色
第3位元組 的 第7位元 至 第4位元 控制 第2組綠色
第3位元組 的 第3位元 至 第0位元 控制 第2組藍色
第1位元組 的 第7位元 至 第4位元 控制 第1組紅色
第1位元組 的 第3位元 至 第0位元 控制 第1組綠色
第2位元組 的 第7位元 至 第4位元 控制 第1組藍色
第2位元組 的 第3位元 至 第0位元 控制 第2組紅色
第3位元組 的 第7位元 至 第4位元 控制 第2組綠色
第3位元組 的 第3位元 至 第0位元 控制 第2組藍色
第1位元組 | 第2位元組 | 第3位元組 | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
第1組紅色 | 第1組綠色 | 第1組藍色 | 第2組紅色 | 第2組綠色 | 第2組藍色 |
16位元顏色深度
16位元顏色深度 共有65536種顏色,不能夠讓紅、綠、藍平均分配,紅藍各使用5位元,綠色使用6位元
D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
紅 | 紅 | 紅 | 紅 | 紅 | 綠 | 綠 | 綠 | 綠 | 綠 | 綠 | 藍 | 藍 | 藍 | 藍 | 藍 |
分配顏色時
第1位元組 的 第7位元 至 第3位元 控制 紅色
第1位元組 的 第2位元 至 第0位元 及 第2位元組 的 第7位元 至 第5位元 控制 綠色
第2位元組 的 第4位元 至 第0位元 控制 藍色
第1位元組 的 第7位元 至 第3位元 控制 紅色
第1位元組 的 第2位元 至 第0位元 及 第2位元組 的 第7位元 至 第5位元 控制 綠色
第2位元組 的 第4位元 至 第0位元 控制 藍色
第1位元組 | 第2位元組 | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
紅色 | 綠色 | 藍色 |
18位元顏色深度
18位元顏色深度 共有262144種顏色,能夠讓紅、綠、藍平均分配,各使用6位元
D17 | D16 | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
紅 | 紅 | 紅 | 紅 | 紅 | 紅 | 綠 | 綠 | 綠 | 綠 | 綠 | 綠 | 藍 | 藍 | 藍 | 藍 | 藍 | 藍 |
分配顏色時
第1位元組 的 第7位元 至 第2位元 控制 紅色
第2位元組 的 第7位元 至 第2位元 控制 綠色
第3位元組 的 第7位元 至 第2位元 控制 藍色
第1位元組 的 第7位元 至 第2位元 控制 紅色
第2位元組 的 第7位元 至 第2位元 控制 綠色
第3位元組 的 第7位元 至 第2位元 控制 藍色
第1位元組 | 第2位元組 | 第3位元組 | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
紅色 | 綠色 | 藍色 |
在資料轉換上,在下認為使用 16位元 或 18位元 操作上會比較簡單
16位元 使用 2位元組 , 18位元 使用 3位元組
而 12位元,其一:顏色深度不足,可調整的顏色數量不多;
其二:寫入 DDRAM 的程序繁複,還要區分 第1組顏色 及 第2組顏色,非常麻煩,因此不建議使用 12位元
16位元 使用 2位元組 , 18位元 使用 3位元組
而 12位元,其一:顏色深度不足,可調整的顏色數量不多;
其二:寫入 DDRAM 的程序繁複,還要區分 第1組顏色 及 第2組顏色,非常麻煩,因此不建議使用 12位元
顏色深度換算
由於在一般電腦語言通常都是使用 24位元顏色深度,要使用其他位元顏色深度便需要轉換
Arduino 提供 map 可以簡單將目標數值的範圍轉換到成另一個範圍
Arduino 提供 map 可以簡單將目標數值的範圍轉換到成另一個範圍
byte y = map(x, 0x00, 0xFF, 0x00, 0x0F);
便可以簡單地將 8位元顏色深度 轉換成 4位元顏色深度
然後再要將常用的 24位元RGB 轉換,例如 16位元
然後再要將常用的 24位元RGB 轉換,例如 16位元
unsigned long convert24to18(unsigned long rgb) { unsigned long r = (rgb >> 16) & 0xFF; unsigned long g = (rgb >> 8) & 0xFF; unsigned long b = rgb & 0xFF; r = map(r, 0x00, 0xFF, 0x00, 0x3F) << 16; g = map(g, 0x00, 0xFF, 0x00, 0x3F) << 8; b = map(b, 0x00, 0xFF, 0x00, 0x3F); return r | g | b; } unsigned long convert24to16(unsigned long rgb) { unsigned long r = (rgb >> 16) & 0xFF; unsigned long g = (rgb >> 8) & 0xFF; unsigned long b = rgb & 0xFF; r = map(r, 0x00, 0xFF, 0x00, 0x1F) << 11; g = map(g, 0x00, 0xFF, 0x00, 0x3F) << 5; b = map(b, 0x00, 0xFF, 0x00, 0x1F); return r | g | b; } unsigned long convert24to12(unsigned long rgb, bool isFirst) { unsigned long r = (rgb >> 16) & 0xFF; unsigned long g = (rgb >> 8) & 0xFF; unsigned long b = rgb & 0xFF; if (isFirst) { r = map(r, 0x00, 0xFF, 0x00, 0x0F) << 12; g = map(g, 0x00, 0xFF, 0x00, 0x0F) << 8; b = map(b, 0x00, 0xFF, 0x00, 0x0F) << 4; } else { r = map(r, 0x00, 0xFF, 0x00, 0x0F) << 8; g = map(g, 0x00, 0xFF, 0x00, 0x0F) << 4; b = map(b, 0x00, 0xFF, 0x00, 0x0F); } return r | g | b; }
便可以將 24位元顏色深度 轉換為 不同顏色深度,例如:12位元、16位元、18位元
使用 PM5566 熒幕測試
顯示 Linux Tux 亦沒有問題
總結
TFT的操作訊號,有點像編寫程度時,使用 API 時執行一些 功能(Function) 或 方法(Method) ,例如:
軟件重設 0x01(); 及 捲動列數 0x37(#, #); 非常相似
軟件重設 0x01(); 及 捲動列數 0x37(#, #); 非常相似
過往使用 1位元組 便可以控制 8個像素 的單色 LCD 熒幕非常不同
最初閱讀總 300多頁的資料表,完全不懂操作方法,只能使用 Arduino 的函式庫
使用函式庫當然能夠運作正常,但卻不太明白運作原理
最後只能慢慢將函式庫的原始碼逆向工程,才理解運作原理
最初閱讀總 300多頁的資料表,完全不懂操作方法,只能使用 Arduino 的函式庫
使用函式庫當然能夠運作正常,但卻不太明白運作原理
最後只能慢慢將函式庫的原始碼逆向工程,才理解運作原理
另外在下發現使用預設的 SPI.h 函式庫執行速度比自行編寫的 SPI 更快
原因是 ATmega328P 為指定引腳供硬件級別的 SPI協定,不需要在軟件上透過編寫程式來模擬
而且原生的 硬件電子訊號 比 軟件模擬電子訊號 快得多 但原生SPI 必須使用預設引腳,軟件模擬SPI 則可以 改用其他引腳
原因是 ATmega328P 為指定引腳供硬件級別的 SPI協定,不需要在軟件上透過編寫程式來模擬
而且原生的 硬件電子訊號 比 軟件模擬電子訊號 快得多 但原生SPI 必須使用預設引腳,軟件模擬SPI 則可以 改用其他引腳
在下亦將自行編寫的函式庫上載,閣下有興趣可以
https://bitbucket.org/hkgoldenmra/tft240240rgbst7789module
或
https://create.arduino.cc/editor/hkgoldenmra/ecee6e5f-cd14-42ec-ad29-69e62cac805d/preview
或在 Terminal 輸入
https://bitbucket.org/hkgoldenmra/tft240240rgbst7789module
或
https://create.arduino.cc/editor/hkgoldenmra/ecee6e5f-cd14-42ec-ad29-69e62cac805d/preview
或在 Terminal 輸入
git clone "https://bitbucket.org/hkgoldenmra/tft240240rgbst7789module.git" --depth=1下載測試
沒有留言 :
張貼留言