S3C2440 TFTLCD驅(qū)動(dòng)詳解
S3C2440自帶有LCD控制器,該控制器主要有以下接口
僅僅說(shuō)TFT顯示器,TFT顯示器的時(shí)序如下
TFT顯示器的驅(qū)動(dòng)是以行列的形式逐點(diǎn)掃描過(guò)來(lái)的,驅(qū)動(dòng)時(shí)鐘有三種,一種是行時(shí)鐘,一種是列時(shí)鐘,還有一個(gè)點(diǎn)時(shí)鐘, VSYNC低電平期間需要掃描完一列數(shù)據(jù), HSYNC低電平期間要寫完一個(gè)點(diǎn)的數(shù)據(jù),vclk負(fù)責(zé)一個(gè)點(diǎn)的每一位數(shù)據(jù)寫入,實(shí)際上就是說(shuō),如果有a列,b行,一個(gè)點(diǎn)需c個(gè)VCLK時(shí)鐘,那么掃描完成需要的中vclk為a*b*c(近似,中間還有一些延時(shí)時(shí)間)
可以將這個(gè)過(guò)程看作是1602的刷新過(guò)程, VSYNC為低選擇一列, HSYNC為低選擇一行,然后寫入顯示數(shù)據(jù)還需要一個(gè)數(shù)據(jù)時(shí)鐘,寫完之后指針自動(dòng)增長(zhǎng),中間的等待時(shí)間是設(shè)備響應(yīng)時(shí)間,在TFT上叫做同步時(shí)間,用于時(shí)鐘的同步,防止時(shí)鐘混亂
那么現(xiàn)在就有這些參數(shù)需要設(shè)置
VBPD: VSYNC與VCLK的開始同步時(shí)間
VSPW: VHYNC脈沖的高電平寬度
LINEVAL LCD面板的垂直尺寸:
VFPD: VSYNC與VCLK的結(jié)束同步時(shí)間
HBPD: HSYNC與VCLK的開始同步時(shí)間
HFPD: HSYNC與VCLK的結(jié)束同步時(shí)間
HOZVAL: 決定了LCD面板的水平尺寸
HSPW: HSYNC脈沖的高電平寬度
配置這些參數(shù)一般都依靠顯示器的數(shù)據(jù)手冊(cè)進(jìn)行配置,我使用群創(chuàng)4.3寸屏幕,數(shù)據(jù)手冊(cè)上顯示
也就是說(shuō),確定一個(gè)DCLK時(shí)間,剩下的都可以確定了.(配置之前注意IO口功能配置GPIOC和D)
根據(jù)這張表,驅(qū)動(dòng)S3C2440的步驟分為以下幾步
1.設(shè)置DCLK頻率,像素比以及信號(hào)輸出
2.確定VSYC的開始同步結(jié)束同步以及高電平寬度還有尺寸
3.3.設(shè)置HSYC的開始同步結(jié)束同步以及高電平寬度還有尺寸
4.設(shè)置HSPW時(shí)間
5.對(duì)于輸出的圖像格式進(jìn)行一些選擇
6.設(shè)置LCD顯示緩沖區(qū)相關(guān)的數(shù)據(jù)
然后,CPU系統(tǒng)就會(huì)去自動(dòng)刷新屏幕(使用緩沖區(qū)數(shù)據(jù)),而我們的讀出寫入都針對(duì)于緩沖區(qū),再由顯示器接口寫入顯示器
具體設(shè)置請(qǐng)查看程序:
Lcd.c
#include"tftlcd.h"volatilestaticunsignedshortLCD_BUFFER[SCR_YSIZE_TFT][SCR_XSIZE_TFT];//定義顯示緩存區(qū)/**************************************************************TFTLCD功能模塊初始化**************************************************************/voidLCDInit(void){//配置引腳rGPCUP=0x00000000;rGPCCON=0xaaaa02a9;rGPDUP=0x00000000;rGPDCON=0xaaaaaaaa;//InitializeVD[15:8]//TFTLCDpanel,16bppTFT,ENVID=offrLCDCON1=(CLKVAL_TFT<<8)"(MVAL_USED<<7)|(3<<5)|(12<<1)|0;rLCDCON2=(VBPD<<24)|(LINEVAL_TFT<<14)|(VFPD<<6)|(VSPW);rLCDCON3=(HBPD<<19)|(HOZVAL_TFT<<8)|(HFPD);rLCDCON4=HSPW;rLCDCON5=(1<<11)|(0<<10)|(1<<9)|(1<<8)|(0<<7)|(0<<6)|(1<<3)|(BSWP<<1)|(HWSWP);//16位輸出格式565,VCLK下降沿取數(shù)據(jù)等(看數(shù)據(jù)手冊(cè))這里指定目的地址rLCDSADDR1=(((u32)LCD_BUFFER>>22)<<21)|M5D((u32)LCD_BUFFER>>1);//單掃描rLCDSADDR2=M5D(((u32)LCD_BUFFER+(SCR_XSIZE_TFT*LCD_YSIZE_TFT*2))>>1);//LCD_WIDTH×16/16;由于是選擇的16位模式,//如果是24位模式,每個(gè)像素4字節(jié)則為L(zhǎng)CD_WIDTH×32/16//(LCD_WIDTH在此為L(zhǎng)CD_XSIZE_TFT)rLCDSADDR3=(((SCR_XSIZE_TFT-LCD_XSIZE_TFT)/1)<<11)|(LCD_XSIZE_TFT/1);rLCDINTMSK|=(3);//MASKLCDSubInterruptrTCONSEL&=(~7);//DisableLPC3600rTPAL=0;//禁止臨時(shí)調(diào)色板寄存器}/***************************************************************LCD視頻和控制信號(hào)輸出或者停止,1開啟視頻輸出**************************************************************/voidLCDEnvidOnOff(intonoff){if(onoff==1)rLCDCON1|=1;//ENVID=ONelserLCDCON1=rLCDCON1&0x3fffe;//ENVIDOff}/***************************************************************TFTLCD電源控制引腳使能*pwren=1時(shí),允許PWREN信號(hào)*pwren=0時(shí),禁止PWREN信號(hào)*invpwre=1,PWREN信號(hào)極性反轉(zhuǎn)*invpwre=0,PWREN信號(hào)極性正常**************************************************************/voidLCDPowerEnable(intinvpwren,intpwren){//GPG4issettedasLCD_PWRENrGPGUP|=(1<<4);//GPG4上拉電阻無(wú)效rGPGCON|=(3<<8);//GPG4=LCD_PWRENrGPGDAT|=1<<4;//GPG4置1//invpwren=pwren;//EnableLCDPOWERENABLEFunctionif(pwren)rLCDCON5|=1<<3;elserLCDCON5&=~(1<<3);if(invpwren)rLCDCON5|=1<<5;elserLCDCON5&=~(1<<5);}/**************************************************************TFTLCD單個(gè)象素的顯示數(shù)據(jù)輸出**************************************************************/voidLCDPutPixel(u32x,u32y,u32color){if((x0)incx=1;//設(shè)置單步方向elseif(delta_x==0)incx=0;//垂直線else{incx=-1;delta_x=-delta_x;}if(delta_y>0)incy=1;elseif(delta_y==0)incy=0;//水平線else{incy=-1;delta_y=-delta_y;}if(delta_x>delta_y)distance=delta_x;//選取基本增量坐標(biāo)軸elsedistance=delta_y;for(t=0;t<=distance+1;t++)//畫線輸出{LCDPutPixel(uRow,uCol,color);//畫點(diǎn)xerr+=delta_x;yerr+=delta_y;if(xerr>distance){xerr-=distance;uRow+=incx;}if(yerr>distance){yerr-=distance;uCol+=incy;}}}//畫矩形voidLCDDrawRectangle(u16x1,u16y1,u16x2,u16y2,u16color){LCDDrawLine(x1,y1,x2,y1,color);LCDDrawLine(x1,y1,x1,y2,color);LCDDrawLine(x1,y2,x2,y2,color);LCDDrawLine(x2,y1,x2,y2,color);}//在指定位置畫一個(gè)指定大小的圓//(x,y):中心點(diǎn)//r:半徑voidLCDDrawCircle(u16x0,u16y0,u8r,u16color){inta,b;intdi;a=0;b=r;di=3-(r<<1);//判斷下個(gè)點(diǎn)位置的標(biāo)志while(a<=b){LCDPutPixel(x0-b,y0-a,color);//3LCDPutPixel(x0+b,y0-a,color);//0LCDPutPixel(x0-a,y0+b,color);//1LCDPutPixel(x0-b,y0-a,color);//7LCDPutPixel(x0-a,y0-b,color);//2LCDPutPixel(x0+b,y0+a,color);//4LCDPutPixel(x0+a,y0-b,color);//5LCDPutPixel(x0+a,y0+b,color);//6LCDPutPixel(x0-b,y0+a,color);a++;//使用Bresenham算法畫圓if(di<0)di+=4*a+6;else{di+=10+4*(a-b);b--;}LCDPutPixel(x0+a,y0+b,color);}}