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