正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-21.5讲 LCD(RGB)驱动读取屏幕ID及IO初始化

前言:

本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。

引用:

正点原子IMX6U仓库 (GuangzhouXingyi) - Gitee.com

《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.2.pdf》

正点原子资料下载中心 — 正点原子资料下载中心 1.0.0 文档

正文:

本文是 “正点原子[第二期]Linux之ARM(MX6U)裸机篇--第21 讲” 的读书笔记。第21讲主要是介绍I.MX6U处理器的LCD液晶显示屏驱动的裸机开发,本节使用的是正点原子I.MX6U ALPHA/Mini 开发板配套的4.7英寸或7英寸 RGBLCD (RGB接口的LCD液晶显示屏)。本节将参考正点原子的视频教程第21讲和配套的正点原子开发指南文档进行学习。

正点原子第21讲I.MX6U ARM裸机RGBLCD液晶显示屏的视频教程比较长一共有8节视频教程,相对来说通过I.MX6U ARM 裸机寄存器来驱动RGBLCD涉及到的寄存器比较多,相对来说还是比较复杂的。

本节是正点原子第21.5讲RGBLCD视频教程,读取屏幕ID。

注意:

只有正点原子自己提供的屏幕才有其自定义的屏幕ID,正点原子定义屏幕ID的原因是正点原子开发板提供了多种的LCD屏幕尺寸,例如4.3英寸屏,7英寸屏,10英寸屏等等,所以需要屏幕ID来区分正点原子自家的集中不同尺寸型号的LCD液晶屏;在适配其他家的LCD显示屏可能不需要读取屏幕ID。

0. 概述

正点原子开发板提供了多种的LCD屏幕尺寸,例如4.3英寸屏,7英寸屏,10英寸屏等,所以在LCD裸机开发驱动实验中需要首先读取到LCD液晶屏的面板ID,通过面板ID来获取到当前使用的LCD显示屏的尺寸和LCD显示屏分辨率。

1. 硬件原理

正点原子的LCD(RGB)液晶显示屏上有几个电阻,通过GPIO读取到电阻的阻值来区分屏幕的“面板ID”型号,通过型号进而可以指导LCD液晶屏的尺寸和分辨率。

正点原子I.MX6U ALPHA/Mini 开发板底板电路原理图如下所示:

LCD_DATA15, LCD_DATA23, LCD_DATA7 ,这3个I.MX6U 连接到处理器引脚,I.MX6U处理器引脚和LCD_DATA15S, LCD_DATA23S, LCD_DATA7S 之间通过 "SGM3157" 来开关器件连接起来,只有 "LCD_VSYSNC" 引脚给出高电平是  "SGM3157" 开关才导通,所以在读取正点原子屏幕ID之前,需要先将 "LCD_VSYSNC" 引脚输出为高电平(配置为GPIO output输出模式),然后通过I.MX6U处理器引脚 “LCD_DATA15, LCD_DATA23, LCD_DATA7” 读取电平值(配置为GPIO input输入模式)来确定屏幕ID。

总结一下,读取正点原子LCD液晶屏ID的步骤如下:

  1. LCD_VSYNC 引脚配置为GPIO输出模式(OUTPUT)并且输出高电平。
    LCD_VSYNC高电平,为SGM_CTL高电平,SGM_CTL为高电平打开3个 SGM3157 电路开关,SGM3157开关打开之后 LCD_DATA15, LCD_DATA23, LCD_DATA7 才和 LCD_DATA15S, LCD_DATA23S, LCD_DATA7S 连接起来。
  2.  配置 LCD_DATA15, LCD_DATA23, LCD_DATA7 三个引脚为GPIO输入模式(INPUT),处理器通过读取三个GPIO引脚的电平高低来获取正点原子屏幕ID。

2. LCD接口寄存器

LCD_VSYNC IO接口寄存器如下图所示,可以将其复用为 GPIO3_IO03 的 GPIO Output 模式并且输出高电平。

LCD_DATA7 IO接口寄存器如下,可以将其复用为 GPIO3_IO12 的 GPIO Intput 模式并且读取gpio引脚上的输入是高电平还是低电平。

3. LCD 屏幕ID读取源码编写

读取正点原子LCD屏幕ID。

bsp/bsp_lcd.h

#ifndef __BSP_LCD_H__
#define __BSP_LCD_H__

#include "imx6u.h"

/* 屏幕ID */
#define ATK4342		0X4342	/* 4.3寸480*272 	*/
#define ATK4384		0X4384	/* 4.3寸800*480 	*/
#define ATK7084		0X7084	/* 7寸800*480 		*/
#define ATK7016		0X7016	/* 7寸1024*600 		*/
#define ATK1018		0X1018	/* 10.1寸1280*800 	*/
#define ATKVGA		0xff00 /* VGA */


unsigned short lcd_read_panelId(void);
void lcd_init(void);
void lcd_gpio_init(void);

#endif

bsp/bsp_lcd.c 源码

#include "bsp_lcd.h"
#include "bsp_gpio.h"
#include "stdio.h"


/*
 * @description 	: LCD初始化
 * @param  			: 无
 * @return 			: 无
 */
void lcd_init(void)
{
	unsigned short panelId = 0;

	panelId = lcd_read_panelId();
	printf("LCD panelId=0X%X\r\n", panelId);
}

/*
 * @description 	: 读取正点原子LCD液晶屏面板Id
 *  	LCD_DATA23=R7(M0);LCD_DATA15=G7(M1);LCD_DATA07=B7(M2);
 * 		M2:M1:M0
 *		0 :0 :0	//4.3寸480*272 RGB屏,ID=0X4342
 *		0 :0 :1	//7寸800*480 RGB屏,ID=0X7084
 *	 	0 :1 :0	//7寸1024*600 RGB屏,ID=0X7016
 *  	1 :0 :1	//10.1寸1280*800,RGB屏,ID=0X1018
 *		1 :0 :0	//4.3寸800*480 RGB屏,ID=0X4384
 * @param  			: 无
 * @return 			: 正点原子LCD液晶屏面板id
 * 
 */
unsigned short lcd_read_panelId(void)
{
	unsigned short idx = 0;
	unsigned short panelId = 0;
	gpio_pin_config_t led_config;

	/* LCD_VSYNC 复用为GPIO3_IO03 输出模式 */
	IOMUXC_SetPinMux(IOMUXC_LCD_VSYNC_GPIO3_IO03, 0);			/* IO复用 */
	IOMUXC_SetPinConfig(IOMUXC_LCD_VSYNC_GPIO3_IO03, 0x10B0);	/* IO电气特性 */

	led_config.directioin = kGPIO_DigitalOutput;		
	led_config.outputLogic = 1;							
	//gpio_init(GPIO5, 1, &led_config);
	gpio_init(GPIO3, 3, &led_config);


	/* M0,M1,M2 IO 复用 */
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA23_GPIO3_IO28, 0);			/* M0(R7)  LCD_DATA23 GPIO输入模式 */
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA15_GPIO3_IO20, 0);			/* M1(G7) LCD_DATA15 GPIO输入模式 */
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA07_GPIO3_IO12, 0);			/* M2(B7) LCD_DATA07 GPIO输入模式 */

	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA23_GPIO3_IO28, 0xF080);	/* M0(R7) IO电气特性 */
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA15_GPIO3_IO20, 0xF080);	/* M1(G7) IO电气特性 */
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA07_GPIO3_IO12, 0xF080);	/* M2(B7) IO电气特性 */

	led_config.directioin = kGPIO_DigitalInput;								
	gpio_init(GPIO3, 28, &led_config);							/* M0 */
	gpio_init(GPIO3, 20, &led_config);							/* M1 */
	gpio_init(GPIO3, 12, &led_config);							/* M2 */


	idx = gpio_pinread(GPIO3, 28);
	idx |= gpio_pinread(GPIO3, 20) << 1;
	idx |= gpio_pinread(GPIO3, 12) << 2;

	printf("idx=%d\r\n", idx);

	switch(idx)
	{
		case 0:
			panelId = ATK4342;
			break;
		case 1:
			panelId = ATK7084;
			break;
		case 2:
			panelId = ATK7016;
			break;
		case 4:
			panelId = ATK4384;
			break;
		case 5:
			panelId = ATK1018;
			break;
	}

	return panelId;
}

4. 初始化LCD IO

初始化LCD IO接口,包括LCD_DATA0~LCD_DATA23,以及LCD_CLK, LCD_ENABLE, LCD_VSYNC, LCD_HSYNC 这些引脚的IO口复用和IO口电气特性。

以及LCD屏幕的背光 LCD_PWM 引脚的IO,从正点原子I.MX6ULL ALPHA/Mini 开发板电路原理图可以看到LCD液晶屏使用的是 GPIO1_IO08 引脚。

4.1 LCD屏幕IO口初始化源码编写

源码中 LCD_DATA0~LCD_DATA23, LCD_CLK, LCD_ENABLE, LCD_VSYNC, LCD_HYSNC 引脚的IO初始化,已经LCD背光 LCD_PWM 的 IO初始化源码如下。

bsp/bsp_lcd.c

void lcd_gpio_init(void)
{
	/* LCD_DATA IO 复用 */
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA00_LCDIF_DATA00, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA01_LCDIF_DATA01, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA02_LCDIF_DATA02, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA03_LCDIF_DATA03, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA04_LCDIF_DATA04, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA05_LCDIF_DATA05, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA06_LCDIF_DATA06, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA07_LCDIF_DATA07, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA08_LCDIF_DATA08, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA09_LCDIF_DATA09, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA10_LCDIF_DATA10, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA11_LCDIF_DATA11, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA12_LCDIF_DATA12, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA13_LCDIF_DATA13, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA14_LCDIF_DATA14, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA15_LCDIF_DATA15, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA16_LCDIF_DATA16, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA17_LCDIF_DATA17, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA18_LCDIF_DATA18, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA19_LCDIF_DATA19, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA20_LCDIF_DATA20, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA21_LCDIF_DATA21, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA22_LCDIF_DATA22, 0);
	IOMUXC_SetPinMux(IOMUXC_LCD_DATA23_LCDIF_DATA23, 0);

	IOMUXC_SetPinMux(IOMUXC_LCD_CLK_LCDIF_CLK, 0);			/* LCD_CLK */
	IOMUXC_SetPinMux(IOMUXC_LCD_ENABLE_LCDIF_ENABLE, 0);	/* LCD_ENABLE */
	IOMUXC_SetPinMux(IOMUXC_LCD_HSYNC_LCDIF_HSYNC, 0);		/* LCD_HSYNC */
	IOMUXC_SetPinMux(IOMUXC_LCD_VSYNC_LCDIF_VSYNC, 0);		/* LCD_VSYNC */


	/* LCD_DATA IO 电气属性 */
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA00_LCDIF_DATA00, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA01_LCDIF_DATA01, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA02_LCDIF_DATA02, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA03_LCDIF_DATA03, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA04_LCDIF_DATA04, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA05_LCDIF_DATA05, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA06_LCDIF_DATA06, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA07_LCDIF_DATA07, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA08_LCDIF_DATA08, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA09_LCDIF_DATA09, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA10_LCDIF_DATA10, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA11_LCDIF_DATA11, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA12_LCDIF_DATA12, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA13_LCDIF_DATA13, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA14_LCDIF_DATA14, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA15_LCDIF_DATA15, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA16_LCDIF_DATA16, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA17_LCDIF_DATA17, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA18_LCDIF_DATA18, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA19_LCDIF_DATA19, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA20_LCDIF_DATA20, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA21_LCDIF_DATA21, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA22_LCDIF_DATA22, 0xB9);
	IOMUXC_SetPinConfig(IOMUXC_LCD_DATA23_LCDIF_DATA23, 0xB9);

	IOMUXC_SetPinConfig(IOMUXC_LCD_CLK_LCDIF_CLK, 0xB9);			/* LCD_CLK */
	IOMUXC_SetPinConfig(IOMUXC_LCD_ENABLE_LCDIF_ENABLE, 0xB9);	/* LCD_ENABLE */
	IOMUXC_SetPinConfig(IOMUXC_LCD_HSYNC_LCDIF_HSYNC, 0xB9);		/* LCD_HSYNC */
	IOMUXC_SetPinConfig(IOMUXC_LCD_VSYNC_LCDIF_VSYNC, 0xB9);		/* LCD_VSYNC */

	/* LCD背光点亮,背光GPIO初始化, LCD_PWM (Pulse Width Modulatization) */
	IOMUXC_SetPinMux(IOMUXC_GPIO1_IO08_GPIO1_IO08, 0);
	IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO08_GPIO1_IO08, 0x10B0);

	gpio_pin_config_t led_config;
	led_config.directioin = kGPIO_DigitalOutput;		
	led_config.outputLogic = 1;										/* 默认输出高电平 */
	gpio_init(GPIO1, 8, &led_config);

}

电气特性设置为 0x00B9

0x00B9 (hex)

0000 0000 1011 1001 (Binary)

 

5. 编译烧写SD卡验证实验结果

译修改主频后源码烧录SD卡验证本节的 LCD(RGB)液晶屏面板实验,读取ID值读取。预期烧录SD卡后正点原子I.MX6ULL ALPHA/Mini 开发板后,UART串口可以在串口中可以打印出读取到的LCD(RGB)液晶名的面板ID。

在本实验中,我使用的是I.MX6ULL Mini 开发板搭配的是4.3英寸 800*480 分辨率的LCD(RGB接口)液晶屏,烧录SD卡上电之后出口打印出来的 panelID=0x4384 和我开发板实际情况是相符的。

6. 总结和实验遇到的问题记录

6.1 问题1:烧录SD之后上电启动后,正点原子4.3英寸LCD屏的M0,M1,M2 三个GPIO口读取到的都是低电平,屏幕PanelID判断错误。

错误原因是如下第43行这里,初始化gpio_init()的时候将gpio的组别和gpio pin 引脚号写错了。应该根据实际使用的gpio引脚传递正确的gpio组别和gpio pin 引脚号来初始化对应的gpio。

这里因为写错了gpio组别和gpio pin 引脚号,LCD_VSYNC 信号实际上没有输出高电平,3个 SGM3157 开关都没有打开,从电路原理图可以看出此时读取到的M0,M1,M2都是低电平。

6.2 GPIO输出引脚的 IO 电气特性应该配置为 "0xF080"

M0,M1,M2 屏幕PanelId所使用的 LCD_DATA23, LCD_DATA15, LCD_DATA07 作为 GPIO输入Input模式的时候,应该配置IO口的电气特性值为 0xF080。

7. 结束

本章至此结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值