S3C2440的LCD編程
4. 幀緩沖(FrameBuffer):
幀緩沖是Linux為顯示設備提供的一個(gè)接口,它把一些顯示設備描述成一個(gè)緩沖區,允許應用程序通過(guò) FrameBuffer定義好的接口訪(fǎng)問(wèn)這些圖形設備,從而不用去關(guān)心具體的硬件細節。對于幀緩沖設備而言,只要在顯示緩沖區與顯示點(diǎn)對應的區域寫(xiě)入顏色 值,對應的顏色就會(huì )自動(dòng)的在屏幕上顯示。下面來(lái)看一下在不同色位模式下緩沖區與顯示點(diǎn)的對應關(guān)系:本文引用地址:http://dyxdggzs.com/article/201611/322380.htm
volatile static unsigned short LCD_BUFFER[240][320];
void Pixel(U32 x,U32 y, U16 c )
{
if ( (x < SCR_XSIZE_TFT_320240) && (y < SCR_YSIZE_TFT_320240) )
LCD_BUFFER[y][x] = c;
}
很容易發(fā)現TFT LCD上顯示單個(gè)像素的函數實(shí)際上很簡(jiǎn)潔,看來(lái)似乎只需要LCD_BUFFER[(y)][(x)] = c這一句話(huà).下面就來(lái)分析下,是如何通過(guò)這一句話(huà)來(lái)實(shí)現在LCD上顯示單個(gè)像素的,先分析下Lcd_Init()即LCD初始化函數:
#define rGPCCON
#define rGPCUP
#define rGPDCON
#define rGPDUP
#define rLCDCON1
#define rLCDCON2
#define rLCDCON3
#define rLCDCON4
#define rLCDCON5
#define rLCDSADDR1
#define rLCDSADDR2
#define rLCDSADDR3
#define rLCDINTMSK
#define rTPAL
void Lcd_Init(void)
{
}
程序分析至此,大概已經(jīng)清楚是如何通過(guò)LCD_BUFFER[(y)][(x)] = c來(lái)實(shí)現在LCD上顯示單個(gè)像素了。就是在設置好各個(gè)LCD寄存器之后,通過(guò)將LCD_BUFFER地址與LCDBANK以及LCDBASEU、 LCDBASEL對應之后,通過(guò)改變LCD_BUFFER里不同單元存儲的值(即像素的顏色),即可在LCD相應位置上做出顯示。
那么在應用不同LCD的時(shí)候,只需對LCDCONx以及LCDSADDRx做出相應的配置,再創(chuàng )建一個(gè)數組,做出上述的地址映射即可。
關(guān)于VCLK計算,由于配置的是TFT,可用到公式VCLK = HCLK / [(CLKVAL+1) * 2] ( CLKVAL>=0 ),設置的Fclk為400MHz,Hclk為100MHz(Fclk:Hclk=1:4),CLKVAL = 4,因此VLCK = 10MHz。
筆記:
首先說(shuō)一下我們平時(shí)所說(shuō)的多少位的LCD,有24位的,有16位的指的是LCD數據的位數,LCD的數據實(shí)際上是LCD要顯示的顏色,24位的是紅綠 藍各占8位,16位則是紅綠藍按照565分配的,其實(shí)24的也可以只接16位,每個(gè)顏色地位接地就可以,所以要給LCD的緩沖區一個(gè)數據才能在LCD上顯 示出來(lái)。那究竟是怎么顯示的呢,那就得先說(shuō)一下像素了,LCD的像素實(shí)際上就LCD屏幕有多少個(gè)點(diǎn),LCD顯示的東西都是一個(gè)一個(gè)點(diǎn)拼湊出來(lái)的,比如我用 的是320*240的LCD,就是說(shuō)LCD每一行有320個(gè)點(diǎn),而每一列有240個(gè)點(diǎn),所以總共有320*240個(gè)點(diǎn),我們讓適當的點(diǎn)顯示適當的顏色就達 到了我們的目的。
其實(shí)剛開(kāi)始困擾我們的是LCD的初始化的問(wèn)題,要設置的東西比較多,其實(shí)我們是記不住這些東西的,呵呵,作為入門(mén)我們可以參考別人的初始化程序,把里面的參數改成我們自己的LCD的參數就OK了。
那么我們到底是怎么把我們要顯示的數據送給LCD控制起的呢?是這樣的,我們可以定義一個(gè)二維數組,把我們要顯示的數據存到里面,然后把這個(gè)數組的地 址賦給LCD的相應的寄存器,這個(gè)寄存器是LCDSADDRn,具體的設置大家可以參考數據手冊,我們可以把二維數組的坐標和LCD的坐標對應起來(lái),那么 我們就可以隨意的讓哪一個(gè)像素點(diǎn)顯示什么顏色就顯示什么顏色了。這就把數據送出的過(guò)程,也就是顯示一個(gè)像素點(diǎn)的過(guò)程。
到現在我們已經(jīng)知道如何顯示一個(gè)像素了,那接下來(lái)就是LCD顯示最基本的東西了----字符和圖片。漢字和圖片的顯示都是基于像素點(diǎn)的顯示的,我們把 要顯示的字符和圖片轉化成相應的數據,然后傳遞給LCD即可。我們可以專(zhuān)門(mén)的寫(xiě)一個(gè)顯示字符的函數和一個(gè)顯示圖片的函數。顯示字符的數據可以用取模軟件生 成,因為生成的字符數據是表示的每一個(gè)點(diǎn)要不要亮,亮的地方用1表示,不亮的地方用0表示,所以如果用LCD顯示,我們還要告訴LCD顯示什么顏色,這才 是LCD需要的數據,比如說(shuō)16*16的數據,有16行16列,我們將一行的數據,也就是16位數據的每一位都取出來(lái),為1的地方,我們就給LCD一個(gè) 16位的數據,為0的地方就不給數據,這樣就能顯示了,取模生成的數據都是按行來(lái)的。圖片的顯示直接就將16位的數據傳遞給LCD,這個(gè)圖片數據的產(chǎn)生, 我們可以用軟件LCD彩色圖片轉換工具(BMP_to_H)生成C語(yǔ)言文件,我們只需對文件進(jìn)行簡(jiǎn)單的修改就能加入到我們的程序中,修改方法在軟件的說(shuō)明 中都有。
編程要點(diǎn):
1、打開(kāi)LCD背光
將LCD背光對應的GPIO設置為禁止上拉(GPxUP相應位寫(xiě)入1),選擇output類(lèi)型(GPxCON相應位寫(xiě)入01),輸出為高電平(GPxDAT相應位寫(xiě)入1)。
2、打開(kāi)LCD電源
可以將GPG4選擇為L(cháng)CD_PWREN(GPGCON:9-8寫(xiě)入11),這時(shí)候LCD電源的打開(kāi)/關(guān)閉可以通過(guò)LCDCON5:3來(lái)控制。也可以自定 義其他GPIO用作LCD電源開(kāi)關(guān),只需將此GPIO設置為禁止上拉(GPxUP相應位寫(xiě)入1),選擇output類(lèi)型(GPxCON相應位寫(xiě)入01), 輸出為高電平(GPxDAT相應位寫(xiě)入1)打開(kāi)LCD電源。
3、設置其他信號線(xiàn)
其他信號線(xiàn)包括VD0-VD23和VFRAME、VLINE、VCLK等,分別在GPCCON,GPDCON中選擇相應功能。
4、設置LCD的頻率(VCLK)
LCD的Datasheet上一般會(huì )寫(xiě)有一個(gè)推薦的頻率,比如我使用的屏幕推薦頻率為6.4M,我需要通過(guò)一些計算選擇一個(gè)合適的CLKVAL以產(chǎn)生這個(gè)頻率:
對于TFT LCD,S3C2440提供的VCLK的計算公式為:VCLK = HCLK / ((CLKVAL+1)*2)
可以得出:CLKVAL = HCLK / (VCLK * 2) - 1
我 的HCLK是100Mhz(CPU運行在400Mhz, CLKDIV_VAL設置為5,Fclk:Hclk:Pclk = 1:4:8),VCLK使用屏幕推薦的6.4M,得到:CLKVAL = 100000000 / (6400000 * 2) - 1 = 6.8
選擇最接近的整數值7,寫(xiě)入LCDCON1:17-8。
(VCLK其實(shí)就是根據 每秒幀數*幀行數*行像素 計算出來(lái)的,幀行數和行像素需要包含空白數和同步數)
5、設置其他相關(guān)參數
LCD相關(guān)的參數主要還有這幾個(gè):LINEVAL: LCD水平像素-1,如320-1 = 319HOZVAL: LCD垂直像素-1,如240-1 = 239HFPD: 行開(kāi)始前的VCLK時(shí)鐘數(LCD屏幕的Datasheet一般有推薦值)HBPD: 行結束后的VCLK時(shí)鐘數(LCD屏幕的Datasheet一般有推薦值)HSPW: 行之間水平同步的無(wú)效VCLK時(shí)鐘數(LCD屏幕的Datasheet一般有推薦值)VFPD: 幀數據開(kāi)始前的空白行數(LCD屏幕的Datasheet一般有推薦值)VBPD: 幀數據結束后的空白行數(LCD屏幕的Datasheet一般有推薦值)VSPW: 幀之間垂直同步的無(wú)效行數(LCD屏幕的Datasheet一般有推薦值)
(相關(guān)寄存器LCDCON2, LCDCON3, LCDCON4)
6、設置視頻緩沖區的地址
2440支持虛擬屏幕,可以通過(guò)改變LCD寄存器實(shí)現屏幕快速移動(dòng):
PAGEWIDTH:虛擬屏幕一行的字節數,如果不使用虛擬屏幕,設置為實(shí)際屏幕的行字節數,如16位寬320像素,設為320 * 2OFFSIZE:虛擬屏幕左側偏移的字節數,如果不使用虛擬屏幕,設置為0
LCDBANK: 視頻幀緩沖區內存地址30-22位LCDBASEU: 視頻幀緩沖區的開(kāi)始地址21-1位LCDBASEL: 視頻幀緩沖區的結束地址21-1位
(相關(guān)寄存器LCDSADDR1,LCDSADDR2,LCDSADDR3)
7、確定信號的極性
2440的LCD控制器允許設置VCLK、VLINE、VFRAME等信號的極性(上升沿有效還是下降沿有效),需要對照LCD的Datasheet一一確認。
(相關(guān)寄存器LCDCON5)
8、禁止LPC3600/LCC3600模式
如果不是使用三星LPC3600/LCC3600 LCD,必須禁止LPC3600/LCC3600模式(寫(xiě)入0到TCONSEL)。
評論