什麼是 SPI?簡言之,也是一種串列傳輸資料的介面,和 I²C 介面有些類似但需要三線信號 (SCLK, MOSI, MISO) 做主從裝置間的雙向傳輸,一組匯流排上只允許一個主裝置 (Master),可有多個從屬裝置 (Slave) 但需要再各有一線選擇信號 (CS),使用上較簡易。欲了解較詳盡的可看這篇介紹 Serial Peripheral Interface (SPI) 的內文。另外,要啟用 Raspberry Pi 的 SPI 介面之前也可參考這篇範例以確認 SPI 相關的模組是否已安裝載入。
LCD12864 在市面上有多種版本,20 線腳位定義偶有不同,我用的這版若選擇使用 SPI 則腳位定義如下:
pin# description
==== ========================================
1 GND - 電源輸入, 0V
2 VCC - 電源輸入, 5V
3 V0 - LCD偏壓輸入, 控制顯示對比
4 CS - 晶片選擇輸入, 1:enable 0:disable
5 SID - 串列資料輸入
6 SCLK - 串列時脈輸入
15 PSB - 控制介面選擇輸入, 0:串列 1:並列
17 /RST - 重設輸入, 低態動作
18 VOUT - LCD倍壓輸出
19 LED_A - 背光LED電源正極
20 LED_K - 背光LED電源負極
與 Raspberry Pi 之間的 SPI 接線:
Raspberry Pi LCD12864 ============ ======== #19 MOSI -- #5 SID #23 SCLK -- #6 SCLK #24 CE0 -- #4 CS
參考 LCD12864 的串列模式時序圖,每次傳送封包的第一個 byte 的前 5 個位元必須固定為 1 (High),接下來兩個位元是 RW 與 RS,而最末位元固定為 0 (Low)。要傳送的指令或資料緊接在其後,每一個 byte 將被當做 4 位元模式分拆組成 2 個 byte。
Python 程式使用 SPI 要借重 spidev 模組,撰寫測試程式如下:
import spidev
import time
class LCD12864B:
def __init__(self, port, cs):
self.spi = spidev.SpiDev()
self.spi.open(port, cs)
self.spi.cshigh = True
def writeCommand(self, cmd):
self.spi.xfer2([0xf8, cmd & 0xf0, (cmd << 4) & 0xf0])
time.sleep(0.001)
def writeByte(self, byte):
self.spi.xfer2([0xfa, byte & 0xf0, (byte << 4) & 0xf0])
def writeData(self, data):
bytes = [0xfa]
for c in data:
b = c.encode('big5')
if len(b) == 1:
bytes.append(ord(c) & 0xf0)
bytes.append((ord(c) << 4) & 0xf0)
elif len(b) == 2:
bytes.append(ord(b[0]) & 0xf0)
bytes.append((ord(b[0]) << 4) & 0xf0)
bytes.append(ord(b[1]) & 0xf0)
bytes.append((ord(b[1]) << 4) & 0xf0)
self.spi.xfer2(bytes)
time.sleep(0.001)
def reset(self):
self.writeCommand(0x30)
self.writeCommand(0x0c)
self.writeCommand(0x01)
self.writeCommand(0x06)
def close(self):
self.spi.close()
def position(self, row, col):
addr = {
0: 0x80,
1: 0x90,
2: 0x88,
3: 0x98,
}
ac = addr.get(row) + col
self.writeCommand(ac)
def display(self, row, col, str):
self.position(row, col)
self.writeData(str)
lcd = LCD12864B(0, 0)
lcd.reset()
lcd.display(0, 0, u"三山半落青天外")
lcd.display(1, 0, u'二水中分白鷺洲')
lcd.display(2, 0, u"總為浮雲能蔽日")
lcd.display(3, 0, u"長安不見使人愁")
lcd.close()
這次僅簡單的做了顯示中文字型的測試,LCD12864 也能有做圖像顯示的能力,以後有機會再試試。


hi;
回覆刪除打擾;
能否跟您請教這款 LCD 在哪可以買到?
感謝
在露天拍賣上可以找到有幾個賣家有賣,我買過的是 http://goods.ruten.com.tw/item/show?21537639838971
刪除供您參考。
請問能否協助提供 C 程式? 因我不熟悉Python, 感謝
回覆刪除抱歉,本文的實驗程式範例僅有python。
刪除我使用了您的python code, 但LCD沒有顯示任何字, 我多加了 PSB pin = low, 不知道有沒有建議?
回覆刪除使用SPI介面需將PSB接地(low)沒錯。
刪除看不到輸出的情況,通常我會再考慮檢視所有信號與電源(包含背光)的接線。
通電後程式執行前會用一個RC電路先做RST重設,另外顯示對比V0會用一個電位器做調節。
以上提供您參考,希望有幫助。