#include<reg51.h>
#include<math.h>
#include<INTRINS.H>
#define Uchar unsigned char
/*注:8031的晶振频率为12MHz*/
/***********液晶显示器接口引脚定义***************/
sbit Elcm=P2^7;
sbit CSALCM= P2^2;
sbit CSBLCM= P2^3;
sbit Dilcm=P2^0;
sbit Rwlcm=P2^1;
sfr Datalcm=0x80; /*数据口*/
/***********常用操作命令和参数定义***************/
#define DISPON 0x3f /*显示on*/
#define DISPOFF 0x3e /*显示off */
#define DISPFIRST 0xc0 /*显示起始行定义*/
#define SETX 0x40 /*X定位设定指令(页)*/
#define SETY 0xb8 /*Y定位设定指令(列)*/
#define Lcdbusy 0x80 /*LCM忙判断位*/
/**************显示分区边界位置*****************/
#define MODL 0x00 /*左区*/
#define MODM 0x40 /*左区和中区分界*/
#define MODR 0x80 /*中区和右区分界*/
#define LCMLIMIT 0xC0 /*显示区的右边界*/
/****************全局变量定义*******************/
Uchar col,row,cbyte; /*列x,行(页)y,输出数据*/
bit xy; /*画线方向标志:1水平*/
/*****************函数列表**********************/
void Lcminit(void); /*液晶模块初始化*/
void Delay(Uchar); /*延时,入口数为Ms */
void lcdbusyL(void); /*busy判断、等待(左区)*/
void lcdbusyM(void); /*busy判断、等待(中区)*/
void lcdbusyR(void); /*busy判断、等待(右区)*/
void Putedot(Uchar); /*半角字符输出*/
void Putcdot(Uchar); /*全角(汉字)输出*/
void Wrdata(Uchar); /*数据输出给LCM*/
void Lcmcls( void ); /*LCM全屏幕清零(填充0) */
void wtcom(void); /*公用busy等待*/
void Locatexy(void); /*光标定位*/
void WrcmdL(Uchar); /*左区命令输出 */
void WrcmdM(Uchar); /*中区命令输出 */
void WrcmdR(Uchar); /*右区命令输出 */
void Putstr(Uchar *puts,Uchar i); /*中英文字符串输出*/
void Rollscreen(Uchar x); /*屏幕向上滚动*/
void Rddata(void); /*从液晶片上读数据*/
void Linehv(Uchar length); /*横(竖)方向画线*/
void point(void); /*打点*/
void Linexy(Uchar endx,Uchar endy);
/******************数组列表*********************/
Uchar code Ezk[]; /*ASCII常规字符点阵码表 */
Uchar code Hzk[]; /*自用汉字点阵码表*/
Uchar code STR1[]; /*自定义字符串*/
Uchar code STR2[];
Uchar code STR3[];
Uchar code STR4[];
/****************************************主程序*****************************************/
void main(void)
{
Uchar x;
col=0;
row=0;
Delay(40); /*延时大约40Ms,等待外设准备好*/
Lcminit(); /*液晶模块初始化,包括全屏幕清屏*/
Putstr(STR1,12); /*第一行字符输出,12字节*/
col=0;
row=2;
Putstr(STR2,14); /*第二行字符输出,14字节*/
col=0;
row=4;
Putstr(STR3,11); /*第三行字符输出,11字节*/
col=0;
row=6;
Putstr(STR4,12); /*第四行字符输出,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(x); /*定位新的显示起始行*/
x++;
Delay(100); /*延时,控制滚动速度*/
};
}
/***********************画线,任意方向的斜线,不支持垂直的或水平线***********************/
void Linexy(Uchar endx,Uchar endy)
{
register Uchar t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
Uchar incx,incy;
delta_x=endx-col; /*计算两个方向的距离*/
delta_y=endy-row;
if(delta_x>0) incx=1; /*计算增量方向,增量为0表示既不是垂直线也不是水平线*/
else if( delta_x==0 ) incx=0;
else incx=-1;
if(delta_y>0) incy=1;
else if( delta_y==0 ) incy=0;
else incy=-1;
delta_x = cabs( delta_x ); /* 判定哪个距离比较大*/
delta_y = cabs( delta_y );
if( delta_x > delta_y ) distance=delta_x;
else distance=delta_y;
/*开始画线*/
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方向的,不支持斜线*************************/
void Linehv(Uchar length)
{
Uchar xs,ys;
if (xy){ys = col;
for (xs=0;xs<length;xs++){
col = ys + xs;
point();}
}
else {xs = row;
for (ys=0;ys<length;ys++)
{
row = xs + ys;
point();}
}
}
/*****************************************画点******************************************/
void point(void)
{
Uchar x1,y1,x,y;
x1=col;
y1=row;
row=y1>>3; /*取Y方向分页地址*/
Rddata();
y=y1&0x07; /*字节内位置计算*/
x=0x01;
x=x<<y; /*移入所画点*/
Wrdata(cbyte|x); /*画上屏幕*/
col=x1; /*恢复xy坐标*/
row=y1;
}
/**************************************屏幕滚动定位*************************************/
void Rollscreen(Uchar x)
{
cbyte = DISPFIRST|x; /*定义显示起始行为x?*/
WrcmdL(cbyte);
WrcmdM(cbyte);
WrcmdR(cbyte);
}
/**************************************一个字串的输出***********************************/
void Putstr(Uchar *puts,Uchar i)
{
Uchar j,X;
for (j=0;j<i;j++)
{
X = puts[j];
if (X&0x80)
{
Putcdot(X&0x7f);/*只保留低7位*/
}
else Putedot(X-0x20); /*ascii码表从0x20开始*/
}
}
/*********************************半角字符点阵码数据输出********************************/
void Putedot(Uchar Order)
{
Uchar i,bakerx,bakery; /*共定义4个局部变量*/
int x; /*偏移量,字符量少的可以定义为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;
} /*整个字符输出结束*/
/*********************************全角字符点阵码数据输出********************************/
void Putcdot(Uchar Order)
{
Uchar i,bakerx,bakery; /*共定义3个局部变量*/
int x; /*偏移量,字符量少的可以定义为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;
} /*整个字符输出结束*/
/************************************清屏,全屏幕清零***********************************/
void Lcmcls( void )
{
for(row=0;row<8;row++)
for(col=0;col<LCMLIMIT;col++) Wrdata(0);
}
/***************************从液晶片上读数据,保留在全局变量中***************************/
void Rddata(void)
{
Locatexy(); /*坐标定位,返回时保留分区状态不变*/
Datalcm=0xFF;
Dilcm = 1; /*数据*/
Rwlcm = 1; /*读数据*/
Elcm = 1; /*读入到LCM*/
_nop_();
cbyte = Datalcm; /*虚读一次*/
Elcm = 0;