<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          S3C2440的LCD編程

          作者: 時(shí)間:2016-11-27 來源:網(wǎng)絡(luò) 收藏

          4. 幀緩沖(FrameBuffer):
            幀緩沖是Linux為顯示設(shè)備提供的一個(gè)接口,它把一些顯示設(shè)備描述成一個(gè)緩沖區(qū),允許應(yīng)用程序通過 FrameBuffer定義好的接口訪問這些圖形設(shè)備,從而不用去關(guān)心具體的硬件細(xì)節(jié)。對于幀緩沖設(shè)備而言,只要在顯示緩沖區(qū)與顯示點(diǎn)對應(yīng)的區(qū)域?qū)懭腩伾?值,對應(yīng)的顏色就會自動的在屏幕上顯示。下面來看一下在不同色位模式下緩沖區(qū)與顯示點(diǎn)的對應(yīng)關(guān)系:

          本文引用地址:http://www.ex-cimer.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上顯示單個(gè)像素的函數(shù)實(shí)際上很簡潔,看來似乎只需要LCD_BUFFER[(y)][(x)] = c這一句話.下面就來分析下,是如何通過這一句話來實(shí)現(xiàn)在LCD上顯示單個(gè)像素的,先分析下Lcd_Init()即LCD初始化函數(shù):

          #define rGPCCON(*(volatile unsigned *)0x56000020)
          #define rGPCUP(*(volatile unsigned *)0x56000028)
          #define rGPDCON(*(volatile unsigned *)0x56000030)
          #define rGPDUP(*(volatile unsigned *)0x56000038)

          #define rLCDCON1(*(volatile unsigned *)0x4d000000)
          #define rLCDCON2(*(volatile unsigned *)0x4d000004)
          #define rLCDCON3(*(volatile unsigned *)0x4d000008)
          #define rLCDCON4(*(volatile unsigned *)0x4d00000c)
          #define rLCDCON5(*(volatile unsigned *)0x4d000010)
          #define rLCDSADDR1(*(volatile unsigned *)0x4d000014)
          #define rLCDSADDR2(*(volatile unsigned *)0x4d000018)
          #define rLCDSADDR3(*(volatile unsigned *)0x4d00001c)
          #define rLCDINTMSK(*(volatile unsigned *)0x4d00005c)
          #define rTPAL(*(volatile unsigned *)0x4d000050)

          void Lcd_Init(void)
          {
          rGPCUP=0xffffffff;// Disable Pull-up register
          rGPCCON=0xaaaa56a9; //Initialize VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND

          rGPDUP=0xffffffff;// Disable Pull-up register
          rGPDCON=0xaaaaaaaa; //Initialize VD[15:8]

          //LCDCON1: TFT LCD panel,MMODE[7]=0,16bpp TFT,ENVID=off
          rLCDCON1=(CLKVAL_TFT_320240<<8)|(MVAL_USED<<7)|(3<<5)|(12<<1)|0;
          rLCDCON2=(VBPD_320240<<24)|(LINEVAL_TFT_320240<<14)|(VFPD_320240<<6)|(VSPW_320240);
          rLCDCON3=(HBPD_320240<<19)|(HOZVAL_TFT_320240<<8)|(HFPD_320240);
          rLCDCON4=(MVAL<<8)|(HSPW_320240);
          rLCDCON5=(1<<11)|(1<<9)|(1<<8)|(1<<3)|(BSWP<<1)|(HWSWP);
          //rLCDCON5=(1<<11)|(0<<9)|(0<<8)|(0<<6)|(BSWP<<1)|(HWSWP);
          //FRM5:6:5,HSYNC and VSYNC are inverted


          //LCDBANK[29:21] = (U32)LCD_BUFFER >> 22 : These bits indicate A[30:22] of the bank location for the video buffer in the system memory. LCDBANK value cannot be changed even when moving the view port. LCD frame buffer should be within aligned 4MB region, which ensures that LCDBANK value will not be changed when moving the view port. So, care should be taken to use the malloc() function.
          //系統(tǒng)內(nèi)存地址A[30:22]處的Bank位置為圖像緩沖。LCDBANK的值在視圖移動的值在視圖移動時(shí)不能改變,LCD幀緩沖應(yīng)該在4MB區(qū)域?qū)R,保證LCDBANK的值在移動視圖時(shí)不會改變。
          //LCDBASEU[20:0] = ((U32)LCD_BUFFER >> 1)&0x1fffff : For dual-scan LCD : These bits indicate A[21:1] of the start address of the upper address counter, which is for the upper frame memory of dual scan LCD or the frame memory of single scan LCD.
          //For single-scan LCD : These bits indicate A[21:1] of the start address of the LCD frame buffer.
          //雙掃描:表明高地址計(jì)數(shù)器的起始地址A[21:1],用于LCD雙掃描的上部幀內(nèi)存或者單掃描的幀內(nèi)存
          //單掃描:表明LCD幀緩沖的起始地址A[21:1]
          rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1);

          //LCDSADDR2 0x4d000018幀緩沖起始寄存器2:
          //LCDBASEL[20:0] = ((LCD_ADDR + LCD_WIDTH * LCD_HEIGHT * 2) >> 1)& 0x1fffff = (LCD_ADDR >> 1 + LCD_WIDTH * LCD_HEIGHT)& 0x1fffff
          //For dual-scan LCD: These bits indicate A[21:1] of the start address of the lower address counter, which is used for the lower frame memory of dual scan LCD.
          //For single scan LCD: These bits indicate A[21:1] of the end address of the LCD frame buffer.
          //LCDBASEL = ((the frame end address) >>1) + 1 = LCDBASEU + (PAGEWIDTH+OFFSIZE) x (LINEVAL+1)
          //雙掃描:表明低地址計(jì)數(shù)器的起始地址A[21:1],用于LCD雙掃描的下部幀內(nèi)存或者單掃描的幀內(nèi)存
          //單掃描:表明LCD幀緩沖的結(jié)束地址A[21:1]
          rLCDSADDR2=M5D( ((U32)LCD_BUFFER+(SCR_XSIZE_TFT_320240*LCD_YSIZE_TFT_320240*2))>>1 );

          //LCDSADDR3 0x4d00001c幀緩沖起始寄存器3:
          //OFFSIZE = 0;PAGEWIDTH = 320 虛擬屏頁寬(半字?jǐn)?shù)量)定義了幀中的視圖域?qū)挾?br />rLCDSADDR3=(((SCR_XSIZE_TFT_320240-LCD_XSIZE_TFT_320240)/1)<<11)|(LCD_XSIZE_TFT_320240/1);

          rLCDINTMSK|=(3);// MASK LCD Sub Interrupt
          //rTCONSEL|=((1<<4)|1); // Disable LCC3600, LPC3600
          rTPAL=0;// Disable Temp Palette
          }

          程序分析至此,大概已經(jīng)清楚是如何通過LCD_BUFFER[(y)][(x)] = c來實(shí)現(xiàn)在LCD上顯示單個(gè)像素了。就是在設(shè)置好各個(gè)LCD寄存器之后,通過將LCD_BUFFER地址與LCDBANK以及LCDBASEU、 LCDBASEL對應(yīng)之后,通過改變LCD_BUFFER里不同單元存儲的值(即像素的顏色),即可在LCD相應(yīng)位置上做出顯示。
            那么在應(yīng)用不同LCD的時(shí)候,只需對LCDCONx以及LCDSADDRx做出相應(yīng)的配置,再創(chuàng)建一個(gè)數(shù)組,做出上述的地址映射即可。

            關(guān)于VCLK計(jì)算,由于配置的是TFT,可用到公式VCLK = HCLK / [(CLKVAL+1) * 2] ( CLKVAL>=0 ),設(shè)置的Fclk為400MHz,Hclk為100MHz(Fclk:Hclk=1:4),CLKVAL = 4,因此VLCK = 10MHz。

          筆記:
            首先說一下我們平時(shí)所說的多少位的LCD,有24位的,有16位的指的是LCD數(shù)據(jù)的位數(shù),LCD的數(shù)據(jù)實(shí)際上是LCD要顯示的顏色,24位的是紅綠 藍(lán)各占8位,16位則是紅綠藍(lán)按照565分配的,其實(shí)24的也可以只接16位,每個(gè)顏色地位接地就可以,所以要給LCD的緩沖區(qū)一個(gè)數(shù)據(jù)才能在LCD上顯 示出來。那究竟是怎么顯示的呢,那就得先說一下像素了,LCD的像素實(shí)際上就LCD屏幕有多少個(gè)點(diǎn),LCD顯示的東西都是一個(gè)一個(gè)點(diǎn)拼湊出來的,比如我用 的是320*240的LCD,就是說LCD每一行有320個(gè)點(diǎn),而每一列有240個(gè)點(diǎn),所以總共有320*240個(gè)點(diǎn),我們讓適當(dāng)?shù)狞c(diǎn)顯示適當(dāng)?shù)念伾瓦_(dá) 到了我們的目的。


            其實(shí)剛開始困擾我們的是LCD的初始化的問題,要設(shè)置的東西比較多,其實(shí)我們是記不住這些東西的,呵呵,作為入門我們可以參考別人的初始化程序,把里面的參數(shù)改成我們自己的LCD的參數(shù)就OK了。


            那么我們到底是怎么把我們要顯示的數(shù)據(jù)送給LCD控制起的呢?是這樣的,我們可以定義一個(gè)二維數(shù)組,把我們要顯示的數(shù)據(jù)存到里面,然后把這個(gè)數(shù)組的地 址賦給LCD的相應(yīng)的寄存器,這個(gè)寄存器是LCDSADDRn,具體的設(shè)置大家可以參考數(shù)據(jù)手冊,我們可以把二維數(shù)組的坐標(biāo)和LCD的坐標(biāo)對應(yīng)起來,那么 我們就可以隨意的讓哪一個(gè)像素點(diǎn)顯示什么顏色就顯示什么顏色了。這就把數(shù)據(jù)送出的過程,也就是顯示一個(gè)像素點(diǎn)的過程。


            到現(xiàn)在我們已經(jīng)知道如何顯示一個(gè)像素了,那接下來就是LCD顯示最基本的東西了----字符和圖片。漢字和圖片的顯示都是基于像素點(diǎn)的顯示的,我們把 要顯示的字符和圖片轉(zhuǎn)化成相應(yīng)的數(shù)據(jù),然后傳遞給LCD即可。我們可以專門的寫一個(gè)顯示字符的函數(shù)和一個(gè)顯示圖片的函數(shù)。顯示字符的數(shù)據(jù)可以用取模軟件生 成,因?yàn)樯傻淖址麛?shù)據(jù)是表示的每一個(gè)點(diǎn)要不要亮,亮的地方用1表示,不亮的地方用0表示,所以如果用LCD顯示,我們還要告訴LCD顯示什么顏色,這才 是LCD需要的數(shù)據(jù),比如說16*16的數(shù)據(jù),有16行16列,我們將一行的數(shù)據(jù),也就是16位數(shù)據(jù)的每一位都取出來,為1的地方,我們就給LCD一個(gè) 16位的數(shù)據(jù),為0的地方就不給數(shù)據(jù),這樣就能顯示了,取模生成的數(shù)據(jù)都是按行來的。圖片的顯示直接就將16位的數(shù)據(jù)傳遞給LCD,這個(gè)圖片數(shù)據(jù)的產(chǎn)生, 我們可以用軟件LCD彩色圖片轉(zhuǎn)換工具(BMP_to_H)生成C語言文件,我們只需對文件進(jìn)行簡單的修改就能加入到我們的程序中,修改方法在軟件的說明 中都有。


          編程要點(diǎn):
          1、打開LCD背光
          將LCD背光對應(yīng)的GPIO設(shè)置為禁止上拉(GPxUP相應(yīng)位寫入1),選擇output類型(GPxCON相應(yīng)位寫入01),輸出為高電平(GPxDAT相應(yīng)位寫入1)。

          2、打開LCD電源
          可以將GPG4選擇為LCD_PWREN(GPGCON:9-8寫入11),這時(shí)候LCD電源的打開/關(guān)閉可以通過LCDCON5:3來控制。也可以自定 義其他GPIO用作LCD電源開關(guān),只需將此GPIO設(shè)置為禁止上拉(GPxUP相應(yīng)位寫入1),選擇output類型(GPxCON相應(yīng)位寫入01), 輸出為高電平(GPxDAT相應(yīng)位寫入1)打開LCD電源。

          3、設(shè)置其他信號線
          其他信號線包括VD0-VD23和VFRAME、VLINE、VCLK等,分別在GPCCON,GPDCON中選擇相應(yīng)功能。

          4、設(shè)置LCD的頻率(VCLK)
          LCD的Datasheet上一般會寫有一個(gè)推薦的頻率,比如我使用的屏幕推薦頻率為6.4M,我需要通過一些計(jì)算選擇一個(gè)合適的CLKVAL以產(chǎn)生這個(gè)頻率:
          對于TFT LCD,S3C2440提供的VCLK的計(jì)算公式為:VCLK = HCLK / ((CLKVAL+1)*2)
          可以得出:CLKVAL = HCLK / (VCLK * 2) - 1
          我 的HCLK是100Mhz(CPU運(yùn)行在400Mhz, CLKDIV_VAL設(shè)置為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其實(shí)就是根據(jù) 每秒幀數(shù)*幀行數(shù)*行像素 計(jì)算出來的,幀行數(shù)和行像素需要包含空白數(shù)和同步數(shù))

          5、設(shè)置其他相關(guān)參數(shù)
          LCD相關(guān)的參數(shù)主要還有這幾個(gè):LINEVAL: LCD水平像素-1,如320-1 = 319HOZVAL: LCD垂直像素-1,如240-1 = 239HFPD: 行開始前的VCLK時(shí)鐘數(shù)(LCD屏幕的Datasheet一般有推薦值)HBPD: 行結(jié)束后的VCLK時(shí)鐘數(shù)(LCD屏幕的Datasheet一般有推薦值)HSPW: 行之間水平同步的無效VCLK時(shí)鐘數(shù)(LCD屏幕的Datasheet一般有推薦值)VFPD: 幀數(shù)據(jù)開始前的空白行數(shù)(LCD屏幕的Datasheet一般有推薦值)VBPD: 幀數(shù)據(jù)結(jié)束后的空白行數(shù)(LCD屏幕的Datasheet一般有推薦值)VSPW: 幀之間垂直同步的無效行數(shù)(LCD屏幕的Datasheet一般有推薦值)
          (相關(guān)寄存器LCDCON2, LCDCON3, LCDCON4)

          6、設(shè)置視頻緩沖區(qū)的地址
          2440支持虛擬屏幕,可以通過改變LCD寄存器實(shí)現(xiàn)屏幕快速移動:
          PAGEWIDTH:虛擬屏幕一行的字節(jié)數(shù),如果不使用虛擬屏幕,設(shè)置為實(shí)際屏幕的行字節(jié)數(shù),如16位寬320像素,設(shè)為320 * 2OFFSIZE:虛擬屏幕左側(cè)偏移的字節(jié)數(shù),如果不使用虛擬屏幕,設(shè)置為0
          LCDBANK: 視頻幀緩沖區(qū)內(nèi)存地址30-22位LCDBASEU: 視頻幀緩沖區(qū)的開始地址21-1位LCDBASEL: 視頻幀緩沖區(qū)的結(jié)束地址21-1位
          (相關(guān)寄存器LCDSADDR1,LCDSADDR2,LCDSADDR3)

          7、確定信號的極性
          2440的LCD控制器允許設(shè)置VCLK、VLINE、VFRAME等信號的極性(上升沿有效還是下降沿有效),需要對照LCD的Datasheet一一確認(rèn)。
          (相關(guān)寄存器LCDCON5)

          8、禁止LPC3600/LCC3600模式
          如果不是使用三星LPC3600/LCC3600 LCD,必須禁止LPC3600/LCC3600模式(寫入0到TCONSEL)。


          上一頁 1 2 下一頁

          關(guān)鍵詞: S3C2440LCD編

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();