前言
LCD屏在嵌入式中是应用比较广泛的,很多电子产品都是需要用到它来进行人机交互,那么工作中我们就少不了要对lcd进行软件驱动和调试。调试LCD需要掌握的学问有很多,没有一定的调试经验就很难对问题进行分析并解决。
博文推荐
LCD屏接口与模式详解:干货超多
1.查阅屏驱数据手册
下面均以st7789的屏驱为例来作说明。
1.1 获取屏基本信息
首先,拿到一块需要调试的屏,我们需要先查阅它的datasheet,获取屏的基本信息。
如下图所示,我们可以直接获取到
显示分辨率为240*RGB(H)*320(V),是个竖屏;
帧内存大小为240 x 320 x 18-bit=1,382,400 bits;
像素数据的数据格式可以是RGB444、RGB565 和 RGB666;
屏接口模式有MCU、RGB、SPI接口等;
屏VGH、VGL等的电压范围(初始化需配置)。
这些都是我们需要知道的,确定LCD显示器的型号和参数,还有其他一些特性可以简单过一遍。
1.2 查阅初始化命令及数据参数
在datasheet中可以查看到初始化中配置屏驱相应寄存器的命令和数据参数,调试过程中改的最多的就是这些,需要去熟悉,通常这部分有不懂的地方可以找屏厂fae支持。
1.3 配置屏寄存器
如下图所示,
RST为屏的复位信号接口;
CS为片选信号;
SCL、SDA分别为时钟线和数据线。
通常对屏寄存器的配置接口为SPI或者I2C接口协议,这里以SPI接口为例,如果主控没有spi功能的pin引脚,可以任意引出3个gpio口,将其模拟SPI协议输出,分别模拟cs、scl和sda。
驱动部分软件驱动代码如下,这里使用的是gpio模拟spi协议。
static void lcd_gpio_spi_config_write(unsigned char bit_9,unsigned char cmd)
{
int i=0;
unsigned char cmd_val = 0;
gpio_spi_disable_cs();//cs
usleep(10);
gpio_spi_init_clk();//sck
gpio_spi_enable_cs();
usleep(2);
if(st7789v2dev.spi_is_9bit == 1)
{
gpio_spi_set_mosi(bit_9);//sda dat=0
usleep(3);
gpio_spi_generate_clk();
}
for(i=8;i>0;i--){
cmd_val = (cmd>>(i-1))&0x1;
gpio_spi_set_mosi(cmd_val);
usleep(2);
gpio_spi_generate_clk();
}
usleep(2);
gpio_spi_disable_cs();
gpio_spi_set_mosi(0);
usleep(10);
}
void st7789_init()
{
......
......
st7789v2_write_command(0x2B);// 分辨率设置
st7789v2_write_data(0x00);
st7789v2_write_data(0x00);
st7789v2_write_data(0x01);
st7789v2_write_data(0x3F);
st7789v2_write_command(0x2A);//分辨率设置
st7789v2_write_data(0x00);
st7789v2_write_data(0x00);
st7789v2_write_data(0x00);
st7789v2_write_data(0xEF);
st7789v2_write_command(0x21); //反色
st7789v2_write_command(0x29); //开显示
}
1.4 模式Timing参数设置
在HV模式中,通常我们还需要去设置它的行、场信号的前后延、像素时钟等参数。
如下图所示,Data bus中有部分数据是Invaild无效的数据,所以配置Timing前后沿的作用就是避开这些无效数据,配置参数值可以参考datasheet中给的参考值设定。
每个平台的配置方法都有些差异,示例参考代码:
output-clock = <9>;
h-total-len = <314>;
v-total-len = <348>;
h-active-len = <240>;
v-active-len = <320>;
h-front-len = <18>;
h-sync-len = <46>;
h-back-len = <10>;
v-front-len = <8>;
v-sync-len = <10>;
v-back-len = <10>;
/* bool type, 0 or 1*/
h-sync-level = <0>;
/* bool type, 0 or 1*/
v-sync-level = <0>;
active-polarity = <1>;
1.5 配置GPIO
最后我们需要将使用到的gpio口配置成相对应的功能,如rgb数据口,根据查看主控端数据手册,将相应gpio配置为rgb功能口。
如果使用的是linux框架,可以在dts上进行配置,如:
rgb {
pinmux-active = <
PINPAD_T01 PINMUX_T01_PRGB_R2
PINPAD_T02 PINMUX_T02_PRGB_R3
PINPAD_T03 PINMUX_T03_PRGB_R4
PINPAD_T04 PINMUX_T04_PRGB_R5
PINPAD_T05 PINMUX_T05_PRGB_R6
PINPAD_T06 PINMUX_T06_PRGB_R7
PINPAD_T09 PINMUX_T09_PRGB_G2
PINPAD_T00 PINMUX_T00_PRGB_G3
PINPAD_T11 PINMUX_T11_PRGB_G4
PINPAD_T12 PINMUX_T12_PRGB_G5
PINPAD_T13 PINMUX_T13_PRGB_G6
PINPAD_T14 PINMUX_T14_PRGB_G7
PINPAD_L01 PINMUX_L01_PRGB_B2
PINPAD_L02 PINMUX_L02_PRGB_B3
PINPAD_L03 PINMUX_L03_PRGB_B4
PINPAD_L04 PINMUX_L04_PRGB_B5
PINPAD_L05 PINMUX_L05_PRGB_B6
PINPAD_L06 PINMUX_L06_PRGB_B7
PINPAD_L07 PINMUX_L07_PRGB_CLK
PINPAD_L08 PINMUX_L08_PRGB_HSYN
PINPAD_L09 PINMUX_L09_PRGB_VSYNC
PINPAD_L10 PINMUX_L10_PRGB_DE>;
status = "okay";
};
2. LCD屏调试
2.1 屏不显示
1.首先确定硬件连线是否有问题,屏本身是否排线问题是坏的,把硬件问题排除完后,那剩下的只能是软件驱动的问题了;
2.用万用表测量屏电压、VGH、VGL等电压范围是否正常,不正常的话在初始化中根据相应的命令去配置电压值;
3.初始化配置寄存器是否有配置进去,这个可以使用逻辑分析仪看CS、CLK、SDA的数据是否正常;
4.如果是HV模式,行、场信号的极性配置不对也可以造成不显示,或异常。
2.2 屏显示异常
2.2.1 闪屏
可能的原因有LCD刷新频率过低、LCD刷新时序不稳定、LCD刷新数据不同步等。
可以有提高刷新频率(加大像素时钟输出)或降低分辨率、优化刷新时序或使用同步信号、使用双缓冲或DMA传输等。
2.2.2 花屏
可能的原因有LCD数据线干扰、LCD数据信号错误、LCD数据缓冲区溢出等。
可以使用屏蔽线或抗干扰措施、校验数据信号或纠正错误、增加数据缓冲区或清空缓冲区;
有时候颜色显示不正常,也可能是屏驱给反色了,可以去配置寄存器。
总结
总之,调屏我们需要掌握基本的驱动流程,如果遇到问题就一步步排除可能的原因,其它有很多细节点,是需要去积累经验的,调试多了自然就懂了。
如果本文理解上有不对的地方,欢迎指出,共同进步!!!