裸机LCD驱动配置

本节来学习裸机下的LCD 驱动,本节学完后,再来学习Linux下如何使用LCD驱动

Linux中的LCD驱动,链接如下:

(Linux-LCD层次分析链接:http://www.cnblogs.com/lifexy/p/7603327.html)

(Linux-LCD驱动分析链接:http://www.cnblogs.com/lifexy/p/7604011.html)

横屏4.3寸LCD为480*272(行:480个像素点        列:272个行)

1.LCD原理图 :

Pin1- Pin6:Von/ Voff  电源正/负(由GPG4控制,高电平有效)

Pin2:VM/VDEN 数据使能信号 (0:表示正在跳行,1:表示可以传输像素数据) 

Pin8:VLINE/HSYNC 水平同步信号(每扫完一行,即发一次水平同步信号)

Pin28:VFRAME/VSNC 垂直同步信号(每扫完一屏,即发一次垂直同步信号)

Pin30:VLCK 时钟信号 

Pin42,Pin45 LED+,LED-   背光显示开关 (由0:off   1:no)

VD23~VD19:R信号   

VD15~VD10:G信号 

VD7~VD3    :B信号 

数据是采用16Bpp像素,RGB565格式(因为LCD控制器不支持18Bpp格式) 

例如:粉色RGB值分别为209,92,174(11010001,01011100,10101110)

数据从高位往下取,R和B取5位,G取6位,那么值为0XD2F5。

565RGB引脚连接图如下:

1.2配置引脚

1     GPCUP   = 0xffffffff;   // 禁止内部上拉
2     GPCCON  = 0xaaaaaaaa;   // GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND 
3     GPDUP   = 0xffffffff;   // 禁止内部上拉
4     GPDCON  = 0xaaaaaaaa;   // GPIO管脚用于VD[23:8]
5     GPBCON &= ~(GPB0_MSK);  // Power enable pin
6     GPBCON |= GPB0_out;
7     GPBDAT &= ~(1<<0);            // Power off

2.设置LCDCON1~5控制寄存器

2.1BSWP和HWSWP介绍

更改存储格式,对于16bppRGB565(高数据在后)来说,BSWP=0, HWSWP=1

2.2查看2440中LCD控制器初始状态时序图:

VSPW: 垂直同步脉冲宽度 pulse widch 

VBPD: 垂直脉冲后沿延迟(用来等待LCD模块响应的时间)  back delay 

VFPD: 垂直脉冲前沿延迟(用来等待LCD模块响应的时间)  Front delay

HSPW: 行同步脉冲宽度 pulse widch 

HBPD: 行脉冲后沿延迟(用来等待LCD模块响应的时间)  back delay 

HFPD: 行脉冲前沿延迟(用来等待LCD模块响应的时间)  Front delay

 LINEVAL:行数,用来决定垂直尺寸,对于4.3寸时,LINEVAL=272-1

HOZVAL:行数,用来决定水平像素点个数,对于4.3寸时,HOZVAL=480-1

2.3 查看 LCD芯片手册时序图,计算周期时间:

从上图2中得到时钟周期为10Mhz(100ns)

通过图1和图3计算出:

HSPW+1=T7=5 clock

HFPD+1=T8-T11=11 clock 

HBPD+1=T6-T7-T8=17 clock

VSPW+1=T1=1 Line

VFPD+1=T2-T5=2 Line

VBPD+1=T0-T2-T1=4 Line

2.4 配置LCDCON1~5

根据上面就先来定义全局变量:

 #define  HSPW_16bpp      5-1
 #define  HFPD _16bpp     11-1
 #define  HBPD _16bpp     17-1
 #define  VSPW _16bpp     1-1
 #define  VFPD _16bpp     2-1
 #define  VBPD _16bpp     4-1

设置LCDCON1寄存器:

CLKVAL[17:8]:

设置VCLK时钟, CLKVAL =HCLK/(LCD时钟*2)-1

本裸板的HCLK=100Mhz,LCD时钟=10MHZ,所以CLKVAL =4

PNRMODE [6:5]:

设置为TFT模式,PNRMODE =0x3

BPPMODE[4:1]:

设置为16BPP, BPPMODE=0x0C

ENVID [0]:

控制PWREN信号(GPG4)输出,先配置好再输出PWREN, ENVID =0

(开启之前应该设置LCDCON5位[3]允许PWREN信号才有效)

设置LCDCON2寄存器:

VBPD [31:24]:垂直脉冲后沿延时, VBPD=VBPD_16bpp;

LINEVAL[23:14]:垂直行数,决定垂直大小, LINEVAL=272-1;

VFPD[13:6]:垂直脉冲前沿延时, VFPD= VFPD_16bpp;

VSPW[5:0]:垂直同步脉冲宽度, VSPW= VSPW_16bpp;

设置LCDCON3寄存器:

HBPD[25:19]:水平脉冲后沿延时, HBPD= HBPD_16bpp;

HOZVAL[18:8]:水平像素点个数, HBPD= 479;

HFPD[7:0]:水平脉冲前沿延时, HFPD= HFPD_16bpp;

设置LCDCON4寄存器:

HSPW[7:0]:水平同步脉冲宽度, HSPW = HSPW_16bpp;

设置LCDCON5寄存器:

FRM565[11]:设置16bpp输出格式, FRM565=1(RGB565);

INVVCLK[10]:设置VCLK记性,LCD手册如下,所以等于0,不设置(下降沿读取数据)

INVVLINE [9]:HSYNC水平同步信号反转, 因为LCD手册和2440手册不一样,所以INVVLINE=1;

INVVFRAME[8]:VSYNC垂直同步信号反转, 因为LCD手册和2440手册不一样,所以INVVFRAME =1;

INVVFRAME[3]:PWREN信号(GPG4)允许位,=0,不设置,等设置了缓存寄存器后才设置

HWSWP [0]:更改存储格式,这里HWSWP=1,BSWP[1]默认等于0,使我们的LCD像素显示从低到高排列

代码如下:

 LCDCON1 = (4<<8) | (0X3<<5) |  (0x0C <<1) | (0<<0);

 LCDCON2 = ((VBPD_16bpp)<<24) | (271<<14) |  ((VFPD_16bpp)<<6) |((VSPW_16bpp)<<0);

 LCDCON3 = ((HBPD_16bpp)<<19) | (479<<8) | ((HFPD_16bpp));

 LCDCON4 = (HSPW_16bpp);

 LCDCON5 = (1<<11) | (1<<9) | (1<<8) |  (1<<0);

 LCDCON1 &=~(1<<0);          // 关闭PWREN信号输出

 LCDCON5 &=~(1<<3);          //禁止PWREN信号

3.设置LCDSADDR1~3缓冲地址寄存器

设置LCDSADDR1寄存器:

LCDBANK[29:21]:

保存缓冲起始地址A[30:22]   

LCDBASEU[20:0]:

保存缓冲起始地址A[21:1]

设置LCDSADDR2寄存器:

LCDBASEL[20:0]:

保存存缓冲结束地址A[21:1],这里我们 采用4.3寸LCD,所以等于((0x30400000+(480)*(272)*2)>>1)&0x1fffff; 这里*2是代表一个像素占了2字节,若是8bpp模式,则就不需要乘以2  

设置LCDSADDR3寄存器:

OFFSIZE[21:11]:

保存LCD上一行结尾和下一行开头的地址之间的差(半字数为单位),我们使用的是连续地址,所以不设置,默认为0

PAGEWIDTH [10:0]:

保存LCD一行占的宽度(半字数为单位),我们每个像素点是半字数,所以等于480

代码如下:     

1 LCDSADDR1 = ((0x30400000>>22)<<21) |  ((0x30400000>>1)& 0x1fffff);
2 LCDSADDR2 = ((0x30400000+(480)*(272)*2)>>1)& 0x1fffff; 3 LCDSADDR3 = (0<<11) | (480*2/2);

4.允许并输出PWREN信号

GPGCON = (GPGCON & (~(3<<8))) | (3<<8);   // GPG4用作LCD_PWREN
GPGUP  = (GPGUP & (~(1<<4))) | (1<<4);    // 禁止内部上拉   
  
LCDCON5 = (LCDCON5 & (~(1<<5))) | (0<<5);  // 设置LCD_PWREN的极性: 正常
LCDCON5 = (LCDCON5 & (~(1<<3))) | (1<<3);     // 允许LCD_PWREN信号输出

LCDCON1 |= 1;                  //输出LCD_PWREN信号

 5.驱动LCD显示白色

 fb_base_addr=0x30400000;    //缓存起始地址
 LCDCON1 |= 1;                // 使能LCD驱动
 GPBDAT |= (1<<0);		 // 开背光
 color=0xffffff;                   //显示白色颜色
 for (y = 0; y < 272; y++)         //向缓存地址里存数据
      for (x = 0; x < 480; x++)
    {
    UINT16 *addr = (UINT16 *)fb_base_addr + (y * 480 + x);  //定义指针变量等于缓存地址
     red   = (color >> 19) & 0x1f;
     green = (color >> 10) & 0x3f;
     blue  = (color >>  3) & 0x1f;
     color = (red << 11) | (green << 5) | blue; // 格式5:6:5
   *addr = (UINT16) color;               //addr表示缓存地址,*addr表示缓存地址里的变量,                                 
    }
 LCDCON1 &= 0x3fffe;                // 失能LCD驱动
 GPBDAT &= ~(1<<0);		  // 关背光

6.TPAL临时调色板寄存器介绍

    当清屏时,可以使用TPAL寄存器,快速清屏 

    位[24]     TPAL使能位

    位[23:0]  RGB数据位

例如: TPAL=0x1ffffff (使能TPAL寄存器,并设为白色屏)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Jerry的SAP技术分享

如何查看CRM WebUI,C4C和Hybris里的页面技术信息

在WebClient UI页面上按F2,就能看到页面的技术信息, 可以找到当前页面是哪一个BSP component实现的:

36840
来自专栏玄魂工作室

CTF实战3 Wireshark网络嗅探工具使用

Wireshark可以打开多种网络分析软件捕捉的包,可以支持许多协议的解码。我们可以用它来检测网络安全隐患、解决网络问题,也可以用它来学习网络协议、测试协议执行...

11730
来自专栏张尧博客

6个好玩儿的LINUX命令

47750
来自专栏瓜大三哥

物理约束

IO约束,如位置和IO标准 引脚分配命令 Set_property PACKAGE_PIN <pin name> [get_ports <port>] 驱动能...

44650
来自专栏数据和云

【循序渐进Oracle】Oracle段空间管理技术

在Oracle数据库内部,对象空间是以段的形式(Segment)存在和管理的,通过不同的段类型Oracle将段区分开来,在Oracle 9i中,主要的段类型有:...

30970
来自专栏WOLFRAM

给大家分享几个操作上的技巧~~~

17320
来自专栏SAP最佳业务实践

SAP最佳业务实践:SD–带质量管理的销售退货(237)-6退货库存处理

一、MIGO退货库存转移至自有非限制库存 如果可重新使用退回的物料,则需要将其从退货库存移至非限制自有库存,这样退货可任意使用,并会重新包括在 MRP 计算之中...

40450
来自专栏Y大宽

RNA-seq分析简洁版

Tumor:SRR316214,SRR316215 Adjacent Normal Liver:SRR316212,SRR316213

34420
来自专栏BY的专栏

快速完成JSON\字典转模型 For YYModelJSON转模型 For YYModel

53980
来自专栏腾讯移动品质中心TMQ的专栏

Android手机上用户操作模拟方法的研究与实现

一、 问题背景 最近研究了一下Android手机上用户操作的模拟方法, 有一些心得与大家分享下。 之所以去研究Android手机上用户操作的模拟方法,是因为最...

1.4K60

扫码关注云+社区

领取腾讯云代金券