LCD驅(qū)動(dòng)的移植及其GUI仿真如何進(jìn)行,LCD數(shù)模轉(zhuǎn)換現(xiàn)實(shí)原理及其源代碼
LCD字模顯示程序如何設(shè)計(jì)?
系統(tǒng)中顯示部分的子程序與字模數(shù)據(jù)結(jié)構(gòu)互相關(guān)聯(lián),這里將ASCII字符顯示子程序和單獨(dú)顯示漢字字模的子程序列出來(lái),根據(jù)這兩個(gè)子程序也可以看出顯示部分的顯示程序?qū)崿F(xiàn)原理。
本文引用地址:http://www.ex-cimer.com/article/201710/367419.htm在這個(gè)子程序中,x指的是漢字行,只能是0~3共4行;y指的是半角字符列,只能是0~15共16列,因而可以在屏幕任何一個(gè)半角字符位置上顯示一個(gè)ASCII半角字符。在處理漢字時(shí)是將漢字當(dāng)作兩個(gè)半角字符來(lái)處理的,顯示時(shí)將一個(gè)漢字分左上、左下、右上、右下4個(gè)部分順序顯示出來(lái),從下面的顯示漢字字模子程序中可以看出這一點(diǎn)。
從程序中可以看出,當(dāng)j=0時(shí)寫(xiě)的是第工個(gè)漢字的左上和左下,然后在j的循環(huán)過(guò)程中依次顯示的是第一個(gè)漢字的右上、右下,第二個(gè)漢字的左上、左下,第二個(gè)漢字的右上、右下。實(shí)際上LCD的起始頁(yè),表示起始顯示的8行,也就是表示一個(gè)半角字符的上半部分。這就是顯示部分漢字的顯示過(guò)程。
S3C2410 LCD 驅(qū)動(dòng)程序移植及GUI程序編寫(xiě):
1. 為了不讓大家覺(jué)枯燥,讓朋友們更好的理解,我以一個(gè)實(shí)例來(lái)敘述 S3C2410 下一個(gè)驅(qū)動(dòng)程序的編寫(xiě)(本文的初始化源碼以華恒公司提供的 s3c2410fb.c 為基礎(chǔ))及簡(jiǎn)單的 GUI程序的編寫(xiě)。
2. 拿到一塊 LCD,首先要將 LCD的各個(gè)控制線與 S3C2410 的 LCD控制信號(hào)相接,當(dāng)然,電源也一定要接入了,否則不亮可別找我。另外需要注意以下幾點(diǎn):
1) 背光:對(duì)于大部分的彩色 LCD一定要接背光,我們才能看到屏上的內(nèi)容;
2) 控制信號(hào):不同的 LCD 廠商對(duì)于控制信號(hào)有不同的叫法,S3C2410 芯片手冊(cè)也給出了一個(gè)信號(hào)的多個(gè)名稱(chēng)(圖一),這就要看你們硬件工程師的功底了,
圖一 S3C2410 手冊(cè)上給出的控制信號(hào)的名稱(chēng)及解釋
這里我做一個(gè)簡(jiǎn)單的介紹:
VFRAME:LCD 控制器和 LCD 驅(qū)動(dòng)器之間的幀同步信號(hào)。該信號(hào)告訴 LCD屏的新的一幀開(kāi)始了。LCD 控制器在一個(gè)完整幀顯示完成后立即插入一個(gè)VFRAME 信號(hào),開(kāi)始新一幀的顯示;
VLINE:LCD控制器和 LCD驅(qū)動(dòng)器之間的線同步脈沖信號(hào),該信號(hào)用于 LCD驅(qū)動(dòng)器將水平線(行)移位寄存器的內(nèi)容傳送給 LCD 屏顯示。LCD 控制器在整個(gè)水平線(整行)數(shù)據(jù)移入 LCD驅(qū)動(dòng)器后,插入一個(gè) VLINE 信號(hào);
VCLK:LCD控制器和 LCD驅(qū)動(dòng)器之間的像素時(shí)鐘信號(hào),由 LCD控制器送出的數(shù)據(jù)在 VCLK的上升沿處送出,在 VCLK的下降沿處被 LCD驅(qū)動(dòng)器采樣;
VM:LCD驅(qū)動(dòng)器的 AC 信號(hào)。VM 信號(hào)被 LCD驅(qū)動(dòng)器用于改變行和列的電壓極性,從而控制像素點(diǎn)的顯示或熄滅。VM 信號(hào)可以與每個(gè)幀同步,也可以與可變數(shù)量的 VLINE 信號(hào)同步。
3) 數(shù)據(jù)線:也就是我們說(shuō)的 RGB 信號(hào)線,S3C2410 芯片手冊(cè)上都有詳細(xì)的說(shuō)明,由于篇幅關(guān)系,在此不一一摘錄,不過(guò)需要與硬件工程是配合的是他采用了哪種接線方法,24 位 16 位或其它。對(duì)于 16 位 TFT 屏又有兩種方式,在寫(xiě)驅(qū)動(dòng)前你要清楚是 5:6:5還是 5:5:5:I,這些與驅(qū)動(dòng)的編寫(xiě)都有關(guān)系
4) 要注意一下 LCD 的電源電壓,對(duì)于手持設(shè)備來(lái)說(shuō)一般都為 5V 或 3.3V,或同時(shí)支持 5V和 3.3V,如果 LCD的需要的電源電壓是 5V,那就要注意了,S3C2410 的邏輯輸出電壓只有 3.3V,此時(shí)一定要讓你們的硬件工程師幫忙把 S3C2410 的邏輯輸出電壓提高到 5V,否則你可能能將屏點(diǎn)亮,但顯示的圖像要等到太陽(yáng)從西邊出來(lái)的那一天才能正常,呵呵,我可吃過(guò)苦頭的哦!
5) 3.3V邏輯電壓轉(zhuǎn)變成 5V邏輯電壓電路圖
6) 最后還有一個(gè)問(wèn)題,有些 LCD 屏還需要一顆伴侶芯片,就是 S3C2410 手冊(cè)中的那顆 LPC3600。這可能在 LCD 的手冊(cè)中都有論述吧,我沒(méi)有遇到過(guò)這樣的屏,所以也不是很清楚。那么是不是所有的屏與 S3C2410相接都需要那個(gè)討厭的家伙呢?這是好多人(包括我)在最開(kāi)始都會(huì)有的疑問(wèn),不過(guò)現(xiàn)在的大部分 LCD 屏應(yīng)該都不需要這個(gè)討厭的家伙了,屏的控制信號(hào)直接與 S3C2410 的控制信號(hào)相接就可以了,至少我還沒(méi)有遇到過(guò)。
7) 還得提醒大家一下,S3C2410到 LCD屏的連線千萬(wàn)千萬(wàn)別超過(guò) 0.5 米,否則會(huì)給你帶來(lái)麻煩,我也是吃過(guò)苦頭的,LCD屏上面的部分顯示任何信息都是正確的,而只有屏的底部會(huì)有時(shí)正確有時(shí)錯(cuò)誤,折騰了好一陣,才知道是連線太長(zhǎng)的緣故!
3. 好了,在硬件工程師的幫助下,硬件接好了,那就該我們做軟件的干活了,編寫(xiě)驅(qū)動(dòng)吧
1) 讓我們首先看一下 RGB數(shù)據(jù)結(jié)構(gòu)的定義
在 s3c2410fb.c 中找到如下信息
staTIc struct s3c2410fb_rgb xxx_tft_rgb_16 = {
red: {offset:11, length:5,},
green: {offset:5, length:6,},
blue: {offset:0, length:5,},
transp: {offset:0, length:0,},
};
這是對(duì) 16 位色的 RGB 顏色進(jìn)行定義,R:G:B:I = 5:6:5:0,即我們常說(shuō)的565 顯示方式。呵呵,為了讓有些朋友更好的理解,我多羅嗦幾句,我們隨便寫(xiě)一個(gè) 16 位數(shù)據(jù)的顏色數(shù)據(jù)(為了分析的方便,我把它寫(xiě)成二進(jìn)制)
RGB = 10101101 10111001
根據(jù)上面的結(jié)構(gòu)定義我們來(lái)分析一下 RGB 各是多少(因?yàn)闆](méi)有透明色,我們不去分析)
a) blue: {offset: 0, length: 5} 偏移量為 0,長(zhǎng)度為 5,我們從那個(gè) RGB 中提取出來(lái)便是“11001”
b) green:{offset: 5, length: 6} 偏移量為 5,長(zhǎng)度為 6,我們從那個(gè) RGB 中提取出來(lái)便是 101 101
c) red: {offset: 11, length: 5 } 偏移量為 11,長(zhǎng)度為 5,我們從那個(gè) RGB 中提取出來(lái)便是 10101
d) 我們得到了一個(gè) RGB 值為 13:45:200,就是這個(gè)顏色
e) 那么反過(guò)來(lái),有了 RGB的值我們?cè)撊绾危驗(yàn)?RGB 的有效位數(shù)都不足一個(gè)字節(jié)(8 位),那我們只能忍痛割?lèi)?ài)了,舍棄掉低位數(shù)據(jù),代碼如下
r=(rDat0xF8);
g=(gDat0xFC);
b=(bDat0xF8);
hight=r|(g《《5);
low=(g》》3)|(b《《3);
color=(hight》》8)|low;
記住,這段代碼在 GUI 程序中是有用的
2) 對(duì)于 8 位色(256 色)的數(shù)據(jù)結(jié)構(gòu)定義
staTIc struct s3c2410fb_rgb rgb_8 = {
red: {offset:0, length:4,},
green: {offset:0, length:4,},
blue: {offset:0, length:4,},
transp: {offset:0, length:0,},
};
這是原程序中給出的定義,我感覺(jué)有些錯(cuò)誤,我認(rèn)為應(yīng)該為 R:G:B = 3:3:2
staTIc struct s3c2410fb_rgb rgb_8 = {
red: {offset:5, length:3,},
green: {offset:2, length:3,},
blue: {offset:0, length:2,},
transp: {offset:0, length:0,},
};
因?yàn)闆](méi)有親自去調(diào)試,所以沒(méi)有什么發(fā)言權(quán),希望做過(guò)這方面的朋友給我一個(gè)答案。
3) 對(duì)于 CSTN 屏,一般都能達(dá)到 12 位色(4096 色)的,S3C2410 這顆芯片也是支持的,但是在軟件方面要做的工作比較大,因?yàn)閺脑械拇a,我們找不到任何 12位色顯示的跡象,另外 Linux 本身好像也不支持 12 位色的,如果你要作的事情比較簡(jiǎn)單,那你就自己寫(xiě)代碼吧。我在此給出 12位色的數(shù)據(jù)結(jié)構(gòu)定義
staTIc struct s3c2410fb_rgb xxx_stn_rgb_12 = {
red: {offset:8, length:4,},
green: {offset:4, length:4,},
blue: {offset:0, length:4,},
transp: {offset:0, length:0,},
};
但是要完成 12 位色 CSTN 屏驅(qū)動(dòng)程序的編寫(xiě)還有一些工作要做,稍后我會(huì)適當(dāng)?shù)南虼蠹医榻B。
4) 接著看下面的代碼,其中要修改的部分已經(jīng)用綠色標(biāo)出,下面分別進(jìn)行介紹。
a) 顏色位數(shù)
bpp:16
如果你的 LCD 屏是 TFT 的,那一般都可以達(dá)到 16 位色或 24 位色,這也要看硬件怎么連接了,根據(jù)情況進(jìn)行設(shè)置即可;
如 果你的 LCD屏是 CSTN的,按照常規(guī) LCD手冊(cè)的介紹,一般都可以支持到8 位色(256色),而實(shí)際的 CSTN屏的顯示效果都可以達(dá)到 12 位色(4096色),那可有很大的區(qū)別的,如果你要選擇便宜的屏又要豐富的顏色,那就費(fèi)點(diǎn)勁,完成 12 位色的驅(qū)動(dòng)。
b) LCD屏的寬度和高度
xres: 240
yres: 320
這個(gè)就不用多說(shuō)了,你的屏的分辨率是多少就設(shè)置成多少唄。
c) 寄存器的設(shè)置,這些也不困難。下面就讓我們一起一口一口的將 S3C2410 的LCD寄存器統(tǒng)統(tǒng)吃掉! 首先介紹一下我這塊屏,這是日立的一塊 TFT 屏,大小為 640X240,可以支持到 16位色。 與驅(qū)動(dòng)有關(guān)的一張表
圖二 LCD屏資料
有了這些信息,讓我們看一下 LCD寄存器的設(shè)置。
LCD控制器1
LINECNT --- 這是一個(gè)只讀的數(shù)據(jù),我們當(dāng)然沒(méi)有必要理它
CLKVAL --- 這可是一個(gè)很有用的參數(shù),其實(shí)沒(méi)必要管它后面的計(jì)算,我們可以通過(guò)實(shí)際的測(cè)試來(lái)得出一個(gè)有效的值,對(duì)于320x240 的屏一般設(shè)置為 7 就可以了,而對(duì)于 640x480 的屏,該值可以小一點(diǎn)。對(duì)于后面的計(jì)算公式及注釋?zhuān)⊿TN: CLKVAL 《= 2,TFT: CLKVAL 《= 0),我不知道該如何去理解,因?yàn)樵趯?shí)際的應(yīng)用中我點(diǎn)了一塊 640X240 的CSTN 屏,當(dāng)我的 CLKVAL = 1 時(shí)才達(dá)到了一個(gè)最佳的效果,這似乎與說(shuō)明書(shū)相違背,我也解釋不清為什么?!
PNRMODE --- 這個(gè)應(yīng)該不用多做解釋?zhuān)蠹乙豢炊济靼琢?,?duì)于 TFT 屏,只能設(shè)置成 11,而對(duì)于 CSTN 屏,可能需要根據(jù)實(shí)際屏的信息去設(shè)置,我遇到的屏都設(shè)置成 10,即 8bit 單掃描模式。對(duì)于4bit單掃描、4bit 雙掃描、8bit 單掃描的說(shuō)明在 s3c2410 的手冊(cè)中有詳細(xì)的介紹,大家可以去參考一下。
BPPMODE --- 這個(gè)參數(shù)更不用多說(shuō)了吧,就是設(shè)置屏的顏色位數(shù)嘍。
這些參數(shù)的設(shè)置都很簡(jiǎn)單,我給出我這塊屏的定義:
lcdcon1: LCD1_BPP_16T | LCD1_PNR_TFT | LCD1_CLKVAL(1),
同時(shí),我也給出一塊 CSTN 屏的寄存器參數(shù)信息
lcdcon1: LCD1_BPP_12S | LCD1_PNR_8S | LCD1_CLKVAL(9),
LCD控制器2
對(duì)于 TFT 屏必須要填,至于什么意思怎么翻譯,相信大家都比我的水平強(qiáng),自己翻譯吧。我只說(shuō)明從 LCD中如何將這個(gè)值“扣”出來(lái)。
很容易,看一下圖二 LCD屏資料,對(duì)比一下得出如下信息:
LCD2_VBPD:
Vertical back porch 典型值為 7
LCD2_VFPD:
Vertical front porch 典型值為 4
LCD2_VSPW:
Vsync Valid width 典型值為 2
關(guān)于 LINEVAL 在程序的后面將會(huì)提到,此處不必理會(huì)。
經(jīng)過(guò)分析,我們知道了如何設(shè)置 LCD2:
lcdcon2: LCD2_VBPD(7) | LCD2_VFPD(4) | LCD2_VSPW(2),
對(duì)于 STN(CSTN)屏,這個(gè)寄存器的設(shè)置最簡(jiǎn)單,將 VBPD、VFPD、VSPW 都設(shè)置成 Zero 就可以了。即
lcdcon2: LCD2_VBPD(0) | LCD2_VFPD(0) | LCD2_VSPW(0),
LCD控制器3
對(duì)于 TFT 屏,很容易將 HBPD 和 HFPD 找出來(lái),如下
LCD3_HBPD:
Horizontal back porch 典型值為 37
LCD3_HFBD:
Horizontal back porch 典型值為 32
對(duì)于 HOZVAL 同樣會(huì)在后面提到,此處暫時(shí)不管
經(jīng)過(guò)分析,我們知道了如何設(shè)置 LCD3:
lcdcon3: LCD3_HBPD(37) | LCD3_HFPD(32) ,
對(duì)于(STN)CSTN屏,我沒(méi)有很好的理解 WDLY 和 LINEBLANK 的真正涵義,通過(guò)改變這兩個(gè)參數(shù)的值,我也沒(méi)有得到特別明顯的差異,我一般設(shè)置為:
lcdcon3: LCD3_WDLY_16 | 0x10 ,
LCD控制器4
對(duì)于 TFT 屏,需要設(shè)置 HSPW 的值,這個(gè)在 LCD 手冊(cè)上也很容易得到
LCD4_HSPW:
Hsync Valid width 典型值為 5
至于 MVAL,我不知道是什么意思,有什么作用,我從來(lái)不動(dòng)它,只取它最初的那個(gè)值 13
經(jīng)過(guò)分析,我們知道了如何設(shè)置 LCD4:
lcdcon4: LCD4_HSPW(5) | LCD4_MVAL(13) ,
對(duì)于 STN(CSTN)屏,像 WDLY 一樣,我通常不改變,因?yàn)楦淖兞藳](méi)有發(fā)現(xiàn)有什么作用,這是我驅(qū)動(dòng)中的代碼,好幾塊屏都一樣的:
lcdcon4: LCD4_WLH(0) | LCD4_MVAL(13) ,
LCD控制器5
這個(gè)寄存器的看起來(lái)比較復(fù)雜,但是無(wú)外乎這幾類(lèi):
只讀信息:VSTATUS和 HSTATUS
只讀的東東,設(shè)置它也沒(méi)用,不必理會(huì)。
TFT 屏的顏色信息:BPP24BL、FRM565
TFT 屏的顏色信息,這個(gè)我們?cè)?LCD的硬件連接時(shí)已經(jīng)提到了,根據(jù)具體的接線方式,設(shè)置信息。
控制信號(hào)的極性
TFT/STN 屏控制信號(hào)的極性:INVVCLK、INVVLINE、INVVFRAME、INVVD、INVPWREN、PWREN
TFT 屏特有的控制信號(hào)的極性:INVVDEN、INVLEND、ENLEND
這些信息主要是使S3C2410的信號(hào)輸出極性與LCD屏的輸入極性的問(wèn)題,需要根據(jù)具體的硬件進(jìn)行設(shè)置,較為常見(jiàn)的是vline/hsync 、VFRAME/VSYNC脈沖的極性。
顏色信息的字節(jié)交換控制位:BSWP、HWSWP
這兩位用來(lái)控制字節(jié)交換和半字交換,主要用來(lái)大小頭的問(wèn)題,如果輸出到屏上的漢字左右互換了,或者輸出到屏上的圖花屏了,可以更改這個(gè)選項(xiàng)。具體涵義在 S3C2410芯片手冊(cè)上有詳細(xì)的說(shuō)明。
我的這塊 TFT 的信息設(shè)置如下:
lcdcon5: LCD5_FRM565 | LCD5_HWSWP | LCD5_PWREN ,
一塊 CSTN屏的信息
lcdcon5: LCD5_BSWP | LCD5_PWREN ,
FrameBuffer 起始寄存器 1
這個(gè)寄存器的設(shè)置沒(méi)有必要去修改(TFT/STN),都使用默認(rèn)的代碼即可:
FrameBuffer 起始寄存器 2 和 FrameBuffer 起始寄存器 3
這兩個(gè)寄存器的設(shè)置比較重要,在此我給出 12 位色 CSTN 屏和 16 位色TFT 的設(shè)置代碼:
前面提到的 LINEVAL 和 HOZVAL 以源碼的形式給出,其中 CSTN 8 位色沒(méi)有經(jīng)過(guò)測(cè)試。
RGB Loopup Table Register
這三個(gè)寄存器的在驅(qū)動(dòng) 256 色 CSTN 屏的時(shí)候需要使用,我在別的芯片上使用過(guò),因?yàn)檫@顆芯片支持 12 位色,所以沒(méi)有去調(diào)試,我給
出兩組可能的值:
S3C44B0 上的
rREDLUT = 0xFCA86420;
rGREENLUT = 0xFCA86420;
rBLUELUT = 0xFFFFFA50;
Jupiter 上的
rREDLUT = 0xFEC85310
rGREENLUT = 0xFEC85310
rBLUELUT = 0xFB40
5) 好了,各個(gè)寄存器的設(shè)置完成了,最后在驅(qū)動(dòng) CSTN屏的時(shí)候需要提醒大家一句,CSTN的信號(hào)引腳中有一個(gè)叫VM/DISP的信號(hào)線,這個(gè)信號(hào)線的作用就是打開(kāi)LCD的顯示開(kāi)關(guān),讓其進(jìn)行顯示,它 可以接到任何一個(gè) GPIO 口上。S3C2410 中提供了一個(gè) VM 信號(hào),可以將 LCD的這個(gè)信號(hào)與 S3C2410 的 VM 信號(hào)相接即可,然后在驅(qū)動(dòng)中一定要加上如下語(yǔ)句(藍(lán)色選中部分):
否則你的 LCD可能沒(méi)有任何顯示哦(對(duì)于 TFT 屏不需要這個(gè)語(yǔ)句)
6) 關(guān)于 12 位色的 CSTN屏的驅(qū)動(dòng)還需要做一些工作,我在這里簡(jiǎn)單介紹一下:
a) 首先要完成一個(gè) fbcon-cfb12.c和 fbcon-cfb12.h 的編寫(xiě),這兩個(gè)文件很簡(jiǎn)單,在armLinux 中不是提供了 fbcon-cfb16.c 和 fbcon-cfb12.h 嗎?簡(jiǎn)單修改一下就可以了;
b) 將 fbcon-cfb12.c 的編譯加入 Config.in 中(不會(huì)的話去 google 搜一下,或者看一下我的另一篇文章《JFFS2 在 HHARM2410 上的實(shí)現(xiàn)》,里邊有一些說(shuō)明),并定義一個(gè) FBCON_HAS_CFB12 參數(shù)(模仿 FBCON_HAS_CFB16 唄);
c) 另外,需要在 s3c2410fb.c 中的相應(yīng)部分加上對(duì) 12位色的支持即可。呵,說(shuō)起來(lái)簡(jiǎn)單,但實(shí)際做起來(lái)可能會(huì)有一些問(wèn)題,給大家一個(gè)竅門(mén):在程序中找到#ifdef FBCON_HAS_CFB16 之類(lèi)的代碼,簡(jiǎn)單理解一下加上對(duì) 12 位色的支持;
d) 我只給出函數(shù) s3c2410fb_set_var中的改動(dòng),其他的應(yīng)該都不是很困難,相信朋友們都能搞定。
e) 不要跟我要源碼哦,否則老板會(huì)不高興哦 。
4. 驅(qū)動(dòng)寫(xiě)好了,重新 Make,下載就可以了。如果一切順利,在 TFT 屏或 256 色的 CSTN屏上會(huì)有一個(gè)漂亮的小蜻蜓(應(yīng)該是蜻蜓吧)出現(xiàn)。注意,并不是蜻蜓出現(xiàn)了就代表你的驅(qū)動(dòng) OK了,還要用 GUI 程序做進(jìn)一步的測(cè)試,因?yàn)槟骋粋€(gè)或幾個(gè)參數(shù)雖然不正確,但是仍然能夠看到小蜻蜓的,但顯示圖形的時(shí)候就有問(wèn)題了。另外,在驅(qū)動(dòng) CSTN到 12位色的時(shí)候,我們?cè)谄辽峡床坏叫◎唑眩ㄎ业?N塊 CSTN屏上都沒(méi)見(jiàn)到小蜻蜓),我想,可能是 armLinux 本身不支持 12 位色顯示,或者我們某些地方?jīng)]搞對(duì)的原因吧,但這不代表你的驅(qū)動(dòng)有問(wèn)題,用 GUI 程序?qū)?FrameBuffer,看看能否的到正確的結(jié)果。
5. GUI 程序的編寫(xiě)
FrameBuffer 驅(qū)動(dòng)寫(xiě)好了,那么怎么去使用,怎么在 LCD 上顯示圖像呢?這就是 GUI程序的任務(wù)了,其實(shí)要在 LCD 上顯示圖像,說(shuō)白了就是把數(shù)據(jù)(包含顏色)寫(xiě)到FrameBuffer 中對(duì)應(yīng)的位置就可以了。如果你使用如 Microwinow、MiniGui、Qt 之類(lèi)的GUI,則沒(méi)有必要關(guān)心 FrameBuffer與 LCD屏上的點(diǎn)如何進(jìn)行映射了,但如果你在使用了 CSTN 屏,并且要顯示效果好的照片,選擇了 CSTN 的 12 位色(4096色 ),那你就要自己寫(xiě) GUI 程序了,因?yàn)楹孟?armLinux(Linux)本身都不支持 12 位色的,聽(tīng)說(shuō) MiniGui支持 12 位色,但我在工作中的要求只是顯示圖形而已,沒(méi)有去深入研究 MiniGui,所以自己寫(xiě)了。
另外請(qǐng)朋友們見(jiàn)諒的是我不能給出全部的源代碼,因?yàn)槲耶吘故芄陀谌?,有些東東是可以 GPL 的,而有些東東暫時(shí)是不可以 GPL 的。
下面給出我的程序的部分代碼,希望對(duì)朋友們有所幫助。
1) 全局變量的定義:
定義幾個(gè)全局變量,用起來(lái)方便。
2) 初始化圖形顯示引擎,將 fb0與 GUI 的 buffer做個(gè)映射
用mmap函數(shù)使用戶(hù)空間的一段地址關(guān)聯(lián)到設(shè)備內(nèi)存(FrameBuffer)上。無(wú)論何時(shí),只要程序在分配的地址范圍內(nèi)進(jìn)行讀取或者寫(xiě)入,實(shí)際上就是對(duì) 設(shè)備的訪問(wèn),使用 mmap 可以既快速又簡(jiǎn)單地訪問(wèn)顯示卡的內(nèi)存。對(duì)于象這樣的性能要求比較嚴(yán)格的應(yīng)用來(lái)說(shuō),直接訪問(wèn)能給我們提供很大不同。 不過(guò)我曾將幫一個(gè)網(wǎng)友調(diào)試了一個(gè) S3C44B0 上的 GUI 程序,在他的 GUI 中 mmap 函數(shù)總會(huì)出錯(cuò),因?yàn)闆](méi)有拿到他的硬件和驅(qū)動(dòng)源碼,沒(méi)有分析出其中的原因,所以只得用 write函數(shù),直接向 fb0 寫(xiě)入數(shù)據(jù),奇怪的是只寫(xiě)入一部分?jǐn)?shù)據(jù)好像都不起任何作用,只得整屏數(shù)據(jù)寫(xiě)入才搞定了。這可就比較痛苦了,不過(guò)好在他只是寫(xiě)入的黑白數(shù)據(jù),數(shù)據(jù)量還不是很 大,要是彩色的那可真的痛苦了 。
另外,我還想多啰嗦兩句,F(xiàn)rameBuffer的像素點(diǎn)與LCD屏上的像素點(diǎn)的對(duì)應(yīng)關(guān)系 ,深入了解一下對(duì)程序的理解可能會(huì)更清楚一點(diǎn)。我們知道黑白(2 色)顏色用 0 和 1 就可以表示了,也就是 1 位數(shù)據(jù)就可以了,那 1 個(gè)字節(jié)就可以表示 8 位數(shù)據(jù),假如這個(gè)字節(jié)是10101010,F(xiàn)rameBuffer 的偏移地址為 0,則在 LCD 屏上便會(huì)顯示出 4 個(gè)黑點(diǎn),黑點(diǎn)中間會(huì)有 4 個(gè)白點(diǎn)出現(xiàn)(假如 1 是黑色);對(duì)于 4 色則用 00、01、10、11 就可以表示出四種顏色,即用兩位數(shù)據(jù)可以表示一位數(shù)據(jù),那同樣是 10101010,則對(duì)應(yīng)于 LCD 屏上則顯示的
是顏色值為10,長(zhǎng)度為4(8/2)的一條直線;同理,對(duì)于8位色(256色),則8位數(shù)據(jù)才能表示出一個(gè)點(diǎn)的顏色值,10101010在LCD屏上就只能顯示為顏色值為10101010的點(diǎn)了。
有了上面的基礎(chǔ)我們就可以很好的理解這個(gè)語(yǔ)句了:
screensize = vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8;
即FrameBuffer 的大小=LCD屏的寬度 * LCD屏的高度 * 每像素的位數(shù) / 每字節(jié)的位數(shù)
例如,一個(gè)320*240的黑白平,F(xiàn)rameBuffer的大小為
320 * 240 * 1 / 8 = 9600 (字節(jié))
而一個(gè)320 * 240的16位色LCD的 FrameBuffer的大小則為
320 * 240 * 16 / 8 = 153600(字節(jié))
3) TFT 屏 16 位色的畫(huà)點(diǎn)函數(shù)
有了畫(huà)點(diǎn)函數(shù),你還愁什么?圖形漢字都可以搞定了吧!
4) CSTN屏 12位色的畫(huà)點(diǎn)函數(shù)
注意,為了更便于代碼書(shū)寫(xiě),我在這個(gè)函數(shù)中將 fbp 定義為 static char * fbp,而在TFT 屏 16 位色的畫(huà)點(diǎn)函數(shù)中 fbp 的定義為 U16 * fbp,你可以根據(jù)需要進(jìn)行修改。
5) TFT 屏 16 位色下顯示 24色位圖函數(shù)
Bmp文件的格式可以參考網(wǎng)上的一些資料,如果需要也可以直接找我要。
6) CSTN屏 12位色下顯示 24 色位圖函數(shù)
7) 呵呵,別忘了關(guān)閉設(shè)備哦
void closegraph()
{
munmap(fbp,screensize);
close(fb);
}
收獲:
1、LCD的電源電壓,對(duì)于手持設(shè)備來(lái)說(shuō)一般都為 5V 或 3.3V,或同時(shí)支持 5V和 3.3V,如果 LCD的需要的電源電壓是 5V,那就要注意了,S3C2410 的邏輯輸出電壓只有 3.3V,此時(shí)一定要讓你們的硬件工程師幫忙把 S3C2410 的邏輯輸出電壓提高到 5V,否則不能將屏點(diǎn)亮
2、S3C2410到 LCD屏的連線千萬(wàn)千萬(wàn)別超過(guò) 0.5 米,否則出現(xiàn)問(wèn)題。如LCD屏上面的部分顯示任何信息都是正確的,而只有屏的底部會(huì)有時(shí)正確有時(shí)錯(cuò)誤。
3、8位色的數(shù)據(jù)結(jié)構(gòu)定義:
static struct s3c2410fb_rgb rgb_8 = {
red: {offset:5, length:3,},
green: {offset:2, length:3,},
blue: {offset:0, length:2,},
transp: {offset:0, length:0,},
};
R:G:B = 3:3:2
4、CLKVAL的確定:
CLKVAL --- 這可是一個(gè)很有用的參數(shù),其實(shí)沒(méi)必要管它后面的計(jì)算,我們可以通過(guò)實(shí)際的測(cè)試來(lái)得出一個(gè)有效的值,對(duì)于320x240 的屏一般設(shè)置為 7 就可以了,而對(duì)于 640x480 的屏,該值可以小一點(diǎn)。
5、在設(shè)置LCDCON5時(shí),通過(guò) TFT/STN 屏控制信號(hào)的極性,使S3C2410的信號(hào)輸出極性轉(zhuǎn)換后與LCD屏的輸入極性相一致
評(píng)論