基于51单片机的内含汉字库的LCM(一)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
内含汉字库的液晶显示模块(LCM),在软件仿真(proteus)的元件库中不会有这种模块,尤其是内含汉字库的模块,proteus的元件库中永远也不会有。因而在51单片机的学习入门后,再继续深入或开发设计,则应采用硬件仿真调试的方法,因此这时需要配备一台51单片机的硬件仿真器(价格约几百元)。
⒈ LCM简介
本人使用的液晶显示模块是P-12864D-GB,它内置ST7290控制器,是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块。其显示分辨率为128X64,内置8192个16X16点汉字,和128个16X8点ASCII字符集。利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。可以显示8X4行16X16点阵的汉字,也可以完成图形显示。
该模块的引脚说明如下。
引脚号 | 引脚说明 | 电平 | 引脚功能 |
1 | VSS | 0V | 电源地 |
2 | VCC | +5V | 电源正 |
3 | N.C |
| 空脚 |
4 | RS(CS) | H/L | 并行的指令/数据选择信号,串行的片选信号 |
5 | R/W(SID) | H/L | 并行的读/写选择信号,串行的数据口 |
6 | E(CLK) | H/L | 并行的使能信号,串行的同步时钟 |
7 | DB0 | H/L | 数据位0 |
8 | DB1 | H/L | 数据位1 |
9 | DB2 | H/L | 数据位2 |
10 | DB3 | H/L | 数据位3 |
11 | DB4 | H/L | 数据位4 |
12 | DB5 | H/L | 数据位5 |
13 | DB6 | H/L | 数据位6 |
14 | DB7 | H/L | 数据位7 |
15 | LED_A | +5V | 背光电源正 |
16 | LED_K | 0V | 背光电源负 |
LCM控制芯片提供两套控制命令:基本指令和扩充指令,如下表所示。
基本指令(RE=0)
指令 | 指 令 码 | 功 能 | |||||||||
RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | ||
清除 显示 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 | 将DDRAM填满20H,并且设定DDRAM的地址计数器(AC)到00H |
地址 归位 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
X | 设定DDRAM的地址计数器(AC)到00H,并且将游标移到开头原点位置。这个指令不改变DDRAM的内容 |
显示状态开关 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
D |
C |
B | D=1:整体显示ON C=1:游标ON B=1:游标位置反白允许 |
进入点设定 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 | I /D |
S | 指定在数据的读取与写入时设定游标的移动方向及指定显示的移位 |
游标显示移位控制 |
0 |
0 |
0 |
0 |
0 |
1 | S /C | R /L |
X |
X | 设定游标的移动与显示的移位控制位。这个指令不改变DDRAM的内容 |
功能设定 |
0 |
0 |
0 |
0 |
1 |
DL |
X |
RE |
X |
X | DL=0/1:4/8位数据 RE=1:扩充指令操作 RE=0:基本指令操作 |
设定CGRAM地址 |
0 |
0 |
0 |
1 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 |
设定CGRAM地址 |
设定DDRAM地址 | 0 | 0 | 1 | 0 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 | 设定DDRAM地址 第一行:80H~87H 第二行:90H~97H |
读取忙标志和地址 |
0 |
1 |
BF |
AC6 |
AC5 |
AC4 |
AC3 |
AC2 |
AC1 |
AC0 | 读取忙标志(BF)可以确定内 部动作是否完成,同时可以读出地址计数器(AC)的值 |
写数据到RAM | 1 | 0 | 数 据 | 将数据D7~D0写入到内部的RAM(DDRAM/CGRAM/IRAM/GRAM) | |||||||
读出RAM的值 |
1 |
1 | 数 据 | 从内部RAM读取数据D7~D0(DDRAM/CGRAM/IRAM/ GRAM) |
扩充指令(RE=1)
指令 | 指 令 码 | 功 能 | |||||||||
RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | ||
待命 模式 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 进入待命模式,执行其它指令后都可终止 |
卷动地址开关开启 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
SR | SR=1:允许输入垂直卷动地址 SR=0:允许输入IRAM和CGRAM地址 |
反白 选择 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
R1 |
R0 | 选择2行中的任一行作反白显示,并可决定反白与否。初始值R1R0=00,第一次设定为反白显示,再次设定变回正常 |
睡眠 模式 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | SL | X | X | SL=1:进入睡眠模式 SL=0:脱离睡眠模式 |
扩充 功能 设定 |
0 |
0 |
0 |
0 |
1 |
CL |
X |
RE |
G |
0 | CL=0/1:4/8位数据 RE=1/0:扩充/基本指令操作 G=1/0:绘图开/关 |
特定 绘图RAM地址 | 0 | 0 | 1 | 0 AC6 | 0 AC5 | 0 AC4 | AC3 AC3 | AC2 AC2 | AC1 AC1 | AC0 AC0 | 设定绘图RAM,先设定垂直(列)地址AC6AC5…AC0,再设定水平(行)地址AC3AC2…AC0 |
12864LCM每屏可显示4行8列共32个16x16点阵的汉字,字符显示的地址为80H~9FH,如下所示。
80H | 81H | 82H | 83H | 84H | 85H | 86H | 87H |
90H | 91H | 92H | 93H | 94H | 95H | 96H | 97H |
88H | 89H | 8AH | 8BH | 8CH | 8DH | 8EH | 8FH |
98H | 99H | 9AH | 9BH | 9CH | 9DH | 9EH | 9FH |
该模块是点阵图形式液晶显示模块,故也可以用于显示图形。显示图形时,每行需16个字节的点阵数据,每屏64行,因此每一屏图形需16x64字节的点阵数据。
有关本模块的其它内容可参考有关书籍或网上文章。
⒉ 硬件设计
当CPU芯片采用AT89S52,液晶显示器采用128x64LCM并行8位的电原理图如下所示。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
⒊ 软件设计
用内含汉字库的LCM显示汉字非常方便,它可以显示四行,每行八个汉字,正好一屏可以显示一首唐诗;它又具有点阵图形显示功能。用一屏显示一首唐诗,另一屏显示一幅图形的流程图如下所示。
用一屏显示一首唐诗,另一屏显示一幅图形的详细C51程序如下所示。
/************************************
*带汉字库的128*64LCD
*显示一首唐诗和电脑桌面图像,12MHz晶体
*************************************/
#include "reg51.h"
#define uint unsigned int
#define uchar unsigned char
sbit RS="P2"^0;
sbit RW="P2"^1;
sbit E="P2"^2;
/**** 延时t毫秒 *****/
void delay1(uint t)
{
uint i;
while(t--)
{
for (i=0;i<125;i++)
; /* 对于12M时钟,约延时1ms */
}
}
/*******************
*写指令子函数
********************/
comm(uchar COM)
{
RS=0;RW=0;E=1;P0=COM;
delay1(2);
E=0;RS=1;RW=1;
}
/***************
*写数据子函数
****************/
dataa(uchar datt)
{
RS=1;RW=0;E=1;P0=datt;
delay1(2);
E=0;RS=0;RW=1;
}
//朝辞白帝彩云间,
uchar code tab1[]={0xb3,0xaf,0xb4,0xc7,0xb0,0xd7,0xb5,0xdb,
0xb2,0xca,0xd4,0xc6,0xbc,0xe4,0xa3,0xac};
//千里江陵一日还,
uchar code tab2[]={0xc7,0xa7,0xc0,0xef,0xbd,0xad,0xc1,0xea,
0xd2,0xbb,0xc8,0xd5,0xbb,0xb9,0xa3,0xac};
//两岸猿声啼不住,
uchar code tab3[]={0xc1,0xbd,0xb0,0xb6,0xd4,0xb3,0xc9,0xf9,
0xcc,0xe4,0xb2,0xbb,0xd7,0xa1,0xa3,0xac};
//轻舟已过万重山。
uchar code tab4[]={0xc7,0xe1,0xd6,0xdb,0xd2,0xd1,0xb9,0xfd,
0xcd,0xf2,0xd6,0xd8,0xc9,0xbd,0xa1,0xa3};
/********电脑桌面数据********************/
uchar code dnzm[]=
{
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xF0,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x18,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0xFF,0xDC,0x00,0x01,
0x80,0x00,0x1F,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0xFF,0xBC,0x00,0x01,
0x80,0x00,0x30,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x01,0x7F,0xFF,0xB8,0x00,0x01,
0x80,0x00,0x30,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x01,0x7F,0xFF,0x78,0x00,0x01,
0x80,0x00,0x19,0xFF,0xFE,0xC0,0x00,0x00,0x00,0x00,0x02,0xFF,0xFF,0x70,0x00,0x01,
0x80,0x00,0x18,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0xFF,0xFE,0xF0,0x00,0x01,
0x80,0x00,0x0C,0x01,0xFF,0x60,0x00,0x00,0x00,0x00,0x05,0xFF,0xFE,0xE0,0x00,0x01,
0x80,0x00,0x0C,0x7F,0xD0,0x20,0x00,0x00,0x00,0x00,0x05,0xFF,0xFD,0xE0,0x00,0x01,
0x80,0x00,0x06,0x00,0x0F,0xB0,0x00,0x00,0x00,0x00,0x0B,0xFF,0xFD,0xC0,0x00,0x01,
0x80,0x00,0x06,0x03,0xFC,0x10,0x00,0x00,0x00,0x00,0x0B,0xFF,0xFB,0xC0,0x00,0x01,
0x80,0x00,0x03,0x1F,0x00,0x18,0x00,0x00,0x00,0x00,0x17,0xFF,0xFB,0x80,0x00,0x01,
0x80,0x00,0x03,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x17,0xFF,0xF7,0x80,0x00,0x01,
0x80,0x00,0x01,0x80,0x00,0x0C,0x00,0x00,0x00,0x00,0x17,0xFF,0xF7,0x00,0x00,0x01,
0x80,0x00,0x01,0x80,0x00,0x04,0x00,0x00,0x00,0x00,0x09,0xFF,0xEF,0x00,0x00,0x01,
0x80,0x00,0x00,0xC0,0x00,0xF6,0x00,0x00,0x00,0x00,0x06,0x7F,0xEF,0x00,0x00,0x01,
0x80,0x00,0x00,0xC0,0x03,0xC2,0x00,0x00,0x00,0x00,0x01,0x9F,0xDE,0x00,0x00,0x01,
0x80,0x00,0x00,0x60,0x00,0x3B,0x00,0x00,0x00,0x00,0x00,0x67,0xDF,0x00,0x00,0x01,
0x80,0x00,0x00,0x60,0x00,0xE3,0x00,0x00,0x00,0x00,0x00,0x19,0xBF,0x00,0x00,0x01,
0x80,0x00,0x00,0x30,0x03,0x8E,0x00,0x00,0x00,0x00,0x00,0x06,0x3F,0x00,0x00,0x01,
0x80,0x00,0x00,0x30,0x06,0x3C,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xC0,0x00,0x01,
0x80,0x00,0x00,0x18,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xEF,0x00,0x00,0x01,
0x80,0x00,0x00,0x18,0x03,0xC0,0x00,0x00,0x00,0x00,0x00,0x0F,0x1F,0x80,0x00,0x01,
0x80,0x00,0x00,0x0C,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1F,0xC0,0x00,0x01,
0x80,0x00,0x00,0x0C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x07,0xE0,0x00,0x01,
0x80,0x00,0x00,0x06,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x1F,0xE0,0x00,0x01,
0x80,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0xC0,0x00,0x01,
0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0xFF,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFC,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF0,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x05,0x40,0x88,0x04,0x01,0x08,0x00,0x00,0x0A,0x81,0x10,0x04,0x00,0x20,0x01,
0x80,0x79,0x21,0x08,0x02,0x21,0x49,0x00,0x00,0xF2,0x42,0x10,0x04,0x47,0x10,0x01,
0x80,0x09,0x07,0xDF,0x7F,0xF7,0xAA,0x00,0x00,0x12,0x0F,0xBE,0x7F,0xE5,0xFE,0x01,
0x80,0x7F,0xF4,0x51,0x08,0x81,0x2C,0x00,0x00,0xFF,0xE8,0xA2,0x44,0x47,0x00,0x01,
0x80,0x09,0x04,0x61,0x08,0x81,0x7F,0x00,0x00,0x12,0x08,0xC2,0x7F,0xC5,0x4A,0x01,
0x80,0x0B,0x24,0x51,0x08,0x83,0x81,0x00,0x00,0x16,0x48,0xA2,0x44,0x45,0x6A,0x01,
0x80,0x1D,0x47,0xC9,0x05,0x05,0x01,0x00,0x00,0x3A,0x8F,0x92,0x44,0x47,0x52,0x01,
0x80,0x68,0x84,0x49,0x05,0x05,0x7F,0x00,0x00,0xD1,0x08,0x92,0x7F,0xC5,0x6A,0x01,
0x80,0x09,0x94,0x41,0x02,0x01,0x01,0x00,0x00,0x13,0x28,0x82,0x44,0x05,0x4A,0x01,
0x80,0x0E,0x57,0xC1,0x0D,0x81,0x01,0x00,0x00,0x1C,0xAF,0x82,0x04,0x29,0x42,0x01,
0x80,0x38,0x34,0x4E,0x70,0x71,0x7F,0x00,0x00,0x70,0x68,0x9C,0x03,0xEB,0x7E,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
};
/*********显示图形子函数**********/
void display_photo()
{
uchar i,j,k=0x80;
comm(0x3c); //设置8BIT控制,绘图OFF
for(i=0;i<32;i++)
{
comm(k); //设置绘图区的Y地址坐标
k=k+1;
comm(0x80); //设置绘图区的X地址坐标
for(j=0;j<16;j++)
{
dataa(dnzm[i*16+j]); //写入上半屏数据
}
}
k=0x80;
for(i=0;i<32;i++)
{
comm(k); //设置绘图区的Y地址坐标
k=k+1;
comm(0x88); //设置绘图区的X地址坐标
for(j=0;j<16;j++)
{
dataa(dnzm[512+i*16+j]); //写入下半屏数据
}
}
comm(0x38); //设置8位
comm(0x01); //清屏
comm(0x3e); //设置8BIT控制,绘图ON(显示图形)
}
main()
{
uchar i;
for(i=0;i<3;i++)
{ //LCD可靠复位
RS=0;RW=0;E=1;
delay1(10);
P0=0X30;E=0;RS=1;RW=1;
}
while(1)
{
comm(0x38); //设置8位,四行
comm(0x01); //清屏
comm(0x80); //设置第一行首址
for(i=0;i<16;i++)
dataa(tab1);
comm(0x90); //设置第二行首址
for(i=0;i<16;i++)
dataa(tab2);
comm(0x88); //设置第三行首址
for(i=0;i<16;i++)
dataa(tab3);
comm(0x98); //设置第四行首址
for(i=0;i<16;i++)
dataa(tab4);
display_photo();
delay1(2000);
}
}
启动MedWin V3.0,执行菜单命令“项目管理”→“新建项目”创建项目(或利用原有项目),然后再执行菜单命令“项目管理”→“新建文件”,在编辑窗口中输入上述源程序,经编译无误后,在构建窗口中将显示无错误。注意:需执行菜单命令“设置”→“设置编译工具”→点选“指定路径下的编译工具”(该软件默认的是汇编语言),将C51文件夹放在适当的路径(可利用Keil中的C51)。
⒋ 仿真调试
本人使用的硬件仿真器是万利公司的“ME-52HU”,将仿真头插入目标板中的CPU插座,先后接通目标板和仿真器的电源,点击快捷按钮“产生代码并装入”,将出现十几个调试的快捷按钮,此时可以点击某个快捷按钮进行调试。当点击“全速运行”按钮时,将会先后显示一首唐诗和电脑桌面图形,如下所示。
本人邮箱:txxyc104@163.com,欢迎来信讨论.
文章评论(0条评论)
登录后参与讨论