什麼是 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 模組,撰寫測試程式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 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會用一個電位器做調節。
以上提供您參考,希望有幫助。