目录
一.背景

屏幕分辨率:横向像素点个数 * 纵向像素点个数( 800 * 480 )1920 * 10801080P2K 2560 * 1440
屏幕尺寸: inch " 英寸,左上角到右下角之间的距离 1" = 2.54cm6.22" 4.3"1920 * 1080分辨率相同,尺寸越小,图像显示效果越好尺寸相同,分辨率越高,图像显示效果越好
像素点颜色:RGB888 :每个像素点占 3 个字节 8bit 面板 1670 万色RGB565: 每个像素点占 2 个字节ARGB :每个像素点占 4 个字节RGB101010: 10bit 面板 10 亿色 贵 视频剪辑 8 抖 10bit
显存:专门存放图像数据的内存空间800 * 480 * 4 = 1.5M ( 512MB 0x80000000 - 0xA0000000 )显存: 0x89000000
像素时钟



二.实现
1.初始化
// 1. 设置lcd引脚复用功能
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_CLK_LCDIF_CLK, 0); // pclk
IOMUXC_SetPinMux(IOMUXC_LCD_HSYNC_LCDIF_HSYNC, 0); // HSYNC
IOMUXC_SetPinMux(IOMUXC_LCD_VSYNC_LCDIF_VSYNC, 0); // VSYNC
IOMUXC_SetPinMux(IOMUXC_LCD_ENABLE_LCDIF_ENABLE, 0); // DE
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO08_GPIO1_IO08, 0); // blt_pwm
为什么硬件叫 blt_pwm,软件却配成 GPIO?
之所以注释写着 blt_pwm,是因为在硬件原理图上,这个引脚确实连接到了 LCD 的背光控制电路。硬件工程师给它起名叫“背光 PWM”,是因为它最终要控制背光。但是,控制背光有两种常见做法:
-
硬件 PWM 控制(ALT0 模式):把引脚配置成
PWM1_OUT,让芯片内部的 PWM 模块输出连续方波,通过改变占空比来无级调节背光亮度(比如从 10% 调到 100%)。 -
软件 GPIO 控制(ALT5 模式,即老师的做法):把引脚配置成普通 GPIO。软件只能输出
0(低电平,背光灭)或1(高电平,背光亮)。-
如果只是需要开灯/关灯,配置成 GPIO 最简单。
-
如果想调节亮度但不想用硬件 PWM,可以在 Linux 驱动里写个定时器,让 GPIO 不断拉高拉低,模拟 PWM 波形(软件模拟 PWM)。
-
// 2. 设置lcd引脚电气属性
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_CLK_LCDIF_CLK, 0xB9);
IOMUXC_SetPinConfig(IOMUXC_LCD_HSYNC_LCDIF_HSYNC, 0xB9);
IOMUXC_SetPinConfig(IOMUXC_LCD_VSYNC_LCDIF_VSYNC, 0xB9);
IOMUXC_SetPinConfig(IOMUXC_LCD_ENABLE_LCDIF_ENABLE, 0xB9);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO08_GPIO1_IO08, 0xB9);
一共设置24个数据引脚(R,G,B各8个)
// 3. 配置pwm引脚
GPIO_Type_t t =
{
.direction = gpio_output,
.default_value = 1
};
gpio_init(GPIO1, 8, &t);
gpio_set_value(GPIO1, 8, 1);
2.配置时钟
要配置31MHZ时钟, 先通过倍频让PLL5输出1008MHZ,再通过两个预分频器除以4和8输出为31.5MHZ

可设置NUM为0,DENOM为1,DIV_SELECT为42即可将24MHZ倍频为1008MHZ

预分频器默认为1分频即可。

再通过CSDR2寄存器选通PLL5时钟且配置第一个分频因子为4,通过CBCMR配置第二个分频因子为8。

CCM_ANALOG->PLL_VIDEO
是 i.MX6UL 芯片内部视频锁相环(Video PLL)的主控制寄存器

// lcd时钟初始化
void lcd_clock_init(void)
{
// BYPASS
CCM_ANALOG->PLL_VIDEO |= (1 << 16);
// Powerdown PLL
CCM_ANALOG->PLL_VIDEO |= (1 << 12);//写1关闭
CCM_ANALOG->PLL_VIDEO_NUM = 0;
CCM_ANALOG->PLL_VIDEO_DENOM = 1;
// 设置42倍频
CCM_ANALOG->PLL_VIDEO &= ~(0x7F << 0);
CCM_ANALOG->PLL_VIDEO |= (42 << 0);
// 设置1分频
CCM_ANALOG->PLL_VIDEO &= ~(3 << 19);
CCM_ANALOG->PLL_VIDEO |= (1 << 20);
// poweron PLL
CCM_ANALOG->PLL_VIDEO &= ~(1 << 12);//写0开启
// enable PLL5 output
CCM_ANALOG->PLL_VIDEO |= (1 << 13);
// 轮询等待时钟频率稳定
while ((CCM_ANALOG->PLL_VIDEO & (1 << 31)) == 0);
// 切回 PLL5
CCM_ANALOG->PLL_VIDEO &= ~(1 << 16);
// 选通门 pll5 + 4分频
unsigned int t = CCM->CSCDR2;
t &= ~(7 << 15);
t |= (1 << 16);
t &= ~(7 << 12);
t |= (3 << 12);
t &= ~(7 << 9);
CCM->CSCDR2 = t;
// 8分频
CCM->CBCMR |= (7 << 23);
}
lcd寄存器
LCDIF->CTRL



CTRL1

TRANSEFR_COUNT

CUR_BUF,NEXT_BUF
存放显存地址
VDCTRL0

VDCTRL1

VDCTRL2

VDCTRL3

VDCTRL4

18位,让VSYNC/HSYNC/DOTCLK等工作,
// lcd参数配置
lcd_dev.width = 800;
lcd_dev.height = 480;
lcd_dev.hspw = 48;
lcd_dev.hfp = 40;
lcd_dev.hbp = 88;
lcd_dev.vspw = 3;
lcd_dev.vfp = 13;
lcd_dev.vbp = 32;
lcd_dev.pix_size = 4;
lcd_dev.frame_buffer = LCD_FRAMEBUF_ADDR;
lcd_dev.fore_color = 0x00FF0000;
lcd_dev.back_color = 0x00FFFFFF;
// LCD寄存器
LCDIF->CTRL |= (1 << 19) | (1 << 17) | (3 << 10) | (3 << 8) | (1 << 5);
LCDIF->CTRL1 = (7 << 16);
LCDIF->TRANSFER_COUNT = (lcd_dev.height << 16) | (lcd_dev.width << 0);
LCDIF->CUR_BUF = lcd_dev.frame_buffer;
LCDIF->NEXT_BUF = lcd_dev.frame_buffer;
LCDIF->VDCTRL0 |= (1 << 28) | (1 << 24) | (1 << 21) | (1 << 20) | (lcd_dev.vspw << 0);
LCDIF->VDCTRL1 = (lcd_dev.height + lcd_dev.vfp + lcd_dev.vbp + lcd_dev.vspw);
LCDIF->VDCTRL2 = (lcd_dev.hspw << 18) | (lcd_dev.width + lcd_dev.hfp + lcd_dev.hbp + lcd_dev.hspw);
LCDIF->VDCTRL3 = ((lcd_dev.hspw + lcd_dev.hbp) << 16) | ((lcd_dev.vspw + lcd_dev.vbp) << 0);
LCDIF->VDCTRL4 |= (1 << 18) | (lcd_dev.width << 0);
LCDIF->CTRL |= (1 << 0);//最后使能
注意,CTRL1位要用=,因为要置0x0111,即7,而16-19位默认为0x1111,所以若使用|=则19位仍为1.


1004



被折叠的 条评论
为什么被折叠?



