嵌入式LCD软件驱动流程与调试

前言

        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。

SPI接口时序图

驱动部分软件驱动代码如下,这里使用的是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数据缓冲区溢出等。

可以使用屏蔽线或抗干扰措施、校验数据信号或纠正错误、增加数据缓冲区或清空缓冲区;

有时候颜色显示不正常,也可能是屏驱给反色了,可以去配置寄存器。

总结

总之,调屏我们需要掌握基本的驱动流程,如果遇到问题就一步步排除可能的原因,其它有很多细节点,是需要去积累经验的,调试多了自然就懂了。

如果本文理解上有不对的地方,欢迎指出,共同进步!!!

猜你喜欢

转载自blog.csdn.net/weixin_49576307/article/details/134691416