因此在下購入一塊 像素為 192x64 的 點陣圖LCD熒幕
相信與 電子紙 差不多,但事實並非預期想像
基本上 點陣文字LCD熒幕 與 點陣圖LCD熒幕 相似,繪製圖案側與 電子紙 亦相似
點陣圖LCD熒幕 型號很多,每種都有些微分別
最初型號為 HD61202 ,而在下購買的 KS0108 是 HD61202 的延伸型號
還有自帶文字暫存器的 ST7920 ,操控上更似 HD44870
但在下此文章主要了解 KS0108 因此不詳細介紹 HD61202 及 ST7920
外觀
192x64 KS0108 點陣圖LCD熒幕 正面
點陣圖LCD熒幕 還很貼心地在 印刷電路板 上標示 引腳功能,很容易識別
引腳編號亦標示 第1引腳 及 最後引腳 的次序,同樣容易識別
不過引腳的針腳要自行焊接
192x64 KS0108 點陣圖LCD熒幕 背面
(在下將生產商資料隱藏,如果閣下有興趣請自行尋找)
192x64 KS0108 點陣圖LCD熒幕 背面引腳
引腳功能
而在下購買的 KS0108 屬於 ERM19264-3 版本,引腳排列與 HD61202 不同編號 | 引腳 | 方向 | 用途 |
---|---|---|---|
1 | D7 | 輸入/輸出 | 第7位元資料訊號 |
2 | D6 | 輸入/輸出 | 第6位元資料訊號 |
3 | D5 | 輸入/輸出 | 第5位元資料訊號 |
4 | D4 | 輸入/輸出 | 第4位元資料訊號 |
5 | D3 | 輸入/輸出 | 第3位元資料訊號 |
6 | D2 | 輸入/輸出 | 第2位元資料訊號 |
7 | D1 | 輸入/輸出 | 第1位元資料訊號 |
8 | D0 | 輸入/輸出 | 第0位元資料訊號 |
9 | E | 輸入 | 啟動訊號 |
10 | R/W | 輸入 | 寫入或讀取資料訊號 |
11 | RS | 輸入 | 指示或資暫存器訊號 |
12 | VO | 熒幕對比度 (接受 15V) | |
13 | VDD | 熒幕電源 (接受 5V) | |
14 | VSS | 熒幕接地 | |
15 | CSA | 輸入 | 切換晶片A訊號 |
16 | CSB | 輸入 | 切換晶片B訊號 |
17 | VOUT | 15V電源輸出 | |
18 | RESB | 輸入 | 重新設定訊號 |
19 | LED(A/K) | LED背光電源 (接受 5V) | |
20 | LED(K/A) | LED背光接地 |
線路接駁
在下使用 Fritzing 設計原型, Fritzing 是一種自由、開源、跨平台的電路圖設計軟件
在 Terminal 輸入
sudo apt-get install fritzing fritzing-parts或 按此安裝 fritzing 及 按此安裝 fritzing-parts
原型與預期相同,線路非常混亂
熒幕對比度
VOUT 輸出大約 15V電源輸出
VO 沒有接駁 VOUT 時不能顯示資料
VO 接駁 VOUT 時,能顯示熒幕,但由於對比度過高,同樣不能正常顯示資料
通過 電位器 來調整 VOUT 的電壓,便可以正常顯示資料
使用大約 7.5V電源 熒幕對比度的效果最適中
調整 VOUT 由 0V 至 15V 的效果
暫存器訊號
讀取 或 寫入 指示 或 資料 到 KS0108RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 用途 |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | O | 設定熒幕開關 (Screen On/Off) O 為 0 時,關閉熒幕,O 為 1 時,開啟熒幕 |
0 | 0 | 1 | 1 | L | L | L | L | L | L | 設定顯示開始行數 (Start Line) 0 至 63 為有效顯示起始行數 |
0 | 0 | 1 | 0 | 1 | 1 | 1 | R | R | R | 設定遊標的行位置 (Cursor at Row) 0 至 7 為遊標有效的行範圍 |
0 | 0 | 0 | 1 | C | C | C | C | C | C | 設定遊標的列位置 (Cursor at Column) 0 至 63 為遊標有效的列範圍 |
0 | 1 | B | 0 | O | R | 0 | 0 | 0 | 0 | 讀取狀態資料 (Read Status) B 為 0 時 閒置狀態 ;為 1 時 忙碌狀態 O 為 0 時 開啟熒幕 ;為 1 時 關閉熒幕 R 為 0 時 正常狀態 ;為 1 時 重置狀態 |
1 | 0 | D | D | D | D | D | D | D | D | 寫入資料 (Write Data) 寫入後 遊標的列位置 加1 ,超過範圍會 歸0 |
1 | 1 | D | D | D | D | D | D | D | D | 讀取資料 (Read Data) 讀取後 遊標的列位置 加1 ,超過範圍會 歸0 |
KS0108 基本使用 D0 至 D7 共8支引腳 控制暫存器
引腳 | 初始化 | 暫存器 週期 | |
---|---|---|---|
RS | 高/低 | ||
R/W | 高/低 | ||
E | 低 | 高 | 低 |
D7 | 高/低 | ||
D6 | 高/低 | ||
D5 | 高/低 | ||
D4 | 高/低 | ||
D3 | 高/低 | ||
D2 | 高/低 | ||
D1 | 高/低 | ||
D0 | 高/低 |
訊號波紋時序圖
熒幕控制
晶片選擇
KS0108 並不是直接控制整個熒幕,而是通過 CSA 及 CSB 2支引腳 的 訊號組合 控制 3組點陣圖LCD熒幕電壓 | 控制範圍 | |
---|---|---|
CSA | CSB | |
低 | 低 | 使用 左分割熒幕 |
低 | 高 | 使用 中分割熒幕 |
高 | 低 | 使用 右分割熒幕 |
高 | 高 | 不使用 熒幕 |
位置控制
高度 64點 的 點陣圖LCD熒幕 由於每行共使用 8位元資料,每1位元 為 1點,因此共有 8行行數/列數 | 左分割熒幕 第 0 至 63 列 | 中分割熒幕 第 0 至 63 列 | 右分割熒幕 第 0 至 63 列 |
---|---|---|---|
第 0 至 7 行 | 8位元資料 | 8位元資料 | 8位元資料 |
將 行數 及 列數 放大
行數/列數 | 分割熒幕 | |
---|---|---|
第 0 列 | 第 1 至 63 列 | |
第 0 行 | 第0位元資料 | 8位元資料 |
第1位元資料 | ||
第2位元資料 | ||
第3位元資料 | ||
第4位元資料 | ||
第5位元資料 | ||
第6位元資料 | ||
第7位元資料 | ||
第 1 至 7 行 | 8位元資料 |
LCD熒幕 與 電子紙 都是以 8位元 為一組資料,都是由 左上角 開始
電子紙 8位元資料 是 左至右 排列,再向 右移動 (因此 電子紙 闊度 必須是 8倍數)
而 LCD熒幕 8位元資料 是 上至下 排列,再向右移動 (因此 LCD熒幕 高度 必須是 8倍數)
寫入內容
內容會在 LCD熒幕 左上角 (0,0) 開始
當寫入資料為 0x01 時,會在 左上角 顯示
(電子紙 為 0x80 是 左上角,些微不同)
當寫入資料為 255 時,便會在 (0,0) 至 (0,7) 的位置顯示圖案
例如在下在 其中一個熒幕 的 第 0 至 4 列 及 第 0 行 顯示 5x7 的 A 字
先設計 點陣圖內容 例如
列數 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
十進制 | 62 | 80 | 144 | 80 | 62 |
十六進制 | 3E | 50 | 90 | 50 | 3E |
二進制 | 00111110 | 01010000 | 10010000 | 01010000 | 00111110 |
行數 / 列數 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
0 | |||||
將資料寫入至 KS0108 ,便可以顯示一個類似 HD44780 的字符
但要留意如果接近末端的位置,例如第 62 列開始顯示圖案,可能會影響內容
行數 / 列數 | 0 | 1 | 2 | 3 至 61 | 62 | 63 |
---|---|---|---|---|---|---|
0 | ||||||
熒幕之間並不相通,因此內容到達熒幕最後位置,游標列位置會自動設定為 0 ,會將寫入的內容切開
而不會自動移動到下個熒幕或停止寫入資料
如果原本列位置已經有內容,會被新內容取代
並不一定所有資料都可以預期使用 64列 來顯示,因此有時需要跨越超過一個熒幕顯示內容
行數 / 列數 | 左分割熒幕 | 中分割熒幕 | |||||
---|---|---|---|---|---|---|---|
0 至 61 | 62 | 63 | 0 | 1 | 2 | 3 至 63 | |
0 | |||||||
要自動到移動下個熒幕或停止寫入資料,需要自行編寫控制程式
還有 設定開始行數 時亦要效慮 內容高度,避免將圖內容切開
例如將 設定開始行數 為 4
行數 / 列數 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
0 (第 4 至 7 位元) | |||||
1 至 7 | |||||
0 (第 0 至 3 位元) | |||||
會將整個熒幕所有行數向上或向下偏移,因此不會影響已寫入的內容,只影響顯示效果
在 LCD熒幕顯示圖案
在下在 LCD熒幕 上顯示圖案,都不可能手工逐點顯示,在下亦是借用 ImageMagick 將圖案轉換成 可移植點陣圖 (Portable BitMap (PBM))
在 Terminal 輸入
sudo apt-get install imagemagick或 按此安裝 ImageMagick
並將 PBM 內容,以每8格資料分割,最後將 8格資料(位元) 轉換成 十六進制資料 便完成
PBM 與 LCD熒幕 顯示方式都是相同, 0 為無色, 1 為有色
由於 LCD熒幕 及 電子紙 顯示方式不同,因此在下 轉換圖案為電子紙點陣方式 改為 轉換圖案為LCD熒幕點陣方式
#!/bin/bash file="image" width=`convert "${file}" -print "%w" "/dev/null"` height=`convert "${file}" -print "%h" "/dev/null"` if [ $(($height%8)) -eq "0" ]; then canvas="" i="0" while [ "${i}" -lt "8" ]; do data=`convert "${file}" -crop "${width}x8+0+$(($i*8))" +repage -rotate 90 -flatten -monochrome -compress none pbm:- | tail +3 | tr -d " \n" | sed -r "s/(.{8})/\1, /g"` canvas=`printf "${canvas}\n{${data}},"` i=$(($i+1)) done v="0" while [ "${v}" -le "255" ]; do b=`printf "%08d" $(echo "obase=2;${v}" | bc)` h=`printf "0x%02X" "${v}"` canvas=`echo "${canvas}" | sed -r "s/${b}/${h}/g"` v=$(($v+1)) done echo "${canvas:1}" else echo "Image height is not multiple of 8" fi
同樣不同型號的 Arduino 的記憶空間不同,要考慮 Arduino 記憶空間
但 LCD熒幕 不能保存資料,因此圖案超出記憶空間,不像 電子紙 能分開數次寫入資料,最後一次過將資料送出
由於 KS0108 沒有文字庫,如果需要在 LCD熒幕 上顯示文字內容,便需要自行繪製
(其實之前使用的 電子紙 都是沒有文字庫,但當時忘記說明)
因此借用 GNU Unifont 自由開源的點陣圖字型作為文字原型
(向朋友查詢,理想的中文字顯示效果,建議使用 24x24 (3行 24列) ,但這種尺寸的文字會減少大量空間
以 192x64 像素,顯示 24x24 的文字 ,只有 16個文字,而且還剩餘 2行 無法使用;而 16x16 則有 48個文字,可以用盡整個顯示熒幕
因為在下使用 16x16
而在下當然都用盡方法懶惰,盡量不會逐個字人手處理
先製作 SVG 範本 (假設檔案名是 template.svg)
<svg version="1.1" width="16" height="16" xmlns="http://www.w3.org/2000/svg"> <g transform="scale(1)"> <rect x="0" y="0" width="16" height="16" fill="#ffffff" fill-opacity="1" stroke-opacity="0"/> <text x="0" y="14" font-family="Unifont" font-size="16" fill="#000000" fill-opacity="1" stroke-opacity="0"></text> </g> </svg>GNU Unifont 的文字會向下偏移 2個像素,因此需要減去偏移值,因此 SVG text元素 的 y值 為 14
根據 GNU Unifont 官方資料,中文字由 4E00(hex) = 19968(dec) 至 9FCF(hex) = 40911(dec)
(實際還有其他 CJK (中日韓) 文字,但主要使用的中文字在這範圍)
另外還需要安裝 GNU Unifont 字型,否則不能顯示 GNU Unifont 字型,亦不能匯出字型圖片
再編寫腳本
#!/bin/bash template="template.svg" temp="temp.svg" d="19968" while [ "${d}" -le "40911" ]; do h=`printf "%X" "${d}"` c=`printf "\\u${h}"` cat "${template}" | sed -r 's/>.*<\/text>$/>'"${c}"'<\/text>/g' >"${temp}" inkscape "${temp}" -z -e "output/${c}.png" 2>/dev/null d=$(($d+1)) done腳本需要使用 Inkscape ,一種自由、開源的向量圖像製作軟件,支援指令操作
在 Terminal 輸入
sudo apt-get install inkscape或 按此安裝 Inkscape
在下大約用 90分鐘 將 20944個 中文字匯出成圖像
如果閣下有更好的方法,可以自行處理,及分享給其他人
然後可以再使用之前的腳本將圖像轉換成 8位元資料
文字資料測試
(效果與 HD44780 非常相似)
閣下有興趣可以到 https://create.arduino.cc/editor/hkgoldenmra/c0ea25bc-d975-4de0-8e60-003596fc0a7b/preview
或 https://bitbucket.org/hkgoldenmra/ks0108module
或在 Terminal 輸入
git clone "https://bitbucket.org/hkgoldenmra/ks0108module.git" --depth=1
補充資料
另外 Arduino 官方的 Arduino IDE 已經包含大量 LCD熒幕範例
可以很快速地控制 LCD熒幕
如果閣下不想打算自行開發,可以使用已經開發完善的函式庫
在 Tools > Manage Libraries...
Type 及 Topic 選擇 ALL
搜尋欄位輸入 KS0108
安裝搜尋結果的函式庫
安裝後的函式庫會標示 INSTALLED
在 File > Examples > U8g2 > full_buffer > HelloWorld
便可以開啟函式庫例子
U8g2函式庫 已經預設大量 LCD熒幕模組 的 建構子
根據 建構子 描述,解除註解,並將線路接駁到對應引腳
但由於在下希望能夠學習控制方法,因此沒有測試函式庫的效果
不過已經發展成熟的函式庫,能夠節省很多學習時間,若果需要短時間達至效果,使用已經穩定開發的函式庫會比較穩妥及快捷
總結
其實在下最初購買回來時,由於與 HD44780 很相似,而且 印刷電路板 上已經顯示引腳用途,因此在下沒有翻查資料便接駁線路但發現引腳已經接駁,雖然 LED背光 能夠亮著,但 VO 不論接駁到 Arduino 的 5V 或 GND 引腳都沒有反應才翻查資料
最初以為是 HD61202 ,發現 HD61202 的引腳次序類購買的 LCD熒幕 不同,回到購買的網頁才知道是 KS0108
但尋找 KS0108 旳資料發現只有晶片資料,而不是模組資料
再查資料才知道這是使用 KS0108 的 ERM19264-3 的 LCD熒幕模組
在下估計是 V0 出現問題,但文件只是說明 VO 是 LCD Contrast Reference
再仔細查看,概要圖顯示 VO 需要接駁到 VOUT 終於能顯示畫面,但對比度調整至最高,因此根本看不到內容 (對比度最高或最低都會看不到內容)
因此在下將 VOUT 及 GND 接駁到 電位器輸入,再將 電位器輸出 接駁到 VO,調整對比度,終於能夠正確顯示內容
之後的操作便與 HD44780 大致相同,而且更少起動步驟,即使從由零開學習使用,亦不會太多時間
沒有留言 :
張貼留言