文档库 最新最全的文档下载
当前位置:文档库 › 12232LCD

12232LCD

12232LCD
12232LCD

A VR学习笔记十七、LCD12232液晶显示实验

-------基于LT_Mini_M16

17.1 LCD12232液晶显示实验

17.1.1、实例功能:

在前面我们已经学习了1602和12864液晶的基本知识,并且通过简单的实例实现了在1602和12864液晶上显示字符和汉字。今天我们再来学习另外一种比较常用的液晶12232.

本实例中我们选用深圳锦昌电子的DM12232B型液晶。

本实例分为三个功能模块,分别描述如下:

●单片机系统:利用A Tmega16单片机与DM12232B型液晶构成液晶显示电路。

●外围电路:DM12232B型液晶与单片机的连接电路。

●软件程序:编写软件,控制液晶显示字符。

通过本实例的学习,掌握以下内容:

●掌握DM12232B型液晶的基本原理和程序设计方法。

17.2、器件和原理

关于液晶的显示原理我们在前面的实例中已经做过介绍,在这里就不再多做说明。在本实例中我们重点介绍DM12232B型液晶的结构、指令及显示控制。

12232系列的LCD大部分都是使用SED1520驱动芯片,12232F用的是ST7920。它们的运行速度都是nS级的,所以一般我们发送数据的时候不用过多考虑等待问题。

许多LCD模块的引脚数都不一致,常见有16~20个不等。不过它们的功能是大同小异。我们所用的DM12232B型液晶是18引脚:VDD,VSS,VLCD,RET,E1,E2,R/W,A0,DB0,DB1,DB2,DB3,DB4,DB5,DB6,DB7,LED+,LED-。

17.2.1、DM12232B型液晶的管脚排列

DM12232B型液晶的管脚排列及说明如图1所示:

引脚功能简单说明:

1、VLCD为LCD电源,要求电压可调节,一般用20K的可调电阻取中间抽头电压供电;

2、RES,复位信号。这个大家都知道,一般应用中直接接到高平就行了;

3、E1,E2为控制器选择线,高电平时为选中;

4、R/W=0时为写选通,R/W=1时为读选通,一般我们只是向液晶发送数据,不读液晶内部的数据,所以该脚可以直接接地(低电平);

5、A0=1时表示所发的数据是显示数据,A0=0时表示所发数据是指令(Instruction);

6、DB0~DB7为数据线;

7、LED-,LED+为背光灯电源,一个接正,一个接地就行。

17.2.1、DM12232B型液晶的读写时序

DM12232B型液晶的读写时序如图2所示,

应用中主要有两种读写时序:写指令和写数据,分别描述如下:

写指令:

E选通—A0=0—读写使能(直接接地就不用设置了)—数据的发送—状态释放

写数据

E选通—A0=1—读写使能(直接接地就不用设置了)—数据的发送—状态释放

图1 DM12232B型液晶的管脚排列及说明

图2 DM12232B型液晶的读写时序

17.2.3、DM12232B型液晶的指令介绍

DM12232B型液晶的指令如表1所示

表1 DM12232B型液晶的指令

表1(续)DM12232B型液晶的指令

17.2.4、DM12232B型液晶的原理图

DM12232B型液晶的原理图如图3所示

17.2.5、DM12232B型液晶的地址表

DM12232B型液晶的地址表如图4所示SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

图3 DM12232B型液晶的原理图

图4 DM12232B型液晶的地址表

10.1.3、电路和连接

图5所示为DM12232B型液晶与单片机之间进行并口通讯的典型接法本实例是在LT_Mini_M16学习板的基础上做的扩展实验,具体连线如下。引脚连接

mcu lcd 引脚说明

Vcc VDD 电源电压

GND VSS 电源地

偏压信号,接可调电阻VEE(VLCD) LCD外接驱动负电压

PA1 RES 复位信号(低电平有效),低电平复位

PA6 E1 读写使能信号1

PA7 E2 读写使能信号2

PA5 R/W 读写选择信号

PA4 A0 H-显示数据。。L-显示指令数据(指令数据选择)

PB0 DB0 数据线

PB1 DB1

PB2 DB2

PB3 DB3

PB4 DB4

PB5 DB5

PB6 DB6

PB7 DB7

Vcc VLED+ LED(+5V)或EL背光源

GND VLED- LED(0V)或EL背光源

图5 12232B液晶与单片机的一种接口图

17.4、程序设计

1、程序功能

程序的功能是使用单片机控制12232B液晶显示字符,程序比较简单,直接看程序就能明白原理了。

2函数说明

本程序多个功能函数,分别是:

●DM12232B液晶处理相关函数:

extern void LCDPort_Init(void); //液晶端口初始化

extern void LCD_Init(void); //LCD初始化

extern void WriteCommand(unsigned char chip_select,unsigned char cmd);//写命令

extern void WriteData(unsigned char chip_select,unsigned char data);//写数据

extern void clear_lcd(void); //清屏

extern void tex_Write(unsigned char *pt); //写字符

extern void WriteCharacter(unsigned char *pt); //写汉字

extern void Drawing_Map(unsigned char *pt); //绘图

●延时相关函数:

void Delayus(unsigned int lus); //us延时函数

void Delayms(unsigned int lms); //ms延时函数

由于WINA VR自带函数库中的延时函数使用起来很不方便,并且晶振频率不同,延时时间也有区别,所以本实例中自己写了两个延时函数。

3、使用WINA VR开发环境,使用的是外部12M的晶振,所以需要将makefile文件中的时钟频率修改为12M。另外在程序烧录到单片机的时候,熔丝位也要选择为外部12M晶振(注意是晶振,不是外部振荡器,一定不要选择错了,否则会导致单片机不能再烧写程序)。

4、程序代码

由于本程序代码比较长,所以在此只列出与控制液晶DM12232B相关的部分代码,完整程序放在附件中

//端口初始化

void LCDPort_Init()

{

//LCD数据端口设置

PORTB = 0xff; //

DDRB = 0xFF; //配置端口PB全部为输出口,LCD数据端口

//LCD控制端口设置

SET_RES;

SET_A0;

SET_RW;

SET_E1;

SET_E2;

DDRA = 0xff; //

Delayms(15);

}

//LCD初始化

void LCD_Init()

{

WriteCommand(0x01,0xe2); //rest 复位

WriteCommand(0x02,0xe2);

//WriteCommand(0x01,0xae); //close display 关显示

//WriteCommand(0x02,0xae);

//WriteCommand(0x01,0xa4); //static driver关静态驱动

//WriteCommand(0x02,0xa4);

WriteCommand(0x01,0xa9); //duty 1/32占空比1/32

WriteCommand(0x02,0xa9);

//WriteCommand(0x01,0xa0); //clockwise output ADC选择,顺时针还是逆时针读取RAM数据

//WriteCommand(0x02,0xa0);

//WriteCommand(0x01,0xee); //end 关闭读修改写,无论读或写操作后,列地址都加1 //WriteCommand(0x02,0xee);

//WriteCommand(0x01,0x00); //行地址设置,设置显示RAM的行地址(Y地址)//WriteCommand(0x02,0x00);

//WriteCommand(0x01,0xc0); //显示起始行设置。指定显示器从显示RAM中的那一行开始显示

//数据,(起始行=0)

//WriteCommand(0x02,0xc0);

WriteCommand(0x01,0xaf); //opend display 开显示

WriteCommand(0x02,0xaf);

}

//LCD写指令,

void WriteCommand(unsigned char chip_select,unsigned char cmd)

{

if(chip_select & 1) //判断对左页还是右页的操作

{

SET_E1; //如果是左页,E1使能

}

else if(chip_select & 2) //

{

SET_E2; //右页,E2使能

}

CLR_A0; //A0=0 写命令

CLR_RW; //RW=0 写操作

PORTB = cmd; //写命令数据到数据端口

if(chip_select & 1) //

{

CLR_E1; //关闭左右页使能

}

else if(chip_select & 2) //

{

CLR_E2; //

}

SET_A0; //

SET_RW; //

}

//写数据

void WriteData(unsigned char chip_select,unsigned char data)

{

if(chip_select & 1) //判断左右页

{

SET_E1; //

}

else if(chip_select & 2) //

{

SET_E2; //

}

SET_A0; //A0=1,写数据

CLR_RW; //RW=0,写操作

PORTB = data; //写数据到数据端口

if(chip_select & 1) //

{

CLR_E1; //结束使能

}

else if(chip_select & 2) //

{

CLR_E2; //

}

CLR_A0; //

SET_RW; //

}

//清屏

void clear_lcd(void)

{

unsigned char a,b,c;

for(a = 0xb8;a < 0xbc;a++) //清屏0-3页,指令分别是b8,b9,ba,bb(X地址){

b = 0; //

WriteCommand(0x01,a); //左,第0页开始

WriteCommand(0x02,a); //右,第0页开始

WriteCommand(0x02,b); //右,第0行开始(Y地址)

WriteCommand(0x01,b); // 左,第0行开始

for(c = 0;c < 61;c++) //总共122列,左右各61列

{

WriteData(0x01,0x00); //左,每列均填充0

WriteData(0x02,0x00); //右,每列均填充0

}

}

}

//写字符

void tex_Write(unsigned char *pt)

{

unsigned char a,b;

if(SEL_E1) //左选中?

{

WriteCommand(0x01,0xb8); //页设置,第0页(X地址)

WriteCommand(0x01,Add1); //第0行开始(Y)地址

for(a = 8;a < 16;a++) //

{

WriteData(0x01,*(pt + a)); //上半部分8-16,总高度16,}

WriteCommand(0x01,0xb9); //第一页

WriteCommand(0x01,Add1); //

for(b = 0;b < 8;b++) //

{

WriteData(0x01,*(pt + b)); //下半部分

}

}

else if(SEL_E1 == 0) //若为0,写右半边

{

WriteCommand(0x02,0xb8); //

WriteCommand(0x02,Add1); //

for(a = 8;a < 16;a++) //

{

WriteData(0x02,*(pt + a)); //

}

WriteCommand(0x02,0xb9); //

WriteCommand(0x02,Add1); //

for(b = 0;b < 8;b++) //

{

WriteData(0x02,*(pt + b)); //

}

}

if((Add1 + 8) < 61)

Add1 += 8; //如果不超过61列列地址+8

else //

{

Add1 = 0; //超过61列,则列地址置0,写右半边

WriteCommand(0x02,0xb8); //

WriteCommand(0x02,Add1); //

for(a = 12;a < 16;a++) //一个字符占8列,所以在61列之后还要写4列

WriteData(0x02,*(pt + a)); //

WriteCommand(0x02,0xb9); //

WriteCommand(0x02,Add1); //

for(b = 4;b < 8;b++) //

WriteData(0x02,*(pt + b)); //

Add1 += 4; //

SEL_E1 = 0; //

}

}

// 写汉字

void WriteCharacter(unsigned char *pt)

{

unsigned char a,b;

if(SEL_E2) //

{

WriteCommand(0x01,0xba); //

WriteCommand(0x01,Add2); //

for(a=16;a<32;a++) //

{

WriteData(0x01,*(pt+a)); //

}

WriteCommand(0x01,0xbb); //

WriteCommand(0x01,Add2); //

for(b=0;b<16;b++) //

{

WriteData(0x01,*(pt+b)); //

}

else if(SEL_E2==0) //

{

WriteCommand(0x02,0xba); //

WriteCommand(0x02,Add2); //

for(a=16;a<32;a++) //

{

WriteData(0x02,*(pt+a)); //

}

WriteCommand(0x02,0xbb); //

WriteCommand(0x02,Add2); //

for(b=0;b<16;b++) //

{

WriteData(0x02,*(pt+b)); //

}

}

if((Add2+16)<61)

Add2+=16; //

else

{

Add2=0; //

WriteCommand(0x02,0xba); //

WriteCommand(0x02,Add2); //

for(a=29;a<32;a++)

WriteData(0x02,*(pt+a)); //一个汉字16列,写完61列之后还要写3列

WriteCommand(0x02,0xbb); //

WriteCommand(0x02,Add2); //

for(b=13;b<16;b++)

WriteData(0x02,*(pt+b)); //

Add2+=3; //

SEL_E2=0; //

}

}

//绘图

void Drawing_Map(unsigned char *pt)

{

unsigned char half,seg,page;

unsigned char flag = 1;

for(page = 0xb8;page < 0xbc;page++)

for(half = 0;half < 2;half++)

{

flag = !flag;

if(flag)

{

WriteCommand(0x02,page);

WriteCommand(0x02,0x00);

}

else

{

WriteCommand(0x01,page);

WriteCommand(0x01,0x00);

}

for(seg = 0;seg < 61;seg++)

{

if(flag)

{

WriteData(0x02,*pt++);

}

else

{

WriteData(0x01,*pt++);

}

}

}

}

}

相关文档