LCD

注意:本資料來源於朱友鵬老師的課程的視頻,只用於學習使用,如用於其他用途,請聯繫朱老師本人,不然後果自負,不允許轉載!!!

LCD的接口技術

從電平角度來講本質上都是TTL信號

(1)什麼是TTL接口。+5V表示邏輯1,0V表示邏輯0.這種就叫TTL電平,和CMOS電平相對比。
(2)SoC的LCD控制器硬件接口是TTL電平的,LCD這邊硬件接口也是TTL電平的。所以他們倆本來是可以直接對接的,手機、平板、開發板都是這樣直接對接的(一般用軟排線連接)。
(3)TTL電平的缺陷就是不能傳遞太遠,如果LCD屏幕和主板控制器太遠(1米甚至更遠)就不能直接TTL連接了,要進行轉換。轉換方式:主機So(TTL) ->VGA-> LCD屏幕(TTL)

RGB接口詳解(參考數據手冊P1207頁時序圖)

(1)VD[23:0]:24根數據線,用來傳輸圖像信息。可見LCD是並行接口,速率纔夠快。
(2)HSYNC(水平同步信號)
(3)VSYNC(垂直同步信號):時序信號線,爲了讓LCD能夠正常顯示給的控制信號
(4)VCLK(像素時鐘):LCD工作時需要主板控制器給LCD模組一個工作時鐘信號,就是VCLK。
(5)VDEN(數據有效標誌):時序信號,和HSYNC、VSYNC結合使用。
(6)LEND(行結束標誌,不是必須的):時序信號,非必須,譬如X210接口就沒有。

圖像是由像素組成的,每個像素由三種組成,紅-綠-藍

顯存的概念

1.顯存就是圖像的信息存儲的那塊內存,這個是由程序員來制定的,通過配置LCD控制器和內存的映射,從而使改變內存就可以改變圖像的,一旦這個關係建立之後,LCD控制器就會自動從顯存中讀取像素數據傳輸給LCD驅動器。這個顯示的過程不需要CPU的參與。
2顯示體系建立起來後,CPU就不用再管LCD控制器、驅動器、面板這些東西了;以後CPU就只關心顯存了,因爲我只要把要顯示的圖像的像素數據丟到顯存中,硬件就會自動響應(屏幕上就能自動看到顯示的圖像了)。

LCD的六個主要時序參數

LCD顯示單位:幀(frame)

(1)顯示器上一整個畫面的內容成爲一個幀(frame),整個顯示器工作時是一幀一幀的在顯示。
(2)電影實際就是以每秒種24幀的速度在播放圖片。
(3)幀內數據:一幀分爲多行,一行分爲多像素,因此一幀圖像其實就是多個像素組成的矩陣。
(4)幀外數據:整個視頻由很多個幀構成,最終播放視頻時逐個播放各個圖像幀即可。

LCD顯示一幀圖像的過程

(1)首先把幀分爲行,然後再把行分爲像素,然後逐個像素去顯示。(顯示像素:其實就是LCD驅動器按照接收到的LCD控制器給的顯示數據,驅動一個像素的液晶分子旋轉,讓這個像素顯示出相應的顏色值的過程)
(2)關鍵點:LCD控制器和驅動器之間一次只能傳一個像素點的顯示數據。所以一幀圖像在屏幕上其實是串行的依次被顯示上去的,不是同一時間顯示出來的。

爲了向前兼容出現的六個時序參數

HSPW 水平同步信號脈寬

HBPD 水平同步信號前肩

HFPD 水平同步信號後肩

VSPW 垂直同步信號脈寬

VBPD 垂直同步信號前肩

VFPD 垂直同步信號後肩

時序過程

(1)一行的通信過程是這樣的:LCD控制器先發送一個HSYNC高電平脈衝(脈衝寬度是HSPW),脈衝告訴驅動器下面的信息是一行信息。然後開始這一行信息,這一行信息包括3部分:HBPD+有效行信息+HFPD。其中前肩和後肩都屬於時序信息(和LCD屏幕具體有關),有效行信息就是橫向分辨率。所以你可以認爲一行總共包含4部分:HSPW+HBPD+有效行信息+HFPD。
(2)一幀圖像其實就是一列,一列圖像由多個行組成,每行都是上面講的這個時序。
(3)一幀圖像的通信過程是這樣的:整個幀圖像信號分爲4部分:VSPW+VBPD+幀有效信號+VFPD。VSPW是幀同步信號寬度,用來告訴驅動器一幀圖像要開始了;VBPD和VFPD分別是垂直同步信號前後肩。
(4)必須說明:這6個參數對於LCD顯示器其實本來是沒用的,這些信號其實是老式的CRT顯示器才需要的,LCD本身不需要,但是出於歷史兼容性要求,LCD選擇了兼容CRT顯示器的這些時序要求,所以理解LCD顯示器時序和編程時,用CRT的方式來理解不會錯。
(5)要注意,這幾個時序參數本身是LCD屏幕本身的參數,與LCD控制器無關。所以同一個主板如果接的屏幕不一樣則時序參數設置也會不同。這些參數的來源一般是:第一,廠家會直接給出,一般以實例代碼的形式給出;第二,來自於LCD的數據手冊。
第一種方式,查看九鼎的210裸機教程(x210v3裸機開發教程\src\template-framebuffer-font\source\hardware\s5pv210-fb.c的第774行)

像素深度(bits per pixel,簡稱bpp)

(1)一個像素在計算機中由多少個字節數據來描述。
(2)計算機中用二進制位來表示一個像素的數據,用來表示一個像素的數據位越多,則這個像素的顏色值更加豐富、分的更細,顏色深度就更深。
(3)一般來說像素深度有這麼幾種:1位、8位、16位、24位、32位。

常見像素深度:1位、8位、16位、24位、32位
1位:用1個二進制位來表示顏色,這種就叫單色顯示。示例就是小飯店、理髮店門口的LED屏。
8位:用8個二進制位來表示顏色,此時能表示256種顏色。這種叫灰度顯示。這時候是黑白的,沒有彩色,我們把純白到純黑分別對應255到0,中間的數值對應不同的灰。示例就是以前的黑白電視機。
16位:用16個二進制位表示顏色,此時能表示65536種顏色。這時候就可以彩色顯示了,一般是RGB565的顏色分佈(用5位二進制表示紅色、用6位二進制表示綠色、用5位二進制表示藍色)。這種紅綠藍都有的顏色表示法就是一種模擬自然界中所有顏色的表示方式。但是因爲RGB的顏色表達本身二進制位數不夠多(導致紅綠藍三種顏色本身分的都不夠細緻),所以這樣顯示的彩色失真比較重,人眼能明顯看到顯示的不真實。
24位:用24個二進制位來表示顏色,此時能表示16777216種顏色。這種表示方式和16位色原理是一樣的,只是RGB三種顏色各自的精度都更高了(RGB各8位),叫RGB888。此時顏色比RGB565更加真實細膩,雖然說比自然界無數種顏色還是少了很多,不過由於人眼的不理想性所以人眼幾乎不能區分1677萬種顏色和無數種顏色的差別了。於是乎就把這種RGB888的表示方法叫做真彩色。(RGB565就是假彩色)
32位:總共用32位二進制來表示顏色,其中24位表示紅綠藍三元色(還是RGB888分佈),剩下8位表示透明度。這種顯色方式就叫ARGB(A是阿爾法,表示透明度),現在PC機中一般都用ARGB表示顏色。

補充:顏色的組成,三元色(三基色)是RGB,也就是說所有的顏色都可以由紅綠藍三種顏色組成。

虛擬屏幕的疊加問題

210 由5個虛擬屏幕 ,每中可以疊加,可以設置顯示的前後

使用虛擬屏幕優勢:不污染原圖像,不佔內存

虛擬顯示(數據手冊P1206)

(1)如何實現在小分辨率的屏幕上(真實)顯示大分辨率的圖像
(2)細節上,我們需要屏幕上看到不同圖像時,需要對顯存區域進行刷新。即使我們只需要屏幕顯示移動一點點,整個屏幕對應的顯存空間也需要整個重新刷新,工作量和完全重新顯示一幅圖像是一樣的。這個顯然不好,這樣CPU刷新屏幕的工作量太大了,效率很低。
(3)如何能夠在顯示一個大圖片的不同區域時讓CPU刷新屏幕工作量減少?有,方法就是虛擬顯示。具體做法就是在內存中建立顯示緩存的時候實際建立一個很大的區域,然後讓LCD去對應其中的一部分區域作爲有效的顯示區域。將來要顯示大圖像時,直接將大圖像全部一次性加載入顯示緩存區,然後通過移動有效顯示區域就可以顯示大圖像的不同區域了。

程序lcd_init

基本流程:1.配置LCD引腳的模式

這裏寫圖片描述

2.設置背光:找到引腳位置,配置爲輸出模式,給其低電平

這裏寫圖片描述

3.最容易忘的點:RGB=FIMD I80=FIMD ITU=FIMD

這裏寫圖片描述

4.RGB接口,並行,時鐘源選擇

這裏寫圖片描述

5.時鐘分頻

這裏寫圖片描述

6. 時序反轉

這裏寫圖片描述

7.時序時間設置

這裏寫圖片描述

8.物理屏幕設置

這裏寫圖片描述

9.設置windows0使能,配置像素深度爲24bpp

這裏寫圖片描述

10.顯存大小配置

這裏寫圖片描述

11.配置顯存地址,顯存地址的空間大小

VIDW00ADD1B0 = (((HOZVAL + 1)4 + 0) (LINEVAL + 1)) & (0xffffff); 這句是將10進制數字轉化爲16進制的數

這裏寫圖片描述

12.使能channel 0傳輸數據

這裏寫圖片描述

示例代碼:

// 配置引腳用於LCD功能
    GPF0CON = 0x22222222;
    GPF1CON = 0x22222222;
    GPF2CON = 0x22222222;
    GPF3CON = 0x22222222;

    // 打開背光 GPD0_0(PWMTOUT0)
    GPD0CON &= ~(0xf<<0);
    GPD0CON |= (1<<0);          // output mode
    GPD0DAT &= ~(1<<0);            // output 0 to enable backlight

    // 10: RGB=FIMD I80=FIMD ITU=FIMD
    DISPLAY_CONTROL = 2<<0;

    // bit[26~28]:使用RGB接口
    // bit[18]:RGB 並行
    // bit[2]:選擇時鐘源爲HCLK_DSYS=166MHz
    VIDCON0 &= ~( (3<<26)|(1<<18)|(1<<2) );

    // bit[1]:使能lcd控制器
    // bit[0]:當前幀結束後使能lcd控制器
    VIDCON0 |= ( (1<<0)|(1<<1) );

    // bit[6]:選擇需要分頻
    // bit[6~13]:分頻係數爲5,即VCLK = 166M/(4+1) = 33M
    VIDCON0 |= 4<<6 | 1<<4;


    // H43-HSD043I9W1.pdf(p13) 時序圖:VSYNC和HSYNC都是低脈衝
    // s5pv210芯片手冊(p1207) 時序圖:VSYNC和HSYNC都是高脈衝有效,所以需要反轉
    VIDCON1 |= 1<<5 | 1<<6;

    // 設置時序
    VIDTCON0 = VBPD<<16 | VFPD<<8 | VSPW<<0;
    VIDTCON1 = HBPD<<16 | HFPD<<8 | HSPW<<0;
    // 設置長寬(物理屏幕)
    VIDTCON2 = (LINEVAL << 11) | (HOZVAL << 0);

    // 設置window0
    // bit[0]:使能
    // bit[2~5]:24bpp(RGB888)
    WINCON0 |= 1<<0;
    WINCON0 &= ~(0xf << 2);
    WINCON0 |= (0xB<<2) | (1<<15);

#define LeftTopX     0
#define LeftTopY     0
#define RightBotX   799
#define RightBotY   479

    // 設置window0的上下左右
    // 設置的是顯存空間的大小
    VIDOSD0A = (LeftTopX<<11) | (LeftTopY << 0);
    VIDOSD0B = (RightBotX<<11) | (RightBotY << 0);
    VIDOSD0C = (LINEVAL + 1) * (HOZVAL + 1);


    // 設置fb的地址
    VIDW00ADD0B0 = FB_ADDR;
    VIDW00ADD1B0 = (((HOZVAL + 1)*4 + 0) * (LINEVAL + 1)) & (0xffffff);

    // 使能channel 0傳輸數據
    SHADOWCON = 0x1;

代碼解析:將顯存地址轉化爲(u32類型)的指針,指針加上像素點所在的位置再把顏色賦值

**注意區別:因爲不乘4 的原因是

內存指針(佔4個內存)+1 是4位佔4個char(一個像素點用RGB+一個空內存存儲的)也就是內存地址和指針的表示方法不同**

u32 *pfb = (u32 *)FB_ADDR;
// 在像素點(x, y)處填充爲color顏色
static inline void lcd_draw_pixel(u32 x, u32 y, u32 color)
{
    *(pfb + COL * y + x) = color;
}#或者
static inline void lcd_draw_pixel(u32 x, u32 y, u32 color)
{
    *(0x23000000 + (COL * y + x)*4) = color;
}

屏幕的幾種玩法:

1.畫橫線,豎線,斜線

解析:把起始點和終點座標確定,把這個線上的像素點顯示,其他位背景色

2.畫圓並填充顏色
3.畫出英文字符

解析:找出ascill碼錶對應的ascill的值,data[count/8]的值是二維數組的內部的第count/8個第一個元素,

// 在座標(i, j)這個像素處判斷是0還是1,如果是1寫color;如果是0直接跳過
                if (data[count/8] & (1<<(count%8)))
                    lcd_draw_pixel(i, j, color);
4.顯示圖片(目前只會:必須是1024*600的像素)

解析:

1.使用Imag2LCD工具把每個圖像轉化成RGB三原色的值組成的數組

注意:Image2LCD工具必須關閉播放器,不然保存會閃退)。

2.由於程序的空間超過16kb,所以採用SD卡,先初始化BL1,再用BL2

3.老師的代碼BL1缺少clock.c文件需要添加(添加這個文件引起Makefile和start.S需要做相應的改動),添加makefile中main.o 和lcd_init.o,添加製作出來的圖片數組聲明,更改頻率以解決閃的問題,將數值4改成3
4.更改顯示圖片的函數位製作出來的圖片數組
5.更改SD 扇區 位3MB
#define SD_BLOCK_CNT (3*2048)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章