新闻中心

EEPW首页>嵌入式系统>设计应用> 51单片机采用模拟时序控制点阵图形液晶程序

51单片机采用模拟时序控制点阵图形液晶程序

作者: 时间:2016-11-28 来源:网络 收藏
;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;连线图:
;//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//
;///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//画线部分请参照avr的c程序。
///#pragma src///生成ASM文件开关,必要时打开///
#include
#include
#include

#define Uchar unsigned char

///////////////////////液晶显示器接口引脚定义///////////////////////////////

sbit Elcm= P2^3; //
sbit CS1LCM= P2^4; //
sbit CS2LCM= P2^5; //
sbit CS3LCM= P3^2; ///这个连接只是做实验的临时接法。///
sbit Dilcm= P2^6; //
sbit Rwlcm= P2^7; //
sfr Datalcm= 0x80; //数据口
unsigned char testi[]={"浸渠叁绳漱塔烃威牺晓玄瑶"};

///////////////////////常用操作命令和参数定义///////////////////////////////
#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,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); ///延时,控制滚动速度 ///
};
}


//////////////////////////////////////////////////////////////////////////////////////////////////
///画线。任意方向的斜线,不支持垂直的或水平线 ///
//////////////////////////////////////////////////////////////////////////////////////////////////

void Linexy(Uchar endx,Uchar endy)
{
register Uchar t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
Uchar incx,incy;

/// compute the distance in both directions ///
delta_x=endx-col;
delta_y=endy-row;

/// compute the direction of the increment ,
an increment of "0" means either a vertical or horizontal lines ///

if(delta_x>0) incx=1;
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;

/// determine which distance is greater ///
delta_x = cabs( delta_x );
delta_y = cabs( delta_y );

if( delta_x > delta_y ) distance=delta_x;
else distance=delta_y;

/// draw the line ///
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
col = ys + xs;
point();}
}
else {xs = row;
for (ys=0;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< ///移入所画点 ///
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
{
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;
} ///整个字符输出结束 ///

上一页 1 2 3 下一页

评论


技术专区

关闭