說明
本文章是使用 PIC18F65J50 來驅動 WinStar 128x64 LCD (WG12864A),PIC 使用並列方式和 LCD 通訊,程式由 WinStar 官方提供的組合語言驅動範例程式修改成 C 語言版本。因為此款 LCD 的電源使用 5V,PIC 和 LCD 連接的通訊腳位要選擇有 5V Toleranted Input 的腳位,如 PORTD。
LCD 資料
外觀腳位資訊
電子特性
電路圖
LCD 初始化步驟
在初始化設定時,送出的 LCD 命令,必須分別送給 CS1 及 CS2 兩顆晶片。LCD 顯示畫面步驟
在顯示整個 LCD 畫面時,先送出 LCD 命令將 CS1 及 CS2 兩顆晶片切到第 1 個 page,Column 設為從最左邊開始寫入 (CS1 從 S1 開始、CS2 從 S65 開始)。接著對 CS1 送出左邊畫面資料,CS2 送出右邊畫面資料,依序的寫滿 8 個 page 後,整個 LCD 的畫面 (128 x 64 bits) 即填滿,最後加個 Delay 延遲一段時間再顯示下一個畫面,調整 Delay 的延遲時間,可以改變顯示的速度。LCD 畫面顯示控制示意圖
每個 page 分為左、右兩邊的晶片控制,每個晶片控制 64 x 8 bits,所以 1 個 page = 128 x 8 bits,總共有 8 個 page,所以全部有 (128 x 8) x 8 = 128 x 64 = 8,192 bits。通訊時序圖
在送出 DB0 ~ DB7 的 LCD 資料後,必須注意 RW 和 E 腳間拉的時間。寫入時序圖
- tASU (Address Setup time) 是 LCD 取得位址的設定時間 (取得要寫入的位址),在 R/W 腳拉 Low 和 E 腳拉 High 之間的時間,最短不能低於 140 ns。
- tDSU (Data Setup time) 為 LCD 資料的設定時間 (取得要寫入的資料),在 R/W 拉 Low 到 E 拉 High 之間的時間,最短不能低於 200 ns。
讀取時序圖
- tASU (Address Setup time) 是 LCD 取得位址的設定時間 (取得要寫入的位址),在 R/W 腳拉 Low 和 E 腳拉 High 之間的時間,最短不能低於 140 ns。
對比控制
LCD 的對比控制是調整 LCD 畫面亮點與暗點的深度比例,在這個電路接了一個 10K 的 VR (可變電阻) 用來調整 LCD 的對比。如下圖,使用 10K ~ 20K 的 VR,將 Vdd 及 Vee 接到 VR 的兩端,VR 的中間腳則拉到 Vo。
背光控制
LCD 底部有一塊會發光的 LED,有些 LCD 在上電時會自動點亮 LCD 背光,此款 LCD 則是提供 LED 的 A (陽極) 及 K (陰極) 腳位,使用外接一個可變電阻調整背光的亮度,在此電路是直接接上一個 220Ω 固定電阻。
WinStar 官方討論區的「How to turn on the backlight by 5V」說明如何計數背光接的電阻,舉例來說,以 WH1602L 的 LCD 為例,Datasheet 說 LED 的電壓為 3.5V,順向電流為 48mA,以歐姆定律來計算背光 LED 需接的電阻值為 31.25Ω。
參考目前此款 WG12864A 的 Datasheet,LED 的電壓為 4.2V,順向電流為 120mA。
以歐姆定律計算需接的電阻值如下:
RA = (5 - 4.2) / 120mA = 6.67Ω但實際接上 220Ω 電阻就夠亮了,此處計算方法可能有問題,擔心接上 6.67Ω 的電阻會燒掉背光 LED,所以直接接一個 220Ω 電阻,流過背光 LED 的電流計算如下。
Iled = (5V - 4.2V) / 220Ω = 3.6mA
程式碼
本程式由 WinStar 官方提供的組合語言驅動範例程式修改成 C 語言版本,此程式會輪流顯示全畫面的 7 張圖片,加上適當的延遲,形成一個動畫。下載完整程式碼:LCD_128x64.zip (20KB)
void LCDInit(void) { LCD_RS_TRIS = 0; LCD_RW_TRIS = 0; LCD_DATA_TRIS = 0; LCD_E_IO = 0; LCD_E_TRIS = 0; LCD_CS1_IO = 0; LCD_CS1_TRIS = 0; LCD_CS2_IO = 0; LCD_CS2_TRIS = 0; LCD_nRESET_IO = 1; LCD_nRESET_TRIS = 0; LCDSendCmd(0x40); // Set Y Column Address from 0 LCDSendCmd(0xB8); // Set Page to 0 LCDSendCmd(0xC0); // Set Display Start Line to 0 LCDSendCmd(0x3F); // Set Display ON } void LCDShow(void) { unsigned char image, page, column; const rom unsigned char *ptrData = Page[0]; for (image = 0; image < 7; image++) { for (page = 0; page < 8; page++) { LCDSendCmd(0xB8 + page); // Set Page (0xB8 ~ 0xBF) LCDSendCmd(0x40); // Set Y Column Address from 0 for (column = 0; column < 64; column++) LCDSendData(LCD_CS1, *ptrData++); for (column = 64; column < 128; column++) LCDSendData(LCD_CS2, *ptrData++); } LED_Toggle(LED1_IO); LED_Toggle(LED2_IO); delay100ms(5); } } void LCDSendCmd(unsigned char cmd) { // Send command to CS1 LCD_CS2_IO = 0; LCD_CS1_IO = 1; _LCDWrite(LCD_FUN_CMD, cmd); // Send command to CS2 LCD_CS1_IO = 0; LCD_CS2_IO = 1; _LCDWrite(LCD_FUN_CMD, cmd); } void LCDSendData(unsigned char cs, unsigned char data) { LCD_CS1_IO = (cs == LCD_CS1); LCD_CS2_IO = (cs == LCD_CS2); _LCDWrite(LCD_FUN_DATA, data); } static void _LCDWrite(unsigned char fun, unsigned char data) { LCD_RS_IO = fun; LCD_RW_IO = 0; LCD_DATA_IO = data; Nop(); LCD_E_IO = 1; // Address Setup time must > 140ns before high Nop(); Nop(); Nop(); LCD_E_IO = 0; // Data Setup time must > 200ns before low }
執行結果
電路有另外加一顆 10K 的可變電阻,用來調整 LCD 的對比度。
參考資料
- WinStar - How to set VEE value outside the LCD module
- WinStar - How to turn on the backlight by 5V
- WinStar - 240x128 Graphical LCD
0 意見:
張貼留言