基于單片機(jī)的VRAM型彩色液晶顯示模塊設(shè)計(jì)
介紹一種基于AVR單片機(jī)和硬件漢字庫(kù)的VRAM 型彩色液晶顯示模塊的設(shè)計(jì)。給出彩色液晶顯示器的顯示原理、硬件接口設(shè)計(jì)框圖以及硬件漢字庫(kù)的制作和應(yīng)用,同時(shí)給出基于C語(yǔ)言的程序設(shè)計(jì)模塊,實(shí)現(xiàn)了應(yīng)用VRAM 型液晶的模塊化,便于移植在其他類(lèi)型的單片機(jī)。
1 引言
隨著電子技術(shù)的飛速發(fā)展,越來(lái)越多的領(lǐng)域應(yīng)用到以單片機(jī)為控制核心、用液晶作為顯示終端的數(shù)字化設(shè)備。彩色液晶顯示器作為當(dāng)代高新技術(shù)的結(jié)晶產(chǎn)品,不但具有超薄平面、顯示信息豐富、色彩逼真的特點(diǎn),而且還具有體積小、耗電省、壽命長(zhǎng)、無(wú)輻射、抗震、防爆等其他類(lèi)型顯示器無(wú)可比擬的優(yōu)點(diǎn),因而是工控儀表、機(jī)電設(shè)備等行業(yè)更新?lián)Q代的理想顯示器件。因此基于單片機(jī)系統(tǒng)的彩色液晶顯示模塊的使用也越來(lái)越廣泛。本文介紹一種基于AVR 單片機(jī)和硬件漢字庫(kù)的彩色液晶顯示模塊,該模塊實(shí)現(xiàn)了在彩色液晶顯示器上顯示不同顏色的中文、英文、數(shù)字及簡(jiǎn)單的畫(huà)圖功能。
2 液晶顯示器顯示原理
本模塊采用的液晶顯示器是河南友利華高科技有限公司生產(chǎn)的YD2502 彩色液晶VRAM 型顯示器。它的點(diǎn)陣數(shù)是320 ×240 ,VRAM 容量是64 k ×8 位,由于屏幕上的任何一點(diǎn)都是由R(紅) 、G(綠) 、B(藍(lán)) 3 種顏色組成,且灰度不可調(diào)節(jié),因此顯示顏色為8 色?;驹砜驁D如圖1所示。DC/ DC 轉(zhuǎn)換器產(chǎn)生液晶所用各種驅(qū)動(dòng)電壓,DC/ AC 逆變器則用來(lái)點(diǎn)亮冷陰極背光燈, 顯示驅(qū)動(dòng)邏輯電路采用了優(yōu)化邏輯電路,利用分時(shí)技術(shù)讓顯示與寫(xiě)入數(shù)據(jù)同時(shí)進(jìn)行,實(shí)現(xiàn)了畫(huà)面的高速更新,且互不干擾。其顯示原理是:在顯示器內(nèi)部含有一個(gè)顯示緩沖區(qū)與屏幕顯示一一對(duì)應(yīng),使用時(shí)只需向緩沖區(qū)里寫(xiě)入相應(yīng)的數(shù)據(jù),屏幕上即可顯示出對(duì)應(yīng)的彩色圖形或文字,也就是說(shuō)該顯示器可作為單片機(jī)系統(tǒng)的一個(gè)外部存儲(chǔ)器就可以實(shí)現(xiàn)彩色信息的顯示。
圖1 YD2502 原理框圖
3 硬件系統(tǒng)設(shè)計(jì)
3. 1 硬件總體設(shè)計(jì)
本模塊中使用的單片機(jī)是AVR 系列單片機(jī)中功能最強(qiáng)的A Tmega128 。該單片機(jī)具有豐富的片上資源如具有128 kB 在線(xiàn)可重復(fù)編程Flash、4 kB 的E2 PROM、4 kB 的內(nèi)部SRAM、48 個(gè)I/ O 端口、34 個(gè)不同的中斷源、可尋址64 kB 的地址空間、ISP 下載以及J TA G 仿真等功能。詳細(xì)介紹請(qǐng)參考其數(shù)據(jù)手冊(cè)。
圖2 是該模塊硬件系統(tǒng)總體設(shè)計(jì)框圖。由于YD2502 的顯示緩沖區(qū)里的內(nèi)容是不能讀出的,為了保存寫(xiě)入內(nèi)容,在該模塊中還外擴(kuò)了一片存儲(chǔ)器芯片61LV5128 ,其存儲(chǔ)容量為512 kB ,除了保存YD2502 顯示緩沖區(qū)里的數(shù)據(jù)外,還為使用本模塊的嵌入式系統(tǒng)提供了擴(kuò)展應(yīng)用。由于A Tmega128 的尋址范圍只達(dá)到64 KB ,因此采用了分頁(yè)管理技術(shù)來(lái)操作512 kB 的存儲(chǔ)空間。在具體電路設(shè)計(jì)時(shí),將A Tmega128 的PB3 ~ PB0連接到61LV5128 的高4 位地址線(xiàn)上,將512 kB的存儲(chǔ)空間分成16 頁(yè),每頁(yè)32 kB。硬件漢字庫(kù)芯片AT29C040A 的存儲(chǔ)容量也是512 kB ,與CPU的接口設(shè)計(jì)與61LV5128 是類(lèi)似的,只需將片選信號(hào)和高4 位地址線(xiàn)接在不同的I/ O 口上就可以了。
圖2 硬件設(shè)計(jì)圖
3. 2 YD2502 的接口設(shè)計(jì)
YD2502 的接口方式采用總線(xiàn)方式,外部引線(xiàn)包括數(shù)據(jù)總線(xiàn)(DB7~DB0) 、片選信號(hào)(/ CS) 、讀寫(xiě)輸入(/ RD、/ WR) 和寄存器選擇信號(hào)(RS) ,可以直接掛接到單片機(jī)的總線(xiàn)上,作為單片機(jī)的某部分內(nèi)存來(lái)使用。接口采用16 針插座,引腳定義請(qǐng)參閱其說(shuō)明書(shū)。
根據(jù)YD2502 可以作為單片機(jī)的外部存儲(chǔ)器使用的接口特性,將A Tmega128 的讀寫(xiě)信號(hào)線(xiàn)與YD2502 的讀寫(xiě)信號(hào)線(xiàn)直接連接,具體接口設(shè)計(jì)原理如圖3 所示。
圖3 AT128 與YD2502 的接口
3. 3 硬件漢字庫(kù)的制作
本模塊使用了硬件漢字庫(kù),省去了利用漢字取模軟件獲取點(diǎn)陣數(shù)據(jù)的麻煩,而且還避免了為保存這些數(shù)據(jù)而開(kāi)辟的大量程序存儲(chǔ)空間。
漢字庫(kù)中要燒寫(xiě)的點(diǎn)陣文件是UCDOS 軟件中的文件HZK16 ,該文件是16 ×16 的國(guó)際漢字點(diǎn)陣文件,文件中按漢字區(qū)位碼從小到大依次存放國(guó)標(biāo)區(qū)位碼表中的所有漢字,每個(gè)漢字占用32字節(jié),每個(gè)區(qū)為94 個(gè)漢字。漢字庫(kù)芯片采用的是AT29C040A ,該芯片是ATMEL 公司生產(chǎn)的512 kB的Flash ROM。在制作時(shí),燒寫(xiě)過(guò)程和普通的程序存儲(chǔ)器的編程基本相同,只要注意選擇正確的型號(hào)和在選擇打開(kāi)HZK16 的方式時(shí)用二進(jìn)制方式就可以了,編程校驗(yàn)成功后,取下備用,硬件漢字庫(kù)芯片就制作好了。
實(shí)際上若顯示HZK16 的文件屬性,其大小為262 kB ,而AT29C040A 的存儲(chǔ)容量為512 kB ,超出部分可以存儲(chǔ)用戶(hù)固定的漢字、字母和數(shù)字的代碼,從而使顯示內(nèi)容更加靈活豐富。4 軟件系統(tǒng)設(shè)計(jì)及實(shí)現(xiàn)
4. 1 操作YD2502 的程序設(shè)計(jì)
YD2502 的指令碼格式如下:
其中: CA1 ,CA0 組合功能為內(nèi)部寄存器通道的選擇,功能如下:
DISP :顯示控制位。
當(dāng)DISP 設(shè)置為“1”時(shí),液晶顯示模塊為開(kāi)顯示狀態(tài)。
當(dāng)DISP 設(shè)置為“0”時(shí),液晶顯示模塊為關(guān)顯示狀態(tài)。
X:表示未用位,可設(shè)為“0”。
ATmega128 訪(fǎng)問(wèn)外部存儲(chǔ)器的軟件設(shè)計(jì)步驟是:先用extern 聲明一個(gè)外部變量,再用map2ping_init 函數(shù)(外部存儲(chǔ)地址分配函數(shù)) 分配給此變量一個(gè)外部存儲(chǔ)地址(因A Tmega128 內(nèi)部有4 kB 的SRAM 所以外部存儲(chǔ)地址范圍為1000H~0FFFFH) ,那么對(duì)該變量的操作就實(shí)現(xiàn)了CPU 對(duì)相應(yīng)地址的外部存儲(chǔ)空間的訪(fǎng)問(wèn)。
根據(jù)此步驟,對(duì)YD2502 寫(xiě)指令和寫(xiě)數(shù)據(jù)的具體函數(shù)如下:
extern unsigned char LCD_DA TA ;
void mapping_init (void) {
asm(“。 area memory (abs) n”
“。 org 0x4000n ” / / 分配給LCD_DA TA 的地址為4000H
“ _LCD_DA TA : : . blkb 1 n”/ / 存儲(chǔ)空間為1
“。 text/ n”) ;}
寫(xiě)指令函數(shù)如下:
void LCD_writeinstr (unsigned char data) {
PORTD & = 0xFC ; / / 置/ CS 為低電平,并且置RS 為低電平,處于寫(xiě)指令狀態(tài)
LCD_DA TA = data ; / / 送數(shù)據(jù)
PORTD | = 0x03 ;} / / 置/ CS 和RS為高電平
寫(xiě)數(shù)據(jù)函數(shù)如下:
void LCD_writedata (unsigned char data) {
PORTD & = 0xFE ; / / 置/ CS 為低,并且置RS 為高電平,處于寫(xiě)數(shù)據(jù)狀態(tài)
LCD_DA TA = data ; / / 送數(shù)據(jù)
PORTD | = 0x01 ;} / / 置/ CS 為高電平除了上面兩個(gè)基本的函數(shù)外,對(duì)YD2502 最基本的操作是往VRAM 里寫(xiě)數(shù)據(jù),根據(jù)上面給出的指令碼,具體函數(shù)如下:
# define HREG 0x09 / / 顯示地址高8 位寄存器指令
# define L REG 0x08 / / 顯示地址低8 位寄存器指令
# define DA TARW 0x0A / / 顯示數(shù)據(jù)讀寫(xiě)通道指令
void LCD_filldata ( unsigned int address ,
unsigned char data) {
unsigned char addrh ,addrl ;
addrh = (char) (address > > 8) ; / / 取內(nèi)存地址的高8 位數(shù)據(jù)
addrl = (char) (address &0xFF) ; / / 取內(nèi)存地址的低8 位數(shù)據(jù)
LCD_writeinst r ( HREG) ; / / 送顯示地址高8 位寄存器指令
LCD_writedata (addrh) ; / / 送內(nèi)存地址的高8 位數(shù)據(jù)
LCD_writeinst r (L REG) ; / / 送顯示地址低8 位寄存器指令
LCD_writedata (addrl) ; / / 送內(nèi)存地址的低8 位數(shù)據(jù)
LCD_writeinst r (DA TARW) ; / / 送顯示數(shù)據(jù)讀寫(xiě)通道指令
LCD_writedata (data) ;} / / 送數(shù)據(jù)
4. 2 畫(huà)點(diǎn)函數(shù)的實(shí)現(xiàn)
要在液晶上實(shí)現(xiàn)顯示字符和畫(huà)圖等功能,在屏幕上顯示一個(gè)點(diǎn)是實(shí)現(xiàn)這些功能的基礎(chǔ)。畫(huà)點(diǎn)函數(shù)實(shí)現(xiàn)的步驟是:首先確定該點(diǎn)對(duì)應(yīng)的VRAM中的內(nèi)存位置,找到該點(diǎn)具體對(duì)應(yīng)的數(shù)據(jù)位,填充顯示顏色的數(shù)據(jù),該點(diǎn)就按對(duì)應(yīng)的顏色顯示出來(lái)了。
4. 2. 1 顯示內(nèi)存與屏幕點(diǎn)陣的對(duì)應(yīng)關(guān)系
YD2502 屏幕點(diǎn)陣為320 ×240 ,每一個(gè)點(diǎn)對(duì)應(yīng)3 個(gè)像素(RGB) ,屏幕上8 個(gè)點(diǎn)對(duì)應(yīng)內(nèi)存3 個(gè)字節(jié),一行對(duì)應(yīng)320/ 8 ×3 = 120 個(gè)字節(jié),其對(duì)應(yīng)關(guān)系如下:
其中R ,G,B 表示紅、綠、藍(lán)三原色,D7~D0 表示對(duì)應(yīng)的數(shù)據(jù)位。
對(duì)于屏幕上坐標(biāo)為( X , Y) 的點(diǎn),其對(duì)應(yīng)內(nèi)存地址的計(jì)算方法為:
當(dāng)Y = 0 時(shí) SRAM = 0EFH ×100H +[ IN T( X/ 8) ] ×3
當(dāng)Y > 0 時(shí) SRAM = ( Y - 1) ×100H +[ IN T( X/ 8) ] ×3
通過(guò)( X/ 8) 的余數(shù)得出具體的內(nèi)存位置:
當(dāng)余數(shù)為0 則 RAM = SRAM [ 1110 ,0000 ]
當(dāng)余數(shù)為1 則 RAM = SRAM [ 0001 ,1100 ]
當(dāng)余數(shù)為2 則 RAM1 = SRAM [ 0000 ,0011 ]
RAM2 = SRAM + 1[1000 ,0000 ]
當(dāng)余數(shù)為3 則 RAM = SRAM + 1[0111 ,0000 ]
當(dāng)余數(shù)為4 則 RAM = SRAM + 1[0000 ,1110 ]
當(dāng)余數(shù)為5 則 RAM1 = SRAM + 1[0000 ,0001 ]
RAM2 = SRAM + 2[1100 ,0000 ]
當(dāng)余數(shù)為6 則 RAM = SRAM + 2[0011 ,1000 ]
當(dāng)余數(shù)為7 則 RAM = SRAM + 2[0000 ,0111 ]
其中[ ]內(nèi)為“1”的位表示應(yīng)該填充顏色的位置, SRAM 表示該點(diǎn)對(duì)應(yīng)的基礎(chǔ)地址, RAM、RAM1 和RAM2 表示該點(diǎn)對(duì)應(yīng)的實(shí)際內(nèi)存地址。
當(dāng)數(shù)據(jù)位為“1”時(shí),對(duì)應(yīng)色點(diǎn)為亮;為“0”時(shí),對(duì)應(yīng)色點(diǎn)為暗。通過(guò)RGB 三原色組合而得到的8 種顏色代碼如下:
例1 :若X 、Y 坐標(biāo)為(7 ,0)
SRAM = 0EFH ×100H + 0 = 0EF00H
余數(shù)為7 ,則 RAM = 0EF00H + 2 = 0EF02H
若此點(diǎn)為紅色,則送入0EF02H 內(nèi)存單元里的數(shù)據(jù)為[ 0EF02H] &11111000B + 00000100B
例2 :若X 、Y 坐標(biāo)為(15 ,5)
SRAM = (5 - 1) ×100H + 1 ×3 = 403H
余數(shù)為5 ,則 RAM1 = 403H + 1 = 404H
RAM2 = 403H + 2 = 405H
若此點(diǎn)為白色,則送入這兩個(gè)單元的數(shù)據(jù)為
[ 404H] &11111110B + 00000001B
[ 405H] &00111111B + 11000000B
4. 2. 2 畫(huà)點(diǎn)函數(shù)的具體實(shí)現(xiàn)
從例1 和例2 可以看出,要只顯示一個(gè)色點(diǎn),就必須知道該點(diǎn)對(duì)應(yīng)的內(nèi)存中的數(shù)據(jù),而前面提到過(guò)內(nèi)存中的數(shù)據(jù)是不能讀出的,所以要將寫(xiě)入內(nèi)存中的數(shù)據(jù)先保存起來(lái),即在向YD2502 的顯示緩沖區(qū)里寫(xiě)數(shù)據(jù)之前, 應(yīng)先將此數(shù)據(jù)寫(xiě)入61LV5128 。若在坐標(biāo)( X , Y) 處畫(huà)顏色為color 的點(diǎn),其具體函數(shù)如下:
void LCD_ disppixel ( unsigned int X , unsigned int Y ,unsigned char color) {
unsigned int address ;
unsigned char data ;
address = LCD_pixeladdr ( X , Y) ;
/ / 計(jì)算該點(diǎn)對(duì)應(yīng)的內(nèi)存地址
switch ( X %8) {
case 0 : data = read _ exram ( ad2
dress) ; / / 讀取相應(yīng)SRAM 中的數(shù)據(jù)
data & = 0x1F; / / [1110 ,
0000]保存其他點(diǎn)的數(shù)據(jù)
data | = (color < < 5) ;
/ / 填充相應(yīng)的顏色
write _ exram ( data , ad2
dress) ; / / 把修改好的數(shù)據(jù)寫(xiě)回到SRAM
LCD_filldata (address ,da2
ta) ; / / 把數(shù)據(jù)寫(xiě)到液晶顯示緩沖區(qū)
break ;
……
case 7 : …; break ;}}
以上只給出了余數(shù)是0 的情況,其他的情況可依此類(lèi)推。計(jì)算內(nèi)存地址的LCD_pixeladdr 函數(shù)可根據(jù)給出的內(nèi)存地址計(jì)算方法編寫(xiě),讀寫(xiě)61LV5128 的read_exram 函數(shù)和write_exram 函數(shù)可根據(jù)具體的硬件設(shè)計(jì)編寫(xiě),這里不再給出。
4. 3 顯示漢字和其他功能的實(shí)現(xiàn)
在屏幕上顯示16 ×16 點(diǎn)陣漢字的基本步驟是:首先取得該漢字的32 個(gè)字節(jié)的點(diǎn)陣數(shù)據(jù),再確定屏幕上顯示的位置,利用畫(huà)點(diǎn)函數(shù)即可顯示該漢字。因本模塊使用了硬件漢字庫(kù)技術(shù),所以漢字的點(diǎn)陣數(shù)據(jù)是從漢字庫(kù)中獲取的。
在計(jì)算機(jī)漢字系統(tǒng)中,漢字是用機(jī)內(nèi)碼的形式存儲(chǔ)的,將漢字機(jī)內(nèi)碼減去0A0A0H 就得到該漢字的區(qū)位碼,通過(guò)區(qū)位碼就可以找到該漢字點(diǎn)陣數(shù)據(jù)在漢字庫(kù)中的位置。例如:漢字“中”的機(jī)內(nèi)碼是十六進(jìn)制的“D6D0”,其中前兩位“D6”表示機(jī)內(nèi)碼的區(qū)碼,后兩位“D0”表示機(jī)內(nèi)碼的位碼。所以“中”的區(qū)位碼為0D6D0H - 0A0A0H =3630H ,將區(qū)碼和位碼分別轉(zhuǎn)換為十進(jìn)制,得漢字“中”的區(qū)位碼為“5448”。即“中”的點(diǎn)陣位于第54區(qū)的第48 個(gè)字的位置,在文件HZK16 中的位置為第32 ×[(54 - 1)×94 + (48 - 1)] = 160928D以后的32 個(gè)字節(jié)為“中”的點(diǎn)陣數(shù)據(jù),用SUPER2PRO25 編程器讀入文件HZK16 后利用其編輯功能中的緩沖區(qū)編輯查找到274A0H (160928D 的十六進(jìn)制表示) 開(kāi)始的32 個(gè)字節(jié): 01H , 00H ,01H , 00H , 01H , 04H , 7FH , FEH , 41H , 04H ,41H , 04H , 41H , 04H , 41H , 04H , 7FH , FCH ,41H , 04H , 01H , 00H , 01H , 00H , 01H , 00H ,01H ,00H ,01H ,00H ,01H ,00H。這些數(shù)據(jù)與其點(diǎn)陣圖形的對(duì)應(yīng)關(guān)系如圖4 所示,圖中黑色方格表示二進(jìn)制位“1”,即對(duì)應(yīng)該顯示的點(diǎn),白色方格表示二進(jìn)制位“0”,即不該顯示的點(diǎn)。因此要在液晶屏幕上顯示16 ×16 點(diǎn)陣的漢字,首先應(yīng)找到該漢字在硬件漢字庫(kù)中的位置,取出其后的32 個(gè)字節(jié)數(shù)據(jù)。取這32 個(gè)字節(jié)數(shù)據(jù)的函數(shù)如下:
圖4 漢字“中”的點(diǎn)陣圖形
unsigned char chinese[ ] [ 2 ] = {“中”“, 國(guó)”} ;
unsigned char buffer [32 ] ;
void LCD_ readdata ( unsigned char num2
ber) {
unsigned char temp1 ,temp2 , k ;
unsigned long address , i ;
temp1 = chinese [ number ] [ 0 ] - 0xA0 ;/ / 把機(jī)內(nèi)碼轉(zhuǎn)換成區(qū)位碼
temp2 = chinese [ number ] [ 1 ] - 0xA0 ;
address = 32 3 ( ( (long) temp1 - 1) 3 94 +( (long) temp2 - 1) ) ; / / 計(jì)算該漢字在漢字庫(kù)中的首地址
k = 0 ;
for ( i = address ; i < address + 32 ; i + + ) {
data = read_exrom( i) ;
buffer [ k ] = data ;
k + + ; }}
讀A T29C040A 的read_exrom 函數(shù)可根據(jù)硬件設(shè)計(jì)編寫(xiě),這里不再給出。
取得這32 個(gè)字節(jié)數(shù)據(jù)后,下面的程序設(shè)計(jì)就比較容易了,這里只給出程序流程(如圖5 所示) ,具體函數(shù)可根據(jù)此流程編寫(xiě)。其中( X , Y) 是該漢字顯示的起始點(diǎn), color 是該漢字的顯示顏色,number 是該漢字在chinese 數(shù)組中的位置。顯示英文和數(shù)字的函數(shù)可根據(jù)顯示漢字的函數(shù)稍加改造后即可得到,這里不再詳細(xì)分析。
圖5 顯示一個(gè)漢字程序流程圖
在本模塊中也實(shí)現(xiàn)了在屏幕上畫(huà)斜線(xiàn)、圓等功能,其具體實(shí)現(xiàn)過(guò)程就是在畫(huà)點(diǎn)函數(shù)的基礎(chǔ)上通過(guò)相應(yīng)的算法來(lái)編寫(xiě)這些函數(shù)。畫(huà)線(xiàn)和畫(huà)圓算法比較多,在這里畫(huà)線(xiàn)算法采用的是整數(shù)數(shù)字微分分析法,畫(huà)圓算法采用的是貝森海姆算法。
鑒于篇幅所限,這里不再具體分析。由于YD2502是點(diǎn)陣式液晶顯示器, 還可以通過(guò)移植嵌入式GUI(如μC/ GUI) 軟件,使其顯示多種曲線(xiàn),各種窗口對(duì)象,如按鈕、編輯框、滑動(dòng)條等更加豐富靈活的圖形界面。
5 結(jié)語(yǔ)
以上程序均在ICCAVR 編譯器里調(diào)試通過(guò),實(shí)現(xiàn)了在液晶屏幕上正常顯示各種顏色的漢字、英文、數(shù)字及簡(jiǎn)單的圖形功能。在筆者參與開(kāi)發(fā)的油田探測(cè)爆炸機(jī)設(shè)備中,采用了本液晶模塊,達(dá)到了顯示穩(wěn)定,顯示色彩豐富,人機(jī)界面友好的較理想的顯示效果。