嵌入式linux驱动-LCD液晶屏驱动

这里写目录标题

  • LCD简介
    • 一些性能参数
    • eLCDIF 接口
  • linux下的LCD驱动
    • Framebuffer 设备
    • LCD 驱动介绍
  • LCD 驱动程序
    • LCD 屏幕 IO 配置
    • LCD 屏幕参数节点信息修改
    • LCD 屏幕背光节点信息
  • 设置 LCD 作为终端控制台

LCD简介

一些性能参数

  • 分辨率
    由一个一个的像素点组成,常有720P,
    1080P( 1920 * 1080 ),
    2K( 2560 * 1440 ),
    4K( 3840 * 2160 )。

    以下就是1080P,X=1920,Y=1080。
    嵌入式linux驱动-LCD液晶屏驱动_第1张图片

  • 像素格式
    一个像素点就相当于一个 RGB 小灯,通过控制 R、 G、 B 这三种颜色的亮度就可以显示出各种各样的色彩
    RGB888:8bit3=24bit
    ARGB8888:8bit
    4=32bit。(另外加了Alpha(透明)通道)

  • LCD 屏幕接口
    显示器上常见的 VGA、 HDMI、 DP 等,然而板子只支持RGB接口
    RGB接口
    嵌入式linux驱动-LCD液晶屏驱动_第2张图片
    嵌入式linux驱动-LCD液晶屏驱动_第3张图片
    两种模式
    DE 模式:R[7:0]、G[7:0]、B[7:0]、DE、VSYNC、PCLK 。
    HV 模式:R[7:0]、G[7:0]、B[7:0]、HSYNC、VSYNC、PCLK 。

  • LCD 时间参数
    HBP: HSYNC信号结束—>新的一行开始
    HFP:一行结束—>HSYNC信号产生
    VBP: VSYNC信号结束—>新的一帧图像开始
    VFP:一帧图像结束—>VSYNC信号产生

为啥会有一圈黑边儿呢?

HBP、 HFP、 VBP 和 VFP 导致了黑边。
因为 RGB LCD屏幕内部是有一个 IC 的,发送一行或者一帧数据给 IC, IC 是需要反应时间的。

嵌入式linux驱动-LCD液晶屏驱动_第4张图片

  • RGB LCD 屏幕时序

行显示时序:
嵌入式linux驱动-LCD液晶屏驱动_第5张图片

帧显示时序图:
嵌入式linux驱动-LCD液晶屏驱动_第6张图片

ATK-4342型号参数:(4.3 寸, 480*272)
嵌入式linux驱动-LCD液晶屏驱动_第7张图片

  • 像素时钟
    像素时钟就是 RGB LCD 的时钟信号。

  • 显存
    其本质就是显卡,但是RGB LCD 内部是没有内存的,所以就需要DDR3 中分出一段内存作为 RGB LCD 屏幕的显存。

eLCDIF 接口

eLCDIF 是 I.MX6U 自带的液晶屏幕接口,用于连接 RGB LCD 接口的屏幕, eLCDIF 接口特性如下:
①、支持 RGB LCD 的 DE 模式。
②、支持 VSYNC 模式以实现高速数据传输。
③、支持 ITU-R BT.656 格式的 4:2:2 的 YCbCr 数字视频,并且将其转换为模拟 TV 信号。
④、支持 8/16/18/24/32 位 LCD。

eLCDIF 支持三种接口: **MPU 接口、 VSYNC 接口和 DOTCLK 接口。**原子教程使用的是DOTCLK 接口。

配置寄存器步骤如下

  • 初始化 LCD 所使用的 IO
  • 设置 LCD 的像素时钟
  • 配置 eLCDIF 接口(eLCDIF接口控制器的各种寄存器
  • 编写 API 函数

所有都配置完成,在DDR中为LCD分了一块儿内存作为显存,直接操作这块儿内存就可以驱动LCD啦!!!

linux下的LCD驱动

Framebuffer 设备

裸机—可以随意的分配显存
Linux 系统—内存的管理很严格,显存是需要申请的

那么,该如何管理这个LCD设备呢?

fb机制:Framebuffer(帧缓冲),将系统中所有跟显示有关的硬件以及软件集合起来,虚拟出一个 fb 设备。

会生成一个名为/dev/fbX(X=0~n)的设备,应用程序通过访问/dev/fbX 这个设备就可以访问 LCD。

LCD 驱动介绍

linux内核中已经写好了关于Framebuffer的LCD驱动,我们主要是修改设备树。

关于Framebuffer的LCD驱动
fb_info结构体:包含了 Framebuffer 设备的完整属性和操作集合,定义在include/linux/fb.h

mxsfb_probe 函数主要内容

  • 申请 fb_info。
  • 初始化 fb_info 结构体中的各个成员变量。
  • 初始化 eLCDIF 控制器。
  • 使用 register_framebuffer 函数向 Linux 内核注册初始化好的 fb_info。

LCD 驱动程序

主要就是修改设备树。

LCD 屏幕 IO 配置

//RGB LCD 的 24 根数据线配置项
pinctrl_lcdif_dat: lcdifdatgrp {
	fsl,pins = <
		MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
		MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
		MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
		MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
		MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
		MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
		MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
		MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
		MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
		MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
		MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
		MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
		MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
		MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
		MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
		MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
		MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79
		MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79
		MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79
		MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79
		MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79
		MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79
		MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79
		MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79
	>;
};
//RGB LCD 的 4 根控制线配置项,包括 CLK、ENABLE、 VSYNC 和 HSYNC。
pinctrl_lcdif_ctrl: lcdifctrlgrp {
	fsl,pins = <
		MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
		MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
		MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
		MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
	>;
}
//LCD 背光 PWM 引脚配置项
pinctrl_pwm1: pwm1grp {
	fsl,pins = <
		MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
	>;
};

LCD 屏幕参数节点信息修改

&lcdif {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_lcdif_dat /* 使用到的 IO */
				&pinctrl_lcdif_ctrl
				//&pinctrl_lcdif_reset	//原子板子没用到
				>;
	display = <&display0>;
	status = "okay";
	
	display0: display { /* LCD 属性信息 */
		bits-per-pixel = <24>; /* 一个像素占用几个 bit */
		bus-width = <24>; /* 总线宽度 */
		
		display-timings {
			native-mode = <&timing0>; /* 时序信息 */
			timing0: timing0 {
				clock-frequency = <51200000>; /* LCD 像素时钟,单位 Hz */
				hactive = <480>; /* LCD X 轴像素个数 */
				vactive = <272>; /* LCD Y 轴像素个数 */
				hfront-porch = <8>; /* LCD hfp 参数 */
				hback-porch = <4>; /* LCD hbp 参数 */
				hsync-len = <41>; /* LCD hspw 参数 */
				vback-porch = <2>; /* LCD vbp 参数 */
				vfront-porch = <4>; /* LCD vfp 参数 */
				vsync-len = <10>; /* LCD vspw 参数 */
				hsync-active = <0>; /* hsync 数据线极性 */
				vsync-active = <0>; /* vsync 数据线极性 */
				de-active = <1>; /* de 数据线极性 */
				pixelclk-active = <0>; /* clk 数据线先极性 */
			};
		};
	};
};

LCD 屏幕背光节点信息

背光控制 IO 连接到了 I.MX6U 的 GPIO1_IO08 引脚

  • GPIO1_IO08 引脚配置imx6ull-alientek-emmc.dts
pinctrl_pwm1: pwm1grp {
	fsl,pins = <
		MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0
	>;
};
...
&pwm1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_pwm1>;
	status = "okay";
};
  • backlight 节点,将 LCD 背光和 PWM1_OUT连接起来。
backlight {
	compatible = "pwm-backlight";
	pwms = <&pwm1 0 5000000>;	//设置背光使用 pwm1, PWM 频率为 5KHz。
	brightness-levels = <0 4 8 16 32 64 128 255>;	//设置背 8 级背光(0~7),分别为 0、 4、 8、 16、 32、 64、 128、 255,
	//对应占空比为0%、 1.57%、 3.13%、 6.27%、 12.55%、 25.1%、 50.19%、 100%,
	//如果嫌少的话可以自行添加一些其他的背光等级值。
	
	default-brightness-level = <6>;	//设置默认背光等级为 6
	status = "okay";
};

设置 LCD 作为终端控制台

1、设置 uboot 中的 bootargs

setenv bootargs 
'console=tty1 	//设置 LCD 屏幕为控制台
console=ttymxc0,115200 	//设置串口也作为控制台
root=/dev/nfs rw 
nfsroot=192.168.1.250:/home/zxy/linux/nfs/rootfs
ip=192.168.1.251:192.168.1.250:192.168.1.1:255.255.255.0::eth0:off'

2、修改/etc/inittab 文件

开发板/etc/inittab 文件中加入一行

tty1::askfirst:-/bin/sh

嵌入式linux驱动-LCD液晶屏驱动_第8张图片

重启以后会显示下面一行语句,按下回车键使能当前终端,之前KEY 按键注册为回车键:

Please press Enter to activate this console.

背光调节
进入目录/sys/devices/platform/backlight/backlight/backlight

echo 7 > brightness	//设置屏幕亮度等级为 7

你可能感兴趣的:(原子笔记-设备树驱动)