直接按照sample code去執行....大致上來說是可以執行...
他這個module 跟一般的LCD 16x2的模組不太一樣的是
有外接兩個控制IC......
這兩個控制IC分別為PCA9633 LED 4bit Fm+ led driver IC (背光控制) 和 AIP31068L (文字控制)
所以你只要拿兩根GPIO來當I2C 就可以控制它們....
GPIO2 -> SDA
GPIO3 -> SCL
然後啟動RPI內部的i2 hardware module 就可以控制lcd module....
先來看背光的部分 ....
首先來看一下sample code...
其中 DISPLAY_RGB_ADDR = 0x62
# set backlight to (R,G,B) (values from 0..255 for each) | |
def setRGB(r,g,b): | |
bus.write_byte_data(DISPLAY_RGB_ADDR,0,0) | |
bus.write_byte_data(DISPLAY_RGB_ADDR,1,0) | |
bus.write_byte_data(DISPLAY_RGB_ADDR,0x08,0xaa) | |
bus.write_byte_data(DISPLAY_RGB_ADDR,4,r) | |
bus.write_byte_data(DISPLAY_RGB_ADDR,3,g) | |
bus.write_byte_data(DISPLAY_RGB_ADDR,2,b) | |
它定義了一個function..... setRGB(r,g,b)
裡面用I2C 傳輸了6個Byte......分別針對
address data
0 0
1 0
8 0xaa
4 r_val
3 g_val
2 b_val
看了 code以後一定沒有甚麼感覺...因為你不曉得為什麼要這樣做....
所以我來看一下datasheet...
以8pin 的version 來看....
slave address 為 (0x62 <<1) | RW
剛好就是 這行 code定義的 ....
DISPLAY_RGB_ADDR = 0x62
以後換了其他的IC...先查datasheet...再可以一樣畫葫蘆
接下來看一下register summary
可以看到...
reg 0h -> Mode register 1
reg 1h -> Mode register 2
reg 8h -> LED output state register
reg 4h -> brightness control LED2
reg 3h -> brightness control LED1
reg 2h -> brightness control LED0
接下來再看更詳細一點
sample code 是填 0 (bus.write_byte_data(DISPLAY_RGB_ADDR,0,0))
所以意思就是說....PCA9633 不需要去回應
output drivers not enabled.......4LED outputs 被 設定 open-drain 架構
output change on STOP...
這些都跟 I2C 的protocol 比較有關....
接下來再看來reg 0x8
sample code 是填 0 (bus.write_byte_data(DISPLAY_RGB_ADDR,0x8,0xaa))
0xaa ->1010 _1010 ....也就是 LDR 3 到LDR0 都是填 10b.....
意思就是 LED driver X(3,2,1,0) 都是用 PWMx register來控制
接下來看 reg 0x4...也就是PWM register
不過這邊我看了datasheet...沒有看到他說....reg4h 就是R的value...不過這個好解決...
try and error就知道....以上大概就是RGB backlight的控制方式.....
直接從別人寫好的sample code去 逆向工程....真的比自己花時間去try快很多....
前提是別人寫好的sample code會動歐....
接下來看文字的部分 ....
sample code如下:DISPLAY_TEXT_ADDR = 0x3e
def textCommand(cmd): | |
bus.write_byte_data(DISPLAY_TEXT_ADDR,0x80,cmd) |
def setText(text): | |
textCommand(0x01) # clear display | |
time.sleep(.05) | |
textCommand(0x08 | 0x04) # display on, no cursor | |
textCommand(0x28) # 2 lines | |
time.sleep(.05) | |
count = 0 | |
row = 0 | |
for c in text: | |
if c == '\n' or count == 16: | |
count = 0 | |
row += 1 | |
if row == 2: | |
break | |
textCommand(0xc0) | |
if c == '\n': | |
continue | |
count += 1 | |
bus.write_byte_data(DISPLAY_TEXT_ADDR,0x40,ord(c)) | |
可以看出大概的流程是
clear display -> set display on, no cursor -> set 2 lines -> sleep....等待一段時間 ....
-> 然後用一個loop把你要傳的文字串拆解成一個一個的文字傳送...處理換行...
不過沒有搭配datasheet...也是不知其所以然....
接下來看看datasheet.....
可以看出來 address (0x3e<<1) | rw_bit ->(DISPLAY_TEXT_ADDR = 0x3e)
然後control byte 會指定device 的register offset..可以看得出...他只有兩種選擇....
0x80和 0xc0 ...就只差在 RS bit...從下圖的instruction set可以看的出來...
RS 為 '0' -> address 0x80
RS 為 '1' -> address 0xc0 (但是sample code的address為0x40...但應該沒有差)
datasheet上有給一個instruction 的流程圖
對照著 code看就很清楚...
textCommand(0x01) # clear display SCREEN CLEAR
textCommand(0x08 | 0x04) # display on, no cursor, CURSOR RETURN...
這就是DISPLAY SWITCH.....把(D,C,B) 設成 (1,0,0)
D : Display on/off -> on
C : cursor on/off -> off
B : blink on/off -> off
textCommand(0x28) # 2 lines
這就是function set .... 8 -> D3 -> 2R
接下來看
bus.write_byte_data(DISPLAY_TEXT_ADDR,0x40,ord(c))
這邊他呼叫了一個function ord()
查了一下google....
內建函數(function) ord() ,回傳字元參數(parameter) c 的Unicode 編碼值
要把你的字元轉換成 Unicode的編碼值....然後才可以傳送進去
Reference : 背光datasheet
Reference : 文字datasheet