89C52单片机液晶汉字显示c语言程序.docx
《89C52单片机液晶汉字显示c语言程序.docx》由会员分享,可在线阅读,更多相关《89C52单片机液晶汉字显示c语言程序.docx(31页珍藏版)》请在冰豆网上搜索。
![89C52单片机液晶汉字显示c语言程序.docx](https://file1.bdocx.com/fileroot1/2022-12/16/f31089e7-967d-45b6-9a63-59de5ca4d8af/f31089e7-967d-45b6-9a63-59de5ca4d8af1.gif)
89C52单片机液晶汉字显示c语言程序
89C52单片机液晶汉字显示c语言程序
*液晶屏分为4行*12列汉字,全部使用模拟接口方式。
/*TGLCMLIMIT64A接口程序(模拟方式)
;**********************单片机液晶汉字显示c语言程序*****************************************************
;连线图:
;*LCM---89C52**LCM---89C52**LCM-------89C52**LCM----------89C52**
;*DB0---P0.0**DB4---P0.4**D/I-------P2.6**CS1----------P2.4**
;*DB1---P0.1**DB5---P0.5**R/W-------P2.7**CS2----------P2.5**
;*DB2---P0.2**DB6---P0.6**RST--------VCC**CS3----------P3.2**
;*DB3---P0.3**DB7---P0.7**E---------P2.3**
;注:
89C52的晶振频率为12MHz*
;*****************************单片机液晶汉字显示c语言程序**********************************************/
//画线部分请参照avr的c程序。
/*#pragmasrc/*生成ASM文件开关,必要时打开*/
#include
#include
#include
#defineUcharunsignedchar
/***********液晶显示器接口引脚定义***************/
sbitElcm=P2^3;//
sbitCS1LCM=P2^4;//
sbitCS2LCM=P2^5;//
sbitCS3LCM=P3^2;/*这个连接只是做实验的临时接法。
*/
sbitDilcm=P2^6;//
sbitRwlcm=P2^7;//
sfrDatalcm=0x80;//数据口
unsignedchartesti[]={"浸渠叁绳漱塔烃威牺晓玄瑶"};
/***********常用操作命令和参数定义***************/
#defineDISPON0x3f/*显示on*/
#defineDISPOFF0x3e/*显示off*/
#defineDISPFIRST0xc0/*显示起始行定义*/
#defineSETX0x40/*X定位设定指令(页)*/
#defineSETY0xb8/*Y定位设定指令(列)*/
#defineLcdbusy0x80/*LCM忙判断位*/
/**************显示分区边界位置*****************/
#defineMODL0x00/*左区*/
#defineMODM0x40/*左区和中区分界*/
#defineMODR0x80/*中区和右区分界*/
#defineLCMLIMIT0xC0/*显示区的右边界*/
/****************全局变量定义*******************/
Ucharcol,row,cbyte;/*列x,行(页)y,输出数据*/
bitxy;/*画线方向标志:
1水平*/
/*****************函数列表**********************/
voidLcminit(void);/*液晶模块初始化*/
voidDelay(Uchar);/*延时,入口数为Ms*/
voidlcdbusyL(void);/*busy判断、等待(左区)*/
voidlcdbusyM(void);/*busy判断、等待(中区)*/
voidlcdbusyR(void);/*busy判断、等待(右区)*/
voidPutedot(Uchar);/*半角字符输出*/
voidPutcdot(Uchar);/*全角(汉字)输出*/
voidWrdata(Uchar);/*数据输出给LCM*/
voidLcmcls(void);/*LCM全屏幕清零(填充0)*/
voidwtcom(void);/*公用busy等待*/
voidLocatexy(void);/*光标定位*/
voidWrcmdL(Uchar);/*左区命令输出*/
voidWrcmdM(Uchar);/*中区命令输出*/
voidWrcmdR(Uchar);/*右区命令输出*/
voidPutstr(Uchar*puts,Uchari);/*中英文字符串输出*/
voidRollscreen(Ucharx);/*屏幕向上滚动演示*/
voidRddata(void);/*从液晶片上读数据*/
voidLinehv(Ucharlength);/*横(竖)方向画线*/
voidpoint(void);/*打点*/
voidLinexy(Ucharendx,Ucharendy);
/******************数组列表*********************/
UcharcodeEzk[];/*ASCII常规字符点阵码表*/
UcharcodeHzk[];/*自用汉字点阵码表*/
UcharcodeSTR1[];/*自定义字符串*/
UcharcodeSTR2[];//
UcharcodeSTR3[];//
UcharcodeSTR4[];//
/********************************/
/*单片机液晶汉字显示c语言程序*/
/********************************/
voidmain(void)
{
Ucharx,y;
col=0;
row=0;
Delay(40);/*延时大约40Ms,等待外设准备好*/
Lcminit();/*液晶模块初始化,包括全屏幕清屏*/
Putstr(STR2,24);/*第一行字符输出,24字节*/
col=0;
row=2;
Putstr(STR1,12);/*第二行字符输出,12字节*/
col=0;
row=4;
Putstr(STR3,24);/*第三行字符输出,24字节*/
col=0;
row=6;
Putstr(STR4,24);/*第四行字符输出,12字节*/
x=0;
col=0;
row=0;
xy=1;/*方向标志。
定为水平方向*/
Linehv(192);/*画一条横线(0,0)-(191,0)*/
col=0;
row=15;
xy=1;
Linehv(192);/*画一条横线(0,15)-(191,15)*/
col=0;
row=32;
xy=1;
Linehv(192);/*画一条横线(0,32)-(191,32)*/
col=0;
row=1;
xy=0;/*方向标志。
定为垂直方向*/
Linehv(31);/*画一条竖线(0,1)-(0,31)*/
col=191;
row=1;
xy=0;
Linehv(31);/*画一条竖线(191,1)-(191,31)*/
col=0;/*设定斜线的起点坐标*/
row=63;
Linexy(44,31);/*画一段斜线(0,63)-(44,31)*/
col=44;
row=31;
Linexy(190,62);/*继续画斜线(44,31)-(191,63)*/
while
(1){
Rollscreen(y);/*定位新的显示起*/
y++;
y%=8;
x=testi[y];
Delay(100);/*延时,控制滚动速度*/
};
}
/************************************************/
/*画线。
任意方向的斜线,不支持垂直的或水平线*/
/************************************************/
voidLinexy(Ucharendx,Ucharendy)
{
registerUchart;
intxerr=0,yerr=0,delta_x,delta_y,distance;
Ucharincx,incy;
/*computethedistanceinbothdirections*/
delta_x=endx-col;
delta_y=endy-row;
/*computethedirectionoftheincrement,
anincrementof"0"meanseitheraverticalorhorizontallines*/
if(delta_x>0)incx=1;
elseif(delta_x==0)incx=0;
elseincx=-1;
if(delta_y>0)incy=1;
elseif(delta_y==0)incy=0;
elseincy=-1;
/*determinewhichdistanceisgreater*/
delta_x=cabs(delta_x);
delta_y=cabs(delta_y);
if(delta_x>delta_y)distance=delta_x;
elsedistance=delta_y;
/*drawtheline*/
for(t=0;t<=distance+1;t++){
point();
xerr+=delta_x;
yerr+=delta_y;
if(xerr>distance){
xerr-=distance;
col+=incx;
}
if(yerr>distance){
yerr-=distance;
row+=incy;
}
}
}
/****************************************/
/*画线。
只提供X或Y方向的,不支持斜线*/
/****************************************/
voidLinehv(Ucharlength)
{
Ucharxs,ys;
if(xy){ys=col;
for(xs=0;xscol=ys+xs;
point();}
}
else{xs=row;
for(ys=0;ysrow=xs+ys;
point();}
}
}
/***************单片机液晶汉字显示c语言程序*************************/
/*画点*/
/****************************************/
voidpoint(void)
{
Ucharx1,y1,x,y;
x1=col;
y1=row;
row=y1>>3;/*取Y方向分页地址*/
Rddata();
y=y1&0x07;/*字节内位置计算*/
x=0x01;
x=x<Wrdata(cbyte|x);/*画上屏幕*/
col=x1;/*恢复xy坐标*/
row=y1;
}
/****************************************/
/*屏幕滚动定位*/
/****************************************/
voidRollscreen(Ucharx)
{
cbyte=DISPFIRST|x;/*定义显示起始行为x?
*/
WrcmdL(cbyte);
WrcmdM(cbyte);
WrcmdR(cbyte);
}
/****************************************/
/*一个字串的输出*/
/****************************************/
voidPutstr(Uchar*puts,Uchari)
{
Ucharj,X;
for(j=0;j
{
X=puts[j];
if(X&0x80)
{
Putcdot(X&0x7f);/*只保留低7位*/
}
elsePutedot(X-0x20);/*ascii码表从0x20开始*/
}
}
/****************************************/
/*半角字符点阵码数据输出*/
/****************************************/
voidPutedot(UcharOrder)
{
Uchari,bakerx,bakery;/*共定义4个局部变量*/
intx;/*偏移量,字符量少的可以定义为UCHAR*/
bakerx=col;/*暂存x,y坐标,已备下半个字符使用*/
bakery=row;
x=Order*0x10;/*半角字符,每个字符16字节*/
/*上半个字符输出,8列*/
for(i=0;i<8;i++)
{
cbyte=Ezk[x];/*取点阵码,rom数组*/
Wrdata(cbyte);/*写输出一字节*/
x++;
col++;
if(col==LCMLIMIT){col=0;row++;row++;};/*下一列,如果列越界换行*/
if(row>7)row=0;/*如果行越界,返回首行*/
}/*上半个字符输出结束*/
col=bakerx;/*列对齐*/
row=bakery+1;/*指向下半个字符行*/
/*下半个字符输出,8列*/
for(i=0;i<8;i++)
{
cbyte=Ezk[x];/*取点阵码*/
Wrdata(cbyte);/*写输出一字节*/
x++;
col++;
if(col==LCMLIMIT){col=0;row=row+2;};/*下一列,如果列越界换行*/
if(row>7)row=1;/*如果行越界,返回首行*/
}/*下半个字符输出结束*/
row=bakery;
}/*整个字符输出结束*/
/****************************************/
/*全角字符点阵码数据输出*/
/****************************************/
voidPutcdot(UcharOrder)
{
Uchari,bakerx,bakery;/*共定义3个局部变量*/
intx;/*偏移量,字符量少的可以定义为UCHAR*/
bakerx=col;/*暂存x,y坐标,已备下半个字符使用*/
bakery=row;
x=Order*0x20;/*每个字符32字节*/
/*上半个字符输出,16列*/
for(i=0;i<16;i++)
{
Wrdata(Hzk[x]);/*写输出一字节*/
x++;
col++;
if(col==LCMLIMIT){col=0;row++;row++;}/*下一列,如果列越界换行*/
if(row>6)row=0;/*如果行越界,返回首行*/
}/*上半个字符输出结束*/
/*下半个字符输出,16列*/
col=bakerx;
row=bakery+1;
for(i=0;i<16;i++)/*下半部分*/
{
Wrdata(Hzk[x]);
x++;
col++;
if(col==LCMLIMIT){col=0;row++;row++;}/*下一列,如果列越界换行*/
if(row>7)row=1;/*如果行越界,返回首行*/
}/*下半个字符输出结束*/
row=bakery;
}/*整个字符输出结束*/
/****************************************/
/*清屏,全屏幕清零*/
/****************************************/
voidLcmcls(void)
{
for(row=0;row<8;row++)
for(col=0;col}
/****************************************/
/*从液晶片上读数据,保留在全局变量中*/
/****************************************/
voidRddata(void)
{
Locatexy();/*坐标定位,返回时保留分区状态不变*/
Datalcm=0xFF;
Dilcm=1;/*数据*/
Rwlcm=1;/*读数据*/
Elcm=1;/*读入到LCM*/
_nop_();
cbyte=Datalcm;/*虚读一次*/
Elcm=0;
Locatexy();/*坐标定位,返回时保留分区状态不变*/
Datalcm=0xFF;
_nop_();
Dilcm=1;/*数据*/
Rwlcm=1;/*读数据*/
Elcm=1;/*读入到LCM*/
_nop_();
cbyte=Datalcm;/*从数据口读数据,真读*/
Elcm=0;
}
/****************************************/
/*数据写输出*/
/****************************************/
voidWrdata(UcharX)
{
Locatexy();/*坐标定位,返回时保留分区状态不变*/
//wtcom();
Dilcm=1;/*数据输出*/
Rwlcm=0;/*写输出*/
Datalcm=X;/*数据输出到数据口*/
Elcm=1;/*读入到LCM*/
_nop_();
Elcm=0;
}
/****************************************/
/*命令输出,每次输出一个分区控制口*/
/****************************************/
/*voidWrcmd(UcharX)
//{
//Locatexy();/*确定分区,返回时保留分区状态不变*/
//wtcom();/*等待LCM操作允许*/
//Dilcm=0;/*数据操作*/
//Rwlcm=0;/*写输出*/
//Datalcm=X;/*数据输出到数据口*/
//Elcm=1;_nop_();Elcm=0;/*读入到LCM*/
//}
/********************************/
/*命令输出到左区控制口*/
/********************************/
voidWrcmdL(UcharX)
{
lcdbusyL();/*确定分区,返回时保留分区状态不变*/
Dilcm=0;/*命令操作*/
Rwlcm=0;/*写输出*/
Datalcm=X;/*数据输出到数据口*/
Elcm=1;_nop_();Elcm=0;/*读入到LCM*/
}
/********************************/
/*命令输出到中区控制口*/
/********************************/
voidWrcmdM(UcharX)
{
lcdbusyM();/*确定分区,返回时保留分区状态不变*/
Dilcm=0;/*命令操作*/
Rwlcm=0;/*写输出*/
Datalcm=X;/*命令输出到数据口*/
Elcm=1;_nop_();Elcm=0;/*读入到LCM*/
}
/********************************/
/*命令输出到右区控制口*/
/********************************/
voidWrcmdR(UcharX)
{
lcdbusyR();/*确定分区,返回时保留分区状态不变*/
Dilcm=0;/*命令操作*/
Rwlcm=0;/*写输出*/
Datalcm=X;/*命令输出到数据口*/
Elcm=1;_nop_();Elcm=0;/*读入到LCM*/
}
/*****************单片机液晶汉字显示c语言程序***************************************/
/*分区操作允许等待,返回时保留分区选择状态*/
/********************************************************/
voidlcdbu