2016年1月21日 星期四

Grovepi+ LCD module with RGB Backlight 詳細研究




直接按照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 不需要去回應 


sample code 是填 0  (bus.write_byte_data(DISPLAY_RGB_ADDR,1,0))

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))

其實就是在寫  data write (0x40 -> RS 為 '1')

這邊他呼叫了一個function  ord()

查了一下google....

內建函數(function) ord() ,回傳字元參數(parameter) c 的Unicode 編碼值

要把你的字元轉換成 Unicode的編碼值....然後才可以傳送進去



Reference : 背光datasheet
Reference : 文字datasheet






沒有留言:

張貼留言