LCD---那些年我們一起玩mini2440(arm9)裸機(jī)
LCD-liquidcrystal display的簡稱,液晶顯示器按驅(qū)動(dòng)方式分為1.靜態(tài)驅(qū)動(dòng)、2.簡單矩陣驅(qū)動(dòng)及3.主動(dòng)矩陣驅(qū)動(dòng)。
其中,簡單矩陣又可分為1.扭轉(zhuǎn)向列型(TN)和超轉(zhuǎn)向列型(STN)兩種,而主動(dòng)矩陣驅(qū)動(dòng)則以TFT為主。
TN與STN都采用場電壓驅(qū)動(dòng)方式,如果顯示尺寸加大,中心部分對電機(jī)變化的反應(yīng)時(shí)間就會(huì)變長,顯示器的速度跟不上。為解決這個(gè)問題,主動(dòng)矩陣驅(qū)動(dòng)TFT被提出,他通過晶體管顯示信號(hào)開啟過關(guān)閉液晶分子的電壓,從而避免了顯示器對電場效應(yīng)的依靠。
LCD一塊屏顯示圖像不但需要LCD驅(qū)動(dòng)器,還需要LCD控制器。很多主芯片cpu集成了LCD控制器。
依據(jù)顯示原理:作為幀同步信號(hào)的vsync,每發(fā)出一個(gè)脈沖,都意味著新的一幅圖像數(shù)據(jù)開始傳送。而作為行同步信號(hào)的hsync,沒發(fā)出一個(gè)脈沖,都表明新的一行圖像資料開始發(fā)送。
LCD時(shí)序圖
所有LCD顯示圖像的原理都是從上到下,從左到右的。一幅圖像可以看做是一個(gè)矩形,由很多排列整齊的像素點(diǎn)一行一行組成,這些點(diǎn)稱為像素。
VCLK:像素時(shí)鐘信號(hào)
沒發(fā)出一個(gè)脈沖信號(hào),表示新的一個(gè)點(diǎn)圖像數(shù)據(jù)開始傳送。
LEND:行結(jié)束信號(hào)
幀緩沖
FrameBuffer從本質(zhì)上講是圖形設(shè)備的硬件抽象。對開發(fā)者而言,F(xiàn)rameBuffer是一塊顯示緩存,往顯示緩存中寫入特定格式的數(shù)據(jù)就意味著向屏幕輸出內(nèi)容。通過不斷的向framebuffer中寫入數(shù)據(jù),顯示控制器就自動(dòng)的從frame buffer中取數(shù)據(jù)并顯示出來。
嵌入式中從內(nèi)存中分一部分出來作為顯存;所以frame buffer的實(shí)質(zhì)就是顯存;
幀緩沖設(shè)備
幀緩沖設(shè)備時(shí)非常典型的字符設(shè)備。幀緩沖設(shè)備對應(yīng)的設(shè)備文件為/dev/fb*,如果系統(tǒng)有多個(gè)顯示卡,Linux下還可支持多個(gè)幀緩沖設(shè)備,最多可達(dá)32個(gè),分別為/dev/fb0到/dev/fb31,而/dev/fb0則為當(dāng)前缺省的幀緩沖設(shè)備,通常指向/dev/fb0。幀緩沖設(shè)備為標(biāo)準(zhǔn)字符設(shè)備,主設(shè)備號(hào)為29,次設(shè)備號(hào)則從0到31.
實(shí)驗(yàn)內(nèi)容:
1.清除LCD
使用命令:ddif=/dev/zero of=/dev/fb0 bs=240 count=320
(dd是用來拷貝文件的if(infile)of(outfile) bs :block size count:)
Bs=240即,一個(gè)塊為240個(gè)字節(jié);count=320有320個(gè)塊
2.運(yùn)行應(yīng)用程序,畫圖
./LCD
3.清除LCD
使用命令:ddif=/dev/zero of=/dev/fb0 bs=240 count=320
1.顯示圖片
2.catxx.bmp > /dev/fb0
總結(jié):通過frame buffer我們可以去操作LCD的顯示圖像,即LCD顯示圖像來源于frame buffer,而/dev/fb0又是frame buffer的設(shè)備文件,所以操作/dev/fb0即是操作frame buffer
平臺(tái)設(shè)備分類方法是:總線;
字符設(shè)備分類方法:功能
#include
#include
#include
#include
#include
intmain(){
intfp=0;
structfb_var_screeninfovinfo;
structfb_fix_screeninfofinfo;
longscreensize=0;
char*fbp=0;
intx=0,y=0;
longlocation=0;
fp=open("/dev/fb0",O_RDWR);//打開framebuffer設(shè)備文件
if(fp<0){
printf("Error:Cannotopenframebufferdevicen");
exit(1);
}
if(ioctl(fp,FBIOGET_FSCREENINFO,&finfo)){//獲取LCD的一些配置參數(shù)
printf("Errorreadingfixedinformationn");
exit(2);
}
if(ioctl(fp,FBIOGET_VSCREENINFO,&vinfo)){
printf("Errorreadingvariableinformationn");
exit(3);
}
screensize=vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8;//單幀畫面空間
/*這就是把fp所指的文件中從開始到screensize大小的內(nèi)容給映射出來,得到一個(gè)指向這塊空間的指針*/
fbp=(char*)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fp,0);//把顯存映射到進(jìn)程空間中來,fbp為映射地址
if((int)fbp==-1)
{
printf("Error:failedtomapframebufferdevicetomemory.n");
exit(4);
}
/*這是你想畫的點(diǎn)的位置坐標(biāo),(0,0)點(diǎn)在屏幕左上角*/
//畫矩形
for(x=100;x<150;x++)
{
for(y=100;y<150;y++)
{
location=x*(vinfo.bits_per_pixel/8)+y*finfo.line_length;
*(fbp+location)=255;/*藍(lán)色的色深*//*直接賦值來改變屏幕上某點(diǎn)的顏色*/
*(fbp+location+1)=0;/*綠色的色深*//*注明:這幾個(gè)賦值是針對每像素四字節(jié)來設(shè)置的,如果針對每像素2字節(jié),*/
*(fbp+location+2)=0;/*紅色的色深*//*比如RGB565,則需要進(jìn)行轉(zhuǎn)化*/
*(fbp+location+3)=0;/*是否透明*/
}
}
munmap(fbp,screensize);/*解除映射*/
close(fp);/*關(guān)閉文件*/
return0;
}