ARM的LCD 的驱动控制实验

单片机实验

27人已加入

描述

ARM的LCD 的驱动控制实验

一、 实验目的
1.了解LCD 基本概念与原理。
2.理解LCD 的驱动控制。
3.熟悉用总线方式驱动LCD 模块。
4.熟悉用ARM 内置的LCD 控制器驱动LCD。
二、 实验内容
学习LCD 显示器的基本原理,理解其驱动控制方法。掌握两种LCD 驱动方式的基本
原理和方法。并用编程实现。
1.用总线方式直接驱动带有驱动模块的LCD。
2.用ARM 内置的LCD 控制器来驱动LCD。
三、 预备知识
1.用ARM SDT 2.5 集成开发环境,编写和调试程序的基本过程。
2.ARM 应用程序的框架结构。
3.会使用Source Insight 3 编辑C 语言源程序。
四、 实验设备及工具
硬件:ARM 嵌入式开发板、用于ARM7TDMI 的JTAG 仿真器、PC 机Pentumn100 以

软件:PC 机操作系统win98、ARM SDT 2.51 集成开发环境、仿真器驱动程序、Source
Insight 3.0
五、 实验原理及说明
1.LCD(Liquid Crystal Display)原理
液晶得名于其物理特性:它的分子晶体,不过以液态存在而非固态。这些晶体分子的液
体特性使得它具有两种非常有用的特点:1、如果让电流通过液晶层,这些分子将会以电流
的流向方向进行排列,如果没有电流,它们将会彼此平行排列。2、如果提供了带有细小沟
槽的外层,将液晶倒入后,液晶分子会顺着槽排列,并且内层与外层以同样的方式进行排列。
液晶的第三个特性是很神奇的:液晶层能够使光线发生扭转。液晶层表现的有些类似偏光器,
这就意味着它能够过滤掉除了那些从特殊方向射入之外的所有光线。此外,如果液晶层发生
了扭转,光线将会随之扭转,以不同的方向从另外一个面中射出。
液晶的这些特点使得它可以被用来当作一种开关——即可以阻碍光线,也可以允许光线
通过。液晶单元的底层是由细小的脊构成的,这些脊的作用是让分子呈平行排列。上表面也
是如此,在这两侧之间的分子平行排列,不过当上下两个表面之间呈一定的角度时,液晶成
了随着两个不同方向的表面进行排列,就会发生扭曲。结果便是这个扭曲了的螺旋层使通过
的光线也发生扭曲。如果电流通过液晶,所有的分子将会按照电流的方向进行排列,这样就
会消除光线的扭转。如果将一个偏振滤光器放置在液晶层的上表面,扭转的光线通过了(如
图A),而没有发生扭转的光线(如图B)将被阻碍。因此可以通过电流的通断改变LCD 中的
液晶排列,使光线在加电时射出,而不加电时被阻断。也有某些设计了省电的需要,有电流
时,光线不能通过,没有电流时,光线通过。

驱动控制

图7-1 光线穿过与阴断示意图
LCD 显示器的基本原理就是通过给不同的液晶单元供电,控制其光线的通过与否,从而达
到显示的目的。因此,LCD 的驱动控制归于对每个液晶单元的通断电的控制,每个液晶单
元都对应着一个电极,对其通电,便可使用光线通过(也有刚好相反的,即不通电时光线通
过,通电时光线不通过)。
2.电致发光
LCD 的发光原理是通过控制加电与否来使光线通过或挡住,从而显示图形。光源的提
供方式有两种:透射式和反射式。笔记本电脑的LCD 显示屏即为透射式,屏后面有一个光
源,因此外界环境可以不需要光源。而一般微控制器上使用的LCD 为反射式,需要外界提
供光源,靠反射光来工作。电致发光(EL)是液晶屏提供光源的一种方式。电致发光的特
点是低功耗,与二极管发光比较而言体积小。
电致发光(EL)是将电能直接转换为光能的一种发光现象。电致发光片是利用此原理
经过加工制作而成的一种发光薄片,如图7-2 所示。其特点是:超薄、高亮度、高效率、低
功耗、低热量、可弯曲、抗冲击、长寿命、多种颜色选择等。因此,电致发光片被广泛应用
于各种领域。

驱动控制

图7-2 电致发光片的基本结构
3.LCD 的驱动控制
市面上出售的LCD 有两种类型:
一种是带有驱动电路的LCD 显示模块,这种LCD 可以方便地与各种低档单片机进行接
口,如8051 系列单片机,但是由于硬件驱动电路的存在,体积比较大。这种模块常常使用
总线方式来驱动。
另一种则仅是LCD 显示屏,没有驱动电路,需要与驱动电路配合使用。特点是体积小,
但是却需要另外的驱动芯片。也可以使用带有LCD 驱动能力的高档MCU 驱动,如ARM 系
列的S3C44B0X。

驱动控制

图7-3 不带驱动电路的LCD 结构
⑴ 总线驱动方式
一般带有驱动模块的LCD显示屏使用这种驱动方式,由于LCD已经带有驱动硬件电路,
因此模块给出的是总线接口,便于与单片机的总线进行接口。驱动模块具有八位数据总线,
外加一些电源接口和控制信号。而且还自带显示缓存,只需要将要显示的内容送到显示缓存
中就可以实现内容的显示。由于只有八条数据线,因此常常通过引脚信号来实现地址与数据
线复用,以达到把相应数据送到相应显示缓存的目的。下图为一个典型的显示模块(HY-
12864B)提供的总线接口。

驱动控制

图7-4 曲型带驱动液晶模块的总线接口
⑵ 控制器扫描方式
S3C44B0X 中具有内置的LCD 控制器,它具有将显示缓存(在系统存储器中)中的LCD
图象数据传输到外部LCD 驱动电路的逻辑功能。
S3C44B0X 中内置的LCD 控制器可支持灰度LCD 和彩色LCD。在灰度LCD 上,使用
基于时间的抖动算法(time-based dithering algorithm)和FRC (Frame Rate Control)方法,可
以支持单色、4 级灰度和16 级灰度模式的灰度LCD, 在彩色LCD 上,可以支持256 级彩
色。对于不同尺寸的LCD,其具有不同数量的垂直和水平象素、数据接口的数据宽度、接
口时间及刷新率,而LCD 控制器可以进行编程控制相应的寄存器值,以适应不同的LCD 显
示板。

内置的LCD 控制器提供了下列外部接口信号:
VFRAME: LCD 控制器和LCD 驱动器之间的帧同步信号。它通知LCD 屏新的一帧的显
示,LCD 控制器在一个完整帧的显示后发出VFRAME 信号。
VLINE: LCD 控制器和LCD 驱动器间的同步脉冲信号,LCD 驱动器通过它来将水平移
位寄存器中的内容显示到LCD 屏上。LCD 控制器在一整行数据全部传输到LCD 驱动器后
发出VLINE 信号。
VCLK: 此信号为LCD 控制器和LCD 驱动器之间的象素时钟信号,LCD 控制器在VCLK
的上升沿发送数据,LCD 驱动器在VCLK 的下降沿采样数据。
VM: LCD 驱动器所使用的交流信号。LCD 驱动器使用VM 信号改变用于打开或关闭象
素的行和列电压的极性。VM 信号在每一帧触发,也在编程决定数量的VLINE 信号触发。
VD[3:0]:LCD 象素数据输出端口。
VD[7:4]:LCD 象素数据输出端口。

驱动控制

图7-5 LCD 控制器逻辑框图
图7-5 为S3C44B0X 中内置的LCD 控制器的逻辑框图,它用于传输显示数据并产生必
要的控制信号,如VFRAME, VLINE, VCLK, 和VM。除了控制信号,还有显示数据的数据
端口VD[7:0]。LCD 控制器包含REGBANK, LCDCDMA, VIDPRCS, 和TIMEGEN。
REGBANK 具有18 个可编程寄存器,用于配置LCD 控制器。LCDCDMA 为专用DMA,它
可以自动地将显示数据从帧内存中传送到LCD 驱动器中。通过专用DMA,可以实验在不
需要CPU 介入的情况下显示数据。VIDPRCS 从LCDCDMA 接收数据,将相应格式(比如
4/8 位单一扫描和4 位双扫描显示模式)的数据通TIMEGEN 包含可编程的逻辑,以支持
常见的LCD 驱动器所需要的不同接口时间和速率的要求。TIMEGEN 部分产生VFRAME,
VLINE, VCLK, VM 等信号。
⑶ 与LCD 有关的函数:
void LCD_Cls(); //文本模式下清除屏幕
void LCD_ChangeMode(U8 mode); //在图形模式和字符模式下切换
void LCD_Refresh(); //图形刷新显示
void LCD_Init(); //初始化LCD 控制寄存器
void LCD_printf(const char *format,...); //输入格式化字符到LCD
void LCD_txtRefresh(); //字符显示刷新
void LCDBkLight(U8 isOpen); //打开/关闭LCD 背光
void LCDDisplayOpen(U8 isOpen); //打开/关闭LCD 显示
六、 实验步骤
1.不带操作系统的LCD 驱动控制实验
在对LCD 进行控制的时候,将显示一级缓存的地址设为0xc000000,一级缓存每4 位(16 级灰度的屏)对应LCD 的一个象素。
U32* pLCDBuffer16=(U32*)0xc000000;
再设置一个行列与LCD 高宽相对应的的数组,每一个元素对应LCD 显示屏上的一个象
素点,数组元素为32 位,分成四个八位,前三个八位分别代表三种颜色的,第四个八位暂
不用,这样可以兼容32 位彩色显示屏。
U32 LCDBuffer[LCDHEIGHT][LCDWIDTH];
ASCII 码的码元信息,共有128 行,每行12 列,ASCII 码为6X12(宽X 高),每行代
表一个ASCII 码字符的字模信息。12 列分别对应高度分辨率的12 行中的一行。
U8 LCDTxtData[128][12];
在不带操作系统环境下进行LCD 驱动控制时,工作分两步进行,第一次是对ARM 中与
LCD 有关的诸寄存器进行设置,相应的设置内容在LCD_Init()函数中,下面对其代码作如下
说明。
U32 LCDBASEU,LCDBASEL,LCDBANK;
首先关闭LCD,等完成对显示寄存器的设置后,再打开LCD 显示。
LCDDisplayOpen(FALSE);
接下来对一级显存的每个单元置零,清除屏幕显示。由于pLCDBuffer16 被定义为U32,
即为32 位(8 个4 位)指针,所以应当循环40*240 次,实际上对应的单元数为整个320X240
的屏幕范围。
for(i=0;i<40*240;i++)
*(pLCDBuffer16+i)=0x0;
/////////////初始化LCD 端口/////////////
LCD 驱动控制端口与ARM 的端口四是共用的,因此,要设置相应的寄存器,将其定义
为功能端口,即LCD 驱动控制端口。
rPDATD= 0xff;
rPCOND= 0xaaaa; //configure the portD as
VD0,VD1,VD2,VD3,VCLK,VLINK,VM,VFRAME...ect. LCD function
rPUPD = 0x0;//enable pull up resistor
/////////////////////////////////////
LCD 共有三个控制寄存器,分别控制与LCD 扫描宽度等硬件时序有关的量。rLCDCON1
和rLCDCON2 为LCD 控制寄存器。
rLCDCON1=(0);//|(1<<5)|(0x3<<8)|(0x3<<10)|(CLKVAL<<12);//先将此控制字设为零。
设置LCD 的垂直尺寸为240,水平尺寸为3200,水平线扫描空闲时间为10MCLK。
rLCDCON2=(240-1)|(79<<10)|(10<<21);
LCDBANK=0xc000000>>22;//((U32)LCDBuffer16)>>22;
LCDBASEU=0x0;//((U32)LCDBuffer16)&0x3fffff;
LCDBASEL=LCDBASEU+(80)*240;
rLCDSADDR1~3 为帧缓冲起始地址。
rLCDSADDR1= (0x2<<27) |(LCDBANK<<21)|LCDBASEU;//|
((((U32)LCDBuffer16)>>1)&0x7ffffff); // 16-gray, LCDBANK, LCDBASEU
rLCDSADDR2= (0<<29)|(0<<21)|LCDBASEL;
rLCDSADDR3= (320/4) | ( 0<<9 );
以下重新设置控制寄存器1 的值。
rLCDCON1=LCDCON1_ENVID|(1<<5)|(0x0<<8)|(0x3<<10)|(CLKVAL<<12);//|LCDCON1

Delay(5000);//延时5 秒
最后打开LCD 的背光,并打开LCD 显示。
LCDBkLight(TRUE);
LCDDisplayOpen(TRUE);
进入完上述初始化操作以后,便可以通过往二级显存中写数据,并调用LCD_REFRESH
函数将其刷新到一级显存,显示在LCD 屏上,以此为基础可以构造出复杂的图形有关函数。
1)使用ARM 驱动控制方式,编程显示液晶的16 级灰度。
在ARM SDT 2.5 中,打开一个新的工程,在主函数中加入下列代码。
void Main(void)
{
Port_Init(); //端口初始化
LCD_Init(); //LCD 初始化
LCD_ChangeMode(DspGraMode);//LCD 切换到图形模式
LCD_Show16Level(0xf); //显示16 级灰度
Delay(15000); //暂停数秒
LCD_ShowMove(); //灰阶图形开始向右移动
LCD_Show16Level(0x8); //再次显示16 级灰度
while(1) ; //死循环等待
}
LCD_ShowMove()和LCD_Show16Level(0x8)的源代码及注释详见源程序文件。
编译并将此工程对应的SYSTEM.BIN 文件下载到嵌入式开发板中,重新启动后运行即
可显示LCD 的16 级灰度及移动的灰度图形。
2)ASCII 字符的显示
使用LCD_printf()可以输出格式化字符。这里主要介绍如何将字符显示到LCD 上。
LCD_printf 函数中使用到的LCD_TxtRefresh 体现了显示LCD 是如何刷新的。
字符使用单独的缓冲区U8 LCDTxtBuffer[LCDRow][LCDColumn];
void LCD_TxtRefresh(int LCDCurrentDspTxt)
{
int i,j,k,showrow;
unsigned int data;
U8 txtdata;
for(j=0;jfor(i=0;idata=0;
showrow=LCDCurrentDspTxt+j/LCDTxtMode_TxtHeight;//如果单独调用此函
数,一般LCDCurrentDspTxt=0,则j/LCDTxtMode_TxtHeight 为当前所在行。
if(showrow>LCDRow-1)//如果超出行范围,则重新指向最顶行
showrow-=LCDRow;
txtdata=LCDTxtBuffer[showrow][i];//提取字符缓存中的当前行的第i 列
if(txtdata>128)//如果超出ASCII 码的范围,则置为空格
txtdata=' ';
txtdata=LCDTxtData[txtdata][j%LCDTxtMode_TxtHeight];//从字模表中提取相
应ASCII 字符的第j 行字模
for(k=7;k>=0;k--){//对字符进行移位处理

data<<=4;
data|=((txtdata>>k)&0x1)*0xf;
}
*(pLCDBuffer16+i+j*40)=data;//将最后结果送一级显存显示
}
}
}
理解了上述程序过程后,可以对显示缓存的某个单元设置值,然后调用此函数进行刷新
显示。
比如,在主函数中加入下列语句:
LCDTxtData[5][5]=’a’;
LCD_TxtRefresh(0);
即可实现在第五行第五列的地方显示字母a。
2.带操作系统的LCD 驱动控制实验
带有操作系统时,可以将LCD 显示部分放到一个单独的任务中,同时操作系统可以响
应键盘输入,可以以键盘输入的内容来作为控制LCD 显示的依据。
void LCD_Show_Task(void *Id)
{
LCD_Init(); //LCD 初始化
LCD_ChangeMode(DspGraMode);
while(1)
{
OSTimeDly(1000); //操作系统延时,使低优先级任务有机会执行
if(ShowNext)
{
LCD_Show16Level(0xf); //显示16 级灰度
}
else LCD_ShowMove(); //灰阶图形开始向右移动
}
}
键盘任务可以响应ARM 开发板键盘输入,每按一次键盘上的任意键,键盘响应任务即
改变一次ShowNext 变量的值,因此可以实现交替显示16 级灰度和显示移动的灰阶图形(按
任意键切换)。
七、 思考题
1.液晶显示的基本原理是什么?
2.总线方式驱动液晶模块和使用控制器进行驱动控制有什么异同?
3.LCD 显示图形、ASCII 字符与汉字的基本思想是什么?

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分