本文参考朱友鹏老师嵌入式核心课程,仅作为记录以及笔记
LCD:(liquid Crystal Display)也叫作液晶显示
液晶是一种材料,该材料具有一种特点,可以在电信号的驱动下液晶分子进行旋转,旋转是会影响透光性,因此我们可以在整个液晶面板的后面用白光照射(背光),可以通过不同的电信号让液晶分子进行选择性的透光,此时在液晶面板看大的各种各样的演的,这也就是LCD显示。
LCD属于被动发光,有的显示器如LED显示器,CRT显示器等,自己本身会发光,成为主动发光,LCD不自己发光,而是靠背光来发光的。
LCD的接口技术:
从技术角度来讲的话本质都是TTL信号,+5V表示逻辑1,0V表示逻辑0,这种电平信号就叫做TTL信号。
芯片控制LCD的硬件接口就是TTL电平,芯片操作IO端口的电平实际上就是TTL信号,因此SOC(芯片)的接口是直接可以跟LCD相连接的。一般LCD屏幕显示类的在嵌入式种都用软排线链接,距离比较短。因为TTL信号的缺陷就在传输距离短,如果显示器离得太远,就不能用SOC出来的排线直接跟LCD相连,可以使用SOC-->VGA--->LCD。
LCD如何显示图像
1.像素:像素就是组成图像的最基本元素,或者说显示中可以被控制的最小单位,整个图像就是被若干个像素点构成的。
2.扫描:扫描是一个动作,就是依次将颜色数值放入屏幕中所有像素点的过程。
3.驱动器和控制器:LCD驱动器一般和LCD显示面板集成在一起,面板只负责里面液晶分子旋转透光,面板需要一定的模拟电信号来控制液晶分子,LCD驱动器芯片负责给米面板提供这些模拟的电信号,驱动器的控制信号来源于自己的数字接口也就是自己的TTL接口。;LCD控制器一般集成在SOC内部,主要负责数字接口向外部的LCD驱动器提供控制像素的数字信号,LCD控制器的关键在于时序,它必须按照两方定好的时序跟LCD驱动器通讯,LCD控制器受SOC控制,SOC会从内存中拿取像素数据给LCD驱动器并最终转换成显示的图像。
4.显存:SOC在内存中挑选一段内存,然后通过配置LCD控制器和这一段内存连接起来构成一定的映射关系,一旦这个映射关系确认之后,LCD控制器就会自动从现存中拿取像素信息去显示,不需要SOC参与,要显示什么的话CPU只需要往显存里放就可以了。
LCD为了向前兼容出现的六个时序参数
HSPW:水平同步信号脉宽 horizontal sync pulse width
HBPD:水平同步信号前肩 horizontal back porch
HFPD:水平同步信号后肩 horizontal front porch
VSPW:垂直同步信号脉宽 vertical sync pulse width
VBPD:垂直同步信号前肩 vertical back porch
VFPD:垂直同步信号后肩 vertical front porch
LCD显示的主要相关概念:
1.像素(pitch);整个图像就是一个个的像素点构成的。一个像素就是一个显示点。
2.像素间距(pitch):pitch是连续两个像素点之间的距离,一般的像素是方形的。所以横向的pitch和纵向的pitch都是一样的,但是也有不一样的显示器。
3.分辨率(resolution):整个屏幕的横向和纵向的像素个数就是分辨率,屏幕的尺寸和分辨率的大小没有关系,同样屏幕大小的话,分辨率越高越清晰。
4.像素深度(bits per pixel, 简称bpp):一个像素在计算机中由多少字节构成,计算机中用二进制来表示一个像素的数据,用来表示一个像素的数据位越多。则这个像素的颜色质量更加丰富,分的更细,颜色深度就越深。一般的计算机中的颜色深度有:1位,8位,16位,24位,32位
有了这些关于LCD显示的基础概念之后再去做LCD的实验就容易很多了,代码就够中,首先去初始化SOC的LCD控制器的相关配置:LCD的数据线,使能引脚,以及上面讲到的六个时序参数,以及LCD屏幕的分辨率,像素深度,内存中给显存划分一段区域,之后再去刷新屏幕就可以了。
#define GPF0CON (*(volatile unsigned long *)0xE0200120)
#define GPF1CON (*(volatile unsigned long *)0xE0200140)
#define GPF2CON (*(volatile unsigned long *)0xE0200160)
#define GPF3CON (*(volatile unsigned long *)0xE0200180)#define GPD0CON (*(volatile unsigned long *)0xE02000A0)
#define GPD0DAT (*(volatile unsigned long *)0xE02000A4)#define CLK_SRC1 (*(volatile unsigned long *)0xe0100204)
#define CLK_DIV1 (*(volatile unsigned long *)0xe0100304)
#define DISPLAY_CONTROL (*(volatile unsigned long *)0xe0107008)#define VIDCON0 (*(volatile unsigned long *)0xF8000000)
#define VIDCON1 (*(volatile unsigned long *)0xF8000004)
#define VIDTCON2 (*(volatile unsigned long *)0xF8000018)
#define WINCON0 (*(volatile unsigned long *)0xF8000020)
#define WINCON2 (*(volatile unsigned long *)0xF8000028)
#define SHADOWCON (*(volatile unsigned long *)0xF8000034)
#define VIDOSD0A (*(volatile unsigned long *)0xF8000040)
#define VIDOSD0B (*(volatile unsigned long *)0xF8000044)
#define VIDOSD0C (*(volatile unsigned long *)0xF8000048)#define VIDW00ADD0B0 (*(volatile unsigned long *)0xF80000A0)
#define VIDW00ADD1B0 (*(volatile unsigned long *)0xF80000D0)#define VIDTCON0 (*(volatile unsigned long *)0xF8000010)
#define VIDTCON1 (*(volatile unsigned long *)0xF8000014)#define HSPW (40) // 1~40 DCLK
#define HBPD (10 - 1) // 46
#define HFPD (240 - 1) // 16 210 354
#define VSPW (20) // 1~20 DCLK
#define VBPD (10 - 1) // 23
#define VFPD (30 - 1) // 7 22 147// FB???
#define FB_ADDR (0x23000000)
#define ROW (600)
#define COL (1024)
#define HOZVAL (COL-1)
#define LINEVAL (ROW-1)#define XSIZE COL
#define YSIZE ROWu32 *pfb = (u32 *)FB_ADDR;// ???????????
#define BLUE 0x0000FF
#define RED 0xFF0000
#define GREEN 0x00FF00
#define WHITE 0xFFFFFF// ?????LCD
static void lcd_init(void)
{// ????????????LCD????GPF0CON = 0x22222222;GPF1CON = 0x22222222;GPF2CON = 0x22222222;GPF3CON = 0x22222222;// ????? GPD0_0??PWMTOUT0??GPD0CON &= ~(0xf<<0);GPD0CON |= (1<<0); // output modeGPD0DAT &= ~(1<<0); // output 0 to enable backlight// 10: RGB=FIMD I80=FIMD ITU=FIMDDISPLAY_CONTROL = 2<<0;// bit[26~28]:???RGB???// bit[18]:RGB ????// bit[2]:????????HCLK_DSYS=166MHzVIDCON0 &= ~( (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) = 33MVIDCON0 |= 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 1023
#define RightBotY 599// ????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;
}
以上为分辨率为1024*600分辨率的初始化部分。
static inline void lcd_draw_pixel(u32 x, u32 y, u32 color)
{*(pfb + COL * y + x) = color;
}static void lcd_draw_background(u32 color)
{u32 i, j;for (j=0; j<ROW; j++){for (i=0; i<COL; i++){lcd_draw_pixel(i, j, color);}}
}
上面为画一个像素点的函数和刷整个屏幕的函数,可以利用这两个函数来验证LCD的显示实验,之后再来扩充显示图片,文字之类的功能。