本系列將驅動一塊1.44"的128x128像素的彩色液晶屏幕。
並分幾個篇幅分別講述如何使其顯示色塊,英文數字,漢字以及圖片。
本文是系列的第一篇,目標是點亮屏幕並顯示指定色塊。
這次直接上代碼,大家自己複製代碼保存為py文件。文件名無所謂。
#!/usr/bin/env python import RPi.GPIO as GPIOimport timecs=23 # 片選rs=17 # 數據 / 命令 切換sda=13 # 數據scl=19 # 時鐘reset=27 # 復位# 傳輸bytedef setByteData(data): # print "" # print "S-setByte:", hex(data) for bit in range(0,8): # 傳入的數字從高位到低位依次判斷是否為1,若為1則設置高電平,
否則設置低電平 # 判斷的方法是先向左移位,把要判斷的位移動到最高位
然後跟0x80(1000 0000)相與, # 如果結果仍然是0x80(1000 0000)就表示最高位是1,
否則最高位就是0 if ((data<<bit) & 0x80 == 0x80): setBitData(True) # print "1", else: setBitData(False) # print "0", # print "" # print "E-setByte"def setBitData(data): GPIO.output(scl, False) GPIO.output(sda, data) GPIO.output(scl, True)def write_command(cmd): GPIO.output(cs, False) GPIO.output(rs, False) setByteData(cmd) GPIO.output(cs, True)def write_data(data): GPIO.output(cs, False) GPIO.output(rs, True) setByteData(data) GPIO.output(cs, True)def write_data_16bit(dataH, dataL): write_data(dataH) write_data(dataL)def lcd_reset(): GPIO.output(reset, False) time.sleep(0.1) GPIO.output(reset, True) time.sleep(0.1)def lcd_init(): lcd_reset() write_command(0x11) # Exit Sleep time.sleep(0.02) write_command(0x26) # Set Default Gamma write_data(0x04) write_command(0xB1)# Set Frame Rate write_data(0x0e) write_data(0x10) write_command(0xC0) # Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD write_data(0x08) write_data(0x00) write_command(0xC1) # Set BT[2:0] for AVDD & VCL & VGH & VGL write_data(0x05) write_command(0xC5) # Set VMH[6:0] & VML[6:0] for VOMH & VCOML write_data(0x38) write_data(0x40) write_command(0x3a) # Set Color Format write_data(0x05) write_command(0x36) # RGB write_data(0xc8) write_command(0x2A) # Set Column Address write_data(0x00) write_data(0x00) write_data(0x00) write_data(0x7F) write_command(0x2B) # Set Page Address write_data(0x00) write_data(0x00) write_data(0x00) write_data(0x7F) write_command(0xB4) write_data(0x00) write_command(0xf2) # Enable Gamma bit write_data(0x01) write_command(0xE0) write_data(0x3f)# p1 write_data(0x22)# p2 write_data(0x20)# p3 write_data(0x30)# p4 write_data(0x29)# p5 write_data(0x0c)# p6 write_data(0x4e)# p7 write_data(0xb7)# p8 write_data(0x3c)# p9 write_data(0x19)# p10 write_data(0x22)# p11 write_data(0x1e)# p12 write_data(0x02)# p13 write_data(0x01)# p14 write_data(0x00)# p15 write_command(0xE1) write_data(0x00)# p1 write_data(0x1b)# p2 write_data(0x1f)# p3 write_data(0x0f)# p4 write_data(0x16)# p5 write_data(0x13)# p6 write_data(0x31)# p7 write_data(0x84)# p8 write_data(0x43)# p9 write_data(0x06)# p10 write_data(0x1d)# p11 write_data(0x21)# p12 write_data(0x3d)# p13 write_data(0x3e)# p14 write_data(0x3f)# p15 write_command(0x29) # Display On write_command(0x2C)def show_single_color(DH,DL): for i in xrange(0,128): for j in xrange(0,128): write_data_16bit(DH,DL)try: GPIO.setmode(GPIO.BCM) GPIO.setup(cs, GPIO.OUT) GPIO.setup(rs, GPIO.OUT) GPIO.setup(sda, GPIO.OUT) GPIO.setup(scl, GPIO.OUT) GPIO.setup(reset, GPIO.OUT) lcd_init() write_command(0x2C) show_single_color(0xf8,0x00) # 紅色背景 while True: passexcept KeyboardInterrupt: pass# 清理GPIO口GPIO.cleanup()
然後,按下表連接液晶屏和樹莓派。(連接完以後屏幕應該是白屏狀態)
液晶屏 |樹莓派
|---
LCD |3.3V(不可以是5V!!)
SCK |GPIO19
SDA |GPIO13
AO |GPIO17
RESET |GPIO27
CS |GPIO23
GND |GND
VCC |3.3V(不可以是5V!!)
然後,執行!
sudo python prog.py
不出意外,你應該能看到屏幕被慢慢地掃描刷新成紅屏了!!!
想要跟硬體通信,給硬體發送指令,首先要搞清楚硬體的通信協議。
對於屏幕來說,其通信協議是由屏幕的主控IC晶片決定的,不同的主控IC晶片有不同的通信協議,也就是發送指令的方法。
不過,即使是不同的屏幕,也有可能使用同一款(或同系列)主控IC。
所以拿到一塊屏幕首先要搞清楚這塊屏幕使用的是哪種主控IC,谷歌,百度都可以,最方便的是問賣家。。。
本文使用的屏幕的主控IC是ST7735S,文末提供數據手冊下載。
簡單來說,通過SDA數據引腳和SCLK時鐘引腳串行輸入(從第一篇學習過來的一定不陌生)不同的指令數據就可以控制屏幕的輸出。
指令數據分成兩種,指令種類數據和指令內容數據。每次發送指令都是先發送指令種類再發送指令內容。
有點拗口,比如說我告訴屏幕「接下來我要改變屏幕顏色啦」,接著你發送了一串數字,硬體接收到這串數字後會作為一個顏色值應用在屏幕上。如果你告訴屏幕「接下來我要改變屏幕的亮度啦」,接著你又發送了一串數字,這次硬體接收到這一串數字後會作為亮度值應用在屏幕上。這麼說你再不明白我就。。。。
再回過頭來看代碼:
def write_command(cmd): GPIO.output(cs, False) GPIO.output(rs, False) setByteData(cmd) GPIO.output(cs, True)def write_data(data): GPIO.output(cs, False) GPIO.output(rs, True) setByteData(data) GPIO.output(cs, True)
上面這兩個函數,一個用來發送指令種類,一個用來發送指令內容。區別僅僅在於rs引腳的電平高低不同。
另外,屏幕初始化函數lcd_init()裡有一堆命令,天書一般,光是看就暈了。
別暈,這些代碼大多只用執行一遍,最開始不必關心,照葫蘆畫瓢即可。
下面是你需要注意的關鍵指令種類和內容:
下面的代碼設定的範圍是(0,0)-(127, 127),也就是全屏幕。
write_command(0x2A) # Set Column Addresswrite_data(0x00)write_data(0x00)write_data(0x00)write_data(0x7F)write_command(0x2B) # Set Page Addresswrite_data(0x00)write_data(0x00)write_data(0x00)write_data(0x7F)
write_command(0x2C)show_single_color(0xf8,0x00) # 紅色背景.def show_single_color(DH,DL): for i in xrange(0,128): for j in xrange(0,128): write_data_16bit(DH,DL)
這就是本文示例代碼顯示紅屏的原理。
其實只要學會了這3個命令的使用,基本上啥都能顯示了,無非是效率問題。給大家留個作業,自己完成本文開頭的最終效果彩帶。
本節到此結束,下一節我們繼續討論。
有人問博主0xF800是什麼鬼?紅色難道不應該是0xFF0000嗎?
這裡就引出一個RGB顏色數據格式的問題,0xF800和0xFF0000都是紅色,只是格式不一樣。
我們常見的0xFF0000這種格式一共是24位,紅綠藍各用8位表示,所以紅色就是FF,00,00。
而本文使用的是另一種叫RGB565的格式,這種格式一共只有16位,紅綠藍分別使用5位6位5位。
根據上圖,紅色應該是11111000 00000000,也就是0xF800。
其實,這款彩屏支持以下3種顏色格式
write_command(0x3a)write_data(0x03)
write_command(0x3a)write_data(0x05)
write_command(0x3a)write_data(0x06)
詳細內容請自己參考文檔(9.8 Data Color Coding)。
本文轉載自芒果愛吃胡蘿蔔的blog