裸机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 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

Silverlight + Model-View-ViewModel (MVVM)

     早在2005年,John Gossman写了一篇关于Model-View-ViewModel模式的博文,这种模式被他所在的微软的项目组用来创建Expr...

3358
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

5318
来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2902
来自专栏跟着阿笨一起玩NET

c#实现打印功能

3902
来自专栏杨龙飞前端

scrollto 到指定位置

2994
来自专栏落花落雨不落叶

canvas画简单电路图

89211
来自专栏java 成神之路

使用 NIO 实现 echo 服务器

5737
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

3037
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3725
来自专栏C#

DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱。不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬。(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...)...

6088

扫码关注云+社区