LCD 移植的那些坑-LCD屏幕配置常见的问题解决方案

在使用我们的开发板过程中,关于LCD屏幕配置有一些常见的问题

 

问题1,如何修改开机默认的屏幕尺寸?

全平台都可以通过uboot的选择菜单来选择默认的显示,对应配置方式可以参阅对应平台的应用手册。

i.MX6DL/i.MX6Q系列uboot已开源,可以通过直接修改uboot源码文件include/configs/mx6sabre_common.h(参考linux4.1.15内核版本)

 

如果是客户自己移植屏幕,可能需要修改uboot源码arch/arm/i.MX-common/video.c文件。修改默认的屏幕配置 setenv("pannel", "SEIKO-WXGA");(参考linux4.1.15内核版本)

 

 

问题2,如何自己移植LCD屏幕?

可以参考i.MX6x平台应用笔记中【8.0寸LCD屏移植笔记.pdf】一章。

lvds屏幕可参考【LVDS屏幕移植应用笔记 .pdf】

 

问题3,移植LCD屏幕,uboot显示logo不正常?

参考i.MX6Q linux4.1.15内核版本,在uboot源码board/freescale/mx6sabresd/mx6sabresd.c文件内默认的LCD 800x480的配置如下。在移植屏幕可以参考此结构体添加新屏幕的参数,参考【问题1】解决办法选择uboot默认屏幕。

 

lvds屏可以直接修改下图中的设置参数。

 

问题4,uboot显示正常,kernel起来后显示不正常?

这个可以通过 cat /proc/cmdline命令来查看uboot传递给内核的参数是不是正确。再参考【问题1】方法修改。(参考i.MX6Q启动参数)

 

到内核驱动文件drivers/video/fbdev/mxc/mxc_LCDif.c中微调对应的LCD屏幕配置参数.

 

lvds对应的内核驱动文件在drivers/video/fbdev/mxc/ldb.c.

 

在linux4.1.15内核版本在可能要在设备树修改默认的fb0输出以及LCD的配置.

 

问题5,LCD移植屏幕不亮?

LCD移植屏幕不亮的原因有很多,大部分的LCD屏幕背光为pwm控制,可以搜索linux Backlight部分,这里不做太多阐述。


问题6,LCD的参数怎么设置,怎么计算?

下面阐述一下LCD参数配置一些知识 

LCD的一些原理

数字视频的概念来自于模拟视频,在模拟视频中有像素,扫描显示方式,帧,前肩,后肩,消影等参数。

在模拟视频中像素(pixel)为图像中的最小的控制单位,整个图像是有许多的像素点构成。

电子枪控制器控制电子枪从屏幕的左上方,从左到右按照像素单元依次打印出图像,到行尾再返回下一行开头从新开始从左到右打印本行像素,直到屏幕最右下方最后一个像素点。然后再返回屏幕的左上角从新打印下一帧图像。

扫描枪就像打印机一样走“之”字路线。打完一行返回重新打印下一行。那么从一行到新的一行的运动时间在模拟视频中叫水平消影(HBlank).

从右下方最后一个像素点到最左上方的第一个像素点,即从一帧数据切换到另一帧数据的时间叫做垂直消影(VBlank).

在数字视频中保留了上述的这些概念。整个LCD的显示典型显示时序参考下图:

 

像素(pixel):整个显示图像是由一个个的像素组成的。

时钟速率(VCLK/LCD_CLK):视频硬件在显示器上绘制像素的速率, 一个 CLK 时钟完成一个像素点的显示。

垂直同步信号(VSYNC): 让LCD控制器知道下面要开始新的一帧图像

水平同步信号(HSYNC):让LCD控制器知道下面要开始新的一行像素.

数据使能(DE), 在数据使能区是有效的数据

VBP(Vertical back porch): 垂直同步信号的后肩,表示一帧图像开始时,垂直同步信号以后的无效行数。

VFP(Vertical front porch): 垂直同步信号的前肩, 表示一帧图像结束后,垂直同步信号以前的无效行数。

HBP(Horizontal back porch): 水平同步信号的后肩,表示从水平同步信号开始到一行的有效数据开始之前的VCLK的个数。

HFP(Horizontal front proch): 水平同步信号的前肩,表示从一行的有效数据结束到下一个水平信号开始之间的VCLK的个数。

要使得VSYNC和HSYNC信号有效,需要其电平保持一定的时间,这段时间被分别称为:HSPW(水平同步信号脉宽), VSPW(垂直同步信号脉宽).

 

LCD手册的时序图(参考我们目前使用的7寸LCD显示屏):

蓝色:水平信号相关部分标注

红色:垂直信号相关部分标注

 

内核对LCD的描述

在linux 内核中, 在include/linux/fb.h文件中定义的fb_videomode结构体对LCD进行描述。

 

下图为linux的结构体的示意图,和结构体属性一一对应:

蓝色:水平信号相关部分标注

红色:垂直信号相关部分标注

 

解释说明

内核对LCD的解释是按照LCD的图像为中心(二维面), 而手册上是按照LCD的时序(一维线性)来解释。二者解释的是相同的东西。

对应关系分别为:

LCD信号

对应LCD手册

对应LCD结构体

VCLK/LCD_CLK

DCLK(dotclock)


DE

DE




Refresh(刷新率)



Pixclock(计算见下文)

HSYNC

HS



thd

xres

HSPW

thpw

hsync_len

HBP

thb

left_margin

HFP

thfp

right_margin

VSYNC

VS



tvd

yres

VSPW

twpw

vsync_len

VBP

tvb

upper_margin

VFP

tvfp

lower_margin




参数计算

参考我们目前使用的7LCD显示屏:

LCD驱动中的参数,左边为实际的参数,右边为结构体定义

蓝色:水平信号相关部分标注 红色:垂直信号相关部分标注

 

7寸LCD显示屏手册:

 

对应值

 

linux结构体名称

linux结构体数值

LCD手册名称

LCD手册数值

refresh

57



xres

800

thd

800

yres

480

tvd

480

pixclock

37037



left_margin

40

thb

46

right_margin

60

thfp

<16 - 354>

upper_margin

10

tvb

23

lower_margin

10

tvfp

<7 - 147 >

hsync_len

20

thpw

<1 - 40>

vsyn_len

10

twpw

<7 - 147>





计算pixclock像素时钟和帧率

   , 其中dotclock是视频硬件在显示器上绘制像素的速率。

根据注释内容 dotclock为 27MHz. 所以

pixclock = 1 / (27E6) = 3.7037037037037036e-08, 取整为37037 皮秒

帧率的计算:

帧率=dotclock / ((xres+left_margin+right_margin+hsync)*(yres+upper_margin+low_margin+vsync))

=  (27E6)/( (40 + 800 + 60 + 20) (10 + 480 + 10 + 10))

= 57.54475703324808, 取整为 57Hz。

xres和yres已经由硬件固定,一般屏幕的刷新率一般为60Hz,而高于刷新率的帧数都是无效帧数。所以可以根据公式调整其他参数以调整LCD帧率,使其尽量接近60fps. 如果数值设置偏差的话,可能会造成屏幕沙点,抖动现象。