1、LCD控制器
打开S3C2440数据手册可以看到LCD控制器硬件组成框图如下
2、LCD时序图
对此图做简单描述:LCD控制器主要由REGBANK,LCDCDMA,VIDPRCS,TIMEGEN等寄存器组成,如果不是用的三星的LCD,LPC3600和LCC3600就不用管它,它们专门为三星的LCD设计的。
REGBANK由17个可编程的寄存器和一个256X16调色板内存组成,他们用来配置LCD控制器
LCDCDMA是一个专用的DMA,它能自动将帧内存中的数据传送到LCD驱动器,通过这个DMA通道,数据不需要CPU干涉就能传送到LCD上显示。
VIDPRCS接收来自LCDCDMA的数据,并转换成合适的数据格式再送到LCD驱动器中。
TIMEGEN由可编程的逻辑组成,生成LCD驱动器的控制信号。
我们在LCD上显示的一幅图像称为一帧图像。在LCD上显示一帧图像的原理:从第一行的最左边开始扫描,一行结束后跳到下一行继续扫描。当显示完一幅图像后,从新
第一行接着扫描。扫描的时候就像一个“Z”字形。扫描图像必须在控制信号下进行,下面讲解一下控制信号。在mini2440开发板上用的是W35的TFT屏。TFT屏工作时序如下图所示
对上面对参数解释一下
VSYNC:垂直同步信号
VSPW:表示垂直同步脉冲的宽度,用行数计算
VBPD:表示新一帧图像的开始,垂直同步信号以后无效的行数
VFPD:表示新一帧图像结束后,垂直同步信号以前的无效的行数
HSYNC:水平同步信号,表示新的一行的开始,即跳到最左边开始行的一行数据的扫描。
HSPW:表示水平同步信号的宽度,用VCLK计算
HBPD:表示水平同步信号从开始到一行的有效数据开始之间VCLK的个数
HFPD:表示一行有限数据结束到下一个水平同步信号开始之间VCLK的个数
VCLK:像素时钟信号
VD[23:0]:LCD像素数据输出端口
VDEN:数据使能信号
LEDN:行结束信号
显示图像的时候会看到图像四周有黑色边框,结合时序图解释一下:当我们发出VSYNC信号后,要经过(VSPW+1+VBPD+1)这么长时间,那么这么长时间所扫面的行是无效的,这对应着我们图像的最上边的黑框,接下来是扫描LINEVAL+1行有效数据,最后经过(VFPD+1)个无效行,这对应着图像下面的黑框。对于每一行图像数据,HSYNC信号发出后,经过(HSPW+1+HBPD+1)个无效像素,这对应着我们图像左边黑框,接下来显示HOZVAL+1个有效像素,接着扫描(HFPD+1)个无效像素,这对应着我们图像的右边黑框。
VSYNC信号的出现表示一帧图像的开始,我们把1s内能显示图像的帧数称为显示器频率,也叫做场频率或者垂直频率。显示分辨率又称屏幕分辨率,指显示器屏幕上显示的有效像素点的数目。这是不同的概念。
3、LCD操作
下面讲解如何操作LCD来显一帧图像:
一个像素点的颜色是由三种颜色(红,绿,蓝)按照一定比例配置得到的,每种颜色由几位二进制来表示,到底是由几位来表示需要我们设置LCD寄存器来配置。LCD支持单色(1BPP),4级灰度(2BPP),16级灰度(4BPP),256级灰度(8BPP)调色板显示模式和16BPP和24BPP的非调色板显示模式。BPP:bit per Pixel 即 位/像素。 我们的LCD就是选择的16BPP显示模式,16BPP有两种表示方式,分别为5:5:5:1显示模式和5:6:5显示模式。我的LCD选择的是5:6:5显示模式,5:6:5表示的就是前5位二进制表示的事红色,中间6位表示绿色,最后5位表示的是蓝色。16BPP显示模式图如下所示
我们先了解下有关帧内存的概念,所谓的帧内存就是图像数据的存放地址,我们将图像数据放入到帧内存中,然后自动通过LCDDMA将数据送到LCD上显示。
我们主要要对一下几个寄存器进行操作:LCDCON1,LCDCON2,LCDCON3,LCDCON4,LCDCON5,LCDSADDR1,LCDSADDR2,LCDSADDR3
LCDCON1寄存器如下图所示
第0位是LCD信号输出使能位,[4:1]位是选择BBP模式,[6:5]位是选择显示模式,我们LCD是TFT屏,故此处应该设置为3,[7]用不到暂时不管,[17:8]位用来设置像素信号始终,这个要根据具体的LCD数据手册来设置,[27:18]没用到暂时不管。
LCDCON2寄存器如下图所示
此处的各参数的含义前面已经解释过了,我们需要查看LCD的数据手册进行设置,其中LINEVAL设置为239,因为我们LCD是320X240的屏
LCDCON3寄存器如下图所示
参考数据手册对上图进行配置,其中HOZVAL为319
LCDCON4寄存器如下图所示
我们只需用到[7:0]位参考数据手册对HSPW进行设置
LCDCON5寄存器如下图所示
第0、1位用来设置数据存储方式,我们ARM上电默认的方式是小端模式,即数据的低位放在低地址处,数据的高位放在高地址处。第3位用来设置给LCD供电,我们LCD有两种供电方式,一种是外接电源,一种是我们io口输出高电平供电,mini2440采用的是io口供电,采用IO供电的好处是当我们不用LCD的时候可以通过软件来设置LCD的开启与关闭。第8、9位是设置信号极性的。所谓信号极性入下图所示
上面一个波形是正极性,下面一个为负极性。参考我们的LCD时序图可以看出,我们在时钟信号的下降沿采集数据,故应该设置为负极性信号,第10位设置为1。第11位用来设置显示模式,我们采用的的是5:6:5模式。谈到数据存储,我们接下来讲一讲帧内存的概念,所谓帧内存就是图像数据在内存中的存储地址,我们将数据存放在帧内存中,然后将帧内存的地址告诉LCD控制器,LCD会自动通过DMA读取数据并显示。因此,我们在编程的时候应该事先声明一个数组用来保存图像数据,然后将内存地址告诉LCd控制器。
下面介绍一下帧内存地址寄存器
【29:21】位用来保存帧内存地址的高9位【30:22】,【20:0】用来保存LCD的帧缓冲区开始地址的【21:1】位
用来保存LCD的帧缓冲区的结束地址的【21:1】位。它的计算方法应经给出来了,LCDBASEL=((the frame end address)>>1)+1=LCDBASEU+(PAGEWID+OFFSIZE)x(LINEVAL+1)
我们用到【10:0】位,这里用来设置视口的宽度,半字位单位,我们一个像素就是半字,LCD的宽度为320个像素,故应该设置为320,其他位置0即可。
下面给出几个例子
1、我们在LCD上显示一个蓝色的点。程序如下:
#include "2440addr.h"
//根据数据手册设置配置参数,W35的屏的收据手册可能参数上有点老了,反正我按照上面的配置就是不对,然后参照开发板自带的程序进行配置
//LCDCON1配置
#define CLKVAL 4
#define BPPMODE 12
#define PNRMODE 3
//LCDCON2配置
#define HEIGHT 240
#define VBPD 10
#define VFPD 4
#define VSPW 1
//LCDCON3,4配置
#define WIDTH 320
#define HBPD 0x44
#define HFPD 0x04
#define HSPW 0x01
//LCDCON5配置
#define FRM565 1
#define INVVCLK 1
#define INVLINE 1
#define INVVFRAME 1
#define PWREN 1
#define BSWP 0
#define HWSWP 1
//此宏定义就是为了获取LCD的帧缓冲区的起始地址的【21:1】位
#define Low21Bits(n) ((n)&0x1fffff)
//声明一个帧内存用于保存帧图像数据
volatile unsigned short Lcd_Buffer[240][320];
//LCD控制寄存器初始化
void Lcd_Init(void)
{
rGPCCON=0xaaaa02a9;
rGPDCON=0xaaaaaaaa; //先将GPC和GPD的管教配置为LCD下的功能。
rLCDCON1=(CLKVAL<<8)|(PNRMODE<<5)|(BPPMODE<<1);
rLCDCON2=(VBPD<<24)|((HEIGHT-1)<<14)|(VFPD<<6)|(VSPW);
rLCDCON3=(HBPD<<19)|((WIDTH-1)<<8)|(HFPD);
rLCDCON4=HSPW;
rLCDCON5=(FRM565<<11)|(INVVCLK<<10)|(INVLINE<<9)|(INVVFRAME<<8)|(BSWP<<1)|(HWSWP);
rLCDSADDR1=(((unsigned int)Lcd_Buffer>>22)<<21)|Low21Bits((unsigned int)Lcd_Buffer>>1);
rLCDSADDR2=Low21Bits(((unsigned int)Lcd_Buffer+(240*320*2))>>1);
rLCDSADDR3=(0<<11)|(WIDTH);
}
void Lcd_PowerEnable(int powerEnable)
{
rGPGCON&=~(3<<8)|(2<<8);
rGPGDAT|=1<<4;
rLCDCON5&=~(1<<3)|(powerEnable<<3);
}
void PutPixel(unsigned int x,unsigned int y,unsigned short c)
{
if((x<320)&&(y<240))
Lcd_Buffer[y][x]=c;
}
void Lcd_ClearScr(unsigned int c)
{
unsigned int x,y;
for(y=0;y<240;y++)
{
for(x=0;x<320;x++)
{
Lcd_Buffer[y][x]=c;
}
}
}
int Main()
{
Lcd_Init();
Lcd_PowerEnable(1);
rLCDCON1|=1<<0;
Lcd_ClearScr(0xffff);
while(1)
{
PutPixel(100,100,569);
}
return 0;
}
上一篇:裸机程序在mini2440上的运行
下一篇:mini2440裸机程序 统宝3.5 LCD驱动 TopPoly-TD035STED4
推荐阅读
史海拾趣
Protel99出现“Access violation at address 40067324 in module 'Vcl50.bpl'. 使用Protel99打开PCB图的时候出现“Access violation at address 40067324 in module \'Vcl50.bpl\'. Write of address 0000014C” 请问怎么解决啊… 查看全部问答∨ |
|
得到一块LPC2478的开发板,里面的资源太少了,只有些Demo程序,如果自己在上面移植个操作系统,ARM7TDMI-S,没MMU也能跑Linux、winCE吗? 请了解的人给点建议。… 查看全部问答∨ |
我们单位要给新买的AN2512C支流低电阻测量仪编一个软件用串口读取测量数据,vc++。这台仪器支持串口通信(说明书里也提供了通信协议)。可是我编出来之后“不灵”(也就是说那台仪器“没有反应”),求教高手!谢谢。 我用串口精灵也调过,按照协 ...… 查看全部问答∨ |
我做的一个模电书中反向加法电路,想让两个信号源中发出的信号同步,比如全是100HZ,峰峰值是100mv,这两者之间没有相位差。这是我的两个信号源发生器,下图… 查看全部问答∨ |
|
我的是8*8点阵,为什么我的中断没用啊,我用m设置中断的啊,要怎么样写才对的啊,为什么m不是=50ms的啊,主要是下面这一块,主函数里的,帮我看下了,谢谢#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code ta ...… 查看全部问答∨ |
有木有给个Xilinx ise的安装包加破解包呢。。。小女子电脑是win764位机,几次下载安装都不正确。。而且Xilinx官网注册了但是老显示错误。。急求,谢谢。。。… 查看全部问答∨ |
设计资源 培训 开发板 精华推荐
- 华为Mate 20系列竞争 分析师下调iPhone XR约3000万部预估出货量
- 为人工智能而生,英特尔公布Cascade Lake-AP处理器详细性能数
- 贸易战恐造成苹果供应链的台湾厂商最大规模迁徙
- 大兴区2018年年底前将建成8KM自动驾驶测试道路
- 都是第一?荣耀与小米都说自己是双十一手机冠军
- 百亿平米住宅物业商用清洁前景广阔,高仙机器人落地东方润园、金茂府等多个小区
- 意法半导体STM32Cube.AI生态系统加强对高效机器学习的支持
- “乘势再上 华南领航”阿童木机器人深圳子公司盛大开业
- 小米智能摄像机获得BSI物联网安全Kitemark风筝标志认证
- 监管出手,车企被迫减产,汽车缺芯何时了?