//写汉字液晶程序 液晶屏分为4行/8列汉字,全部使用模拟接口方式。
///////////////////////////////////////////////////////////////////////////////////////////////////
连线图: /
/LCM---89C52/ /LCM---89C52/ /LCM-------89C52/ /LCM----------89C52/ /
/DB0---P1.0/ /DB4---P1.4/ /D/I-------P2.3/ /CS1----------P2.0/ /
/DB1---P1.1/ /DB5---P1.5/ /R/W-------P2.2/ /CS2----------P2.1/ /
/DB2---P1.2/ /DB6---P1.6/ /E---------P2.4/ /EL-E---------P3.4/ /
/DB3---P1.3/ /DB7---P1.7/ /RST-------VCC /EL-D---------VCC /
注:89C52的晶振频率为12MHz /
////////////////////////////////////////////////////////////////////////////////////////////////////
#include
#include
#define Uchar unsigned char
#define _Nop() _nop_() //定义空指令//
/////////////////全局变量定义///////////////////
Uchar col,row,cbyte,keyd,t,Signal; //列y,行(页)x,输出数据;keyd为键值;t为数组下标;Signal为触发传感器的编号 //
Uchar buf[10]; //保存,显示数据缓冲区//
////////////液晶显示器接口引脚定义////////////////
sbit EL_E= P3^4; //背景光控制脚
sbit Elcm= P2^4; //
sbit CS1LCM= P2^0; //
sbit CS2LCM= P2^1; //
sbit Dilcm= P2^3; //
sbit Rwlcm= P2^2; //
sfr Datalcm= 0x90; //数据口.即P1口地址
sbit PL= P3^5; //接74HC164的PL脚,并行数据锁入使能,低电平有效
////////////常用操作命令和参数定义////////////////
#define DISPON 0x3f //显示on //
#define DISPOFF 0x3e //显示off //
#define DISPFIRST 0xc0 //显示起始行定义 //
#define SETX 0xb8 //X定位设定指令(页) //
#define SETY 0x40 //Y定位设定指令(列) //
#define Lcdbusy 0x80 //LCM忙判断位 //
///////////////显示分区边界位置//////////////////
#define MODL 0x00 //左区 //
#define MODM 0x40 //左区和右区分界 //
#define LCMLIMIT 0x80 //显示区的右边界 //
//////////////////函数列表///////////////////////
void InputNo(void);
void ShowPage(void);
void input(void);
void LookOver(void);
void Drawing(void);
void Save(void);
void ProcessSgl(void);
///////////////////数组列表//////////////////////
Uchar code Ezk[]; //ASCII常规字符点阵码表 //
Uchar code Hzk[]; //自用汉字点阵码表 //
Uchar code KJHM[]; //开机画面点阵码表 //
//////////////////////////////////
//定义字符串数组 //
//////////////////////////////////
Uchar code BH[]={0x80,0x81,0x23,0x25,0x25};
Uchar code JL[]={0x82,0x83,0x23,0x25,0x25,0x25,0x25,0x8b,0x8c}; //9个字节
Uchar code FW[]={0x84,0x85,0x23,0x25,0x25,0x25,0x25,0x86,0x85};
Uchar code BC[]={0x89,0x8a,0x9e,0x9f,0xa1,0x22}; //保存??//
Uchar code LX[]={0x87,0x88,0x23};
Uchar code ZD[]={0x8d,0x8e,0x93};
Uchar code HZ[]={0x8f,0x90,0x93};
Uchar code ZS[]={0x91,0x92,0x93};
Uchar code XD[]={0x94,0x95,0x96,0x97};
Uchar code YJ[]={0x98,0x99};
Uchar code SR[]={0xa0,0x9a,0x9b,0x9e,0x9f};
Uchar code CK[]={0x9a,0x9b,0x80,0x81,0x9c,0x9d,0x9e,0x9f};
//状态标志//
bit ack; //应答标志位//
///////////////////////////液晶子程序//////////////////////////////
//公用busy等待//
void wtcom(void)
{
Dilcm = 0; //CLR DI 命令操作 //
Rwlcm = 1; //SETB RW 读操作 //
Datalcm = 0xFF; //用作输入时,口锁存器必须先写1 //
Elcm = 1;_nop_();
while(Datalcm & Lcdbusy);
Elcm = 0;
}
//////////////////////////////////////////////////////////
// 分区操作允许等待,返回时保留分区选择状态 //
//////////////////////////////////////////////////////////
void lcdbusyL(void)
{
CS1LCM = 1; //CLR CS1 //
CS2LCM = 0; //SETB CS2 //
wtcom(); // waitting for enable //
}
void lcdbusyR(void)
{
CS1LCM = 0; //SETB CS1 //
CS2LCM = 1; //SETB CS2 //
wtcom(); // waitting for enable //
}
//////////////////////////////////
// 命令输出到左区控制口 //
//////////////////////////////////
void WrcmdL(Uchar X)
{
lcdbusyL(); //确定分区,返回时保留分区状态不变//
Dilcm = 0; //命令操作 //
Rwlcm = 0; //写输出 //
Datalcm = X; //数据输出到数据口 //
Elcm = 1;_nop_();Elcm = 0; //下降沿,写入到LCM//
}
//////////////////////////////////
// 命令输出到右区控制口 //
//////////////////////////////////
void WrcmdR(Uchar X)
{
lcdbusyR(); //确定分区,返回时保留分区状态不变 //
Dilcm = 0; //命令操作 //
Rwlcm = 0; //写输出 //
Datalcm = X; //命令输出到数据口 //
Elcm = 1;_nop_();Elcm = 0; //读入到LCM//
}
//////////////////////////////////////////////////////////
//根据设定的坐标数据,定位LCM上的下一个操作单元位置 //
//////////////////////////////////////////////////////////
void Locatexy(void)
{
unsigned char x,y;
y = col&0x3F|SETY; // col.and.0x3f.or.setx //
x = row&0x07|SETX; // row.and.0x07.or.sety //
switch (col&0xc0) // col.and.0xC0 //
{ //条件分支执行 //
case 0: {WrcmdL(y);
WrcmdL(x);
break;} //左区 //
case 0x40:{WrcmdR(y);
WrcmdR(x);
break;} //右区 //
}
}
[page]
//////////////////////////////////////////////
// 从液晶片上读数据,保留在全局变量cbyte中 //
//////////////////////////////////////////////
void Rddata(void)
{
Locatexy(); //坐标定位,返回时保留分区状态不变 //
Datalcm=0xFF;
wtcom(); // waitting for enable //
Dilcm = 1; //数据//
Rwlcm = 1; //读数据//
Elcm = 1; //读入到LCM//
_nop_();
cbyte = Datalcm; //虚读一次 //
Elcm = 0;
Locatexy(); //坐标定位,返回时保留分区状态不变 //
Datalcm=0xFF;
wtcom(); // waitting for enable //
Dilcm = 1; //数据//
Rwlcm = 1; //读数据//
Elcm = 1; //读入到LCM//
_nop_();
cbyte = Datalcm; //从数据口读数据,真读 //
Elcm = 0;
}
///////////////////////////////////////////
/// 数据写入 //
///////////////////////////////////////////
void Wrdata(Uchar X)
{
Locatexy(); ///坐标定位,返回时保留分区状态不变 //
wtcom();
Dilcm = 1; ///数据输出//
Rwlcm = 0; ///写输出 //
Datalcm = X; ///数据输出到数据口 //
Elcm = 1; ////读入到LCM//
_nop_();
Elcm = 0;
}
///////////////////////////////////////////
/// 清屏,全屏幕清零 //
///////////////////////////////////////////
void Lcmcls( void )
{
for(row=0;row<8;row++)
for(col=0;col
}
///////////////////////////////////
///液晶屏初始化 //
///////////////////////////////////
void Lcminit(void)
{
cbyte = DISPOFF; ///关闭显示屏 //
WrcmdL(cbyte);
WrcmdR(cbyte);
cbyte = DISPON; ///打开显示屏 //
WrcmdL(cbyte);
WrcmdR(cbyte);
cbyte = DISPFIRST; ///定义显示起始行为零 //
WrcmdL(cbyte);
WrcmdR(cbyte);
Lcmcls();
col=0; //清屏 //
row=0;
Locatexy();
}
///////////////////////////////////
/// 延时 //
///////////////////////////////////
void Delay(Uchar MS)
{
Uchar us,usn;
while(MS!=0)
{ usn = 4;
while(usn!=0)
{
us=0xf0;
while (us!=0){us--;};
usn--;
}
MS--;
}
}
/////////////////////////////////////////////////////////
// 半角字符(西文字符库)点阵码数据输出16/16 //
/////////////////////////////////////////////////////////
void Putedot(Uchar Order)
{
Uchar i,bakerx,bakery; //共定义4个局部变量 //
int x; //偏移量,字符量少的可以定义为UCHAR //
bakerx = row; //暂存x,y坐标,已备下半个字符使用 //
bakery = col;
x=Order / 0x10; //半角字符,每个字符16字节 //
///上半个字符输出,8列 //
for(i=0;i<8;i++)
{
cbyte = Ezk[x]; ///取点阵码,rom数组 //
Wrdata(cbyte); ///写输出一字节 //
x++;
col++;
} ///上半个字符输出结束 //
col = bakery; ///列对齐 //
row = bakerx+1; ///指向下半个字符行 //
///下半个字符输出,8列 //
for(i=0;i<8;i++)
{
cbyte = Ezk[x]; ///取点阵码 //
Wrdata(cbyte); ///写输出一字节 //
x++;
col++;
} ///下半个字符输出结束 //
row=bakerx;
} ///整个字符输出结束 //
/////////////////////////////////////////////////////
/// 全角字符(汉字库)点阵码数据输出16/32 //
/////////////////////////////////////////////////////
void Putcdot(Uchar Order)
{
Uchar i,bakerx,bakery; ///共定义3个局部变量 //
int x; ///偏移量,字符量少的可以定义为UCHAR //
bakerx = row; / / //暂存x,y坐标,已备下半个字符使用 //
bakery = col;
x=Order / 0x20; ///每个字符32字节 //
///上半个字符输出,16列 //
for(i=0;i<16;i++)
{
Wrdata(Hzk[x]); / //写输出一字节 //
x++;
col++;
} ///上半个字符输出结束 //
///下半个字符输出,16列 //
col = bakery;
row = bakerx+1;
for(i=0;i<16;i++) / //下半部分//
{
Wrdata(Hzk[x]);
x++;
col++;
} //下半个字符输出结束 //
row = bakerx;
} //整个字符输出结束 //
/////////////////////////////////////////////////////////////////////////////
/// 一个字串的输出.第一个参数为一个字符串,第二个参数为此字符串的字节数 //
/////////////////////////////////////////////////////////////////////////////
void Putstr(Uchar /puts,Uchar i)
{
Uchar j,X;
for (j=0;j
{
X = puts[j];
if (X&0x80)
{
Putcdot(X&0x7f); / //只保留低7位//
}
else Putedot(X-0x20); / //ascii码表从0x20开始//
if (col==LCMLIMIT){col=0;row+=2;}; ///下一列,如果列越界换行//
if (row>6) row=0; ///如果行越界,返回首行 //
}
}