⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd.c

📁 LM128*64液晶驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:

/*******************************************************
程序功能:LCD汉字及图形点阵显示
作者:FEDLT
广西工学院电子信息工程03级
e-mail:fedlt@163.com
QQ:282695105

*********************************************************
接线说明:
89C51  LM1264ldc
P0.0~7 --- DB0~7(7~14)	
P2.0---RS(4)	
P2.1---R/W(5)	
P2.2---E(6)	 
P2.3---CS1(15)	
P2.4---CS2(16)	
P2.5---RST(17)	

*********************************************************/
#include<reg51.h>
#include<math.h>
#include<INTRINS.H>
#define Uchar unsigned char
/*注:89c51的晶振频率为12MHz*/
/***********液晶显示器接口引脚定义***************/
sbit	RS=P2^7;               /*RS控制信号*/  
sbit	RW=P2^6;               /*R/W控制信号*/ 
sbit	E=P2^5;	              /*使能信号*/
sbit	CS1=P2^4;              /*CS1控制信号*/
sbit	CS2=P2^3;               /*CS2控制信号*/
sbit	RST=P2^2;	           /*RST清零控制信号*/
sfr 	Data=0x80;				/*数据口*/
/***********常用操作命令和参数定义***************/
#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	 MODR		0x40		/*左区和右区分界*/
#define	 LCDLIMIT   0x80		/*显示区的右边界*/

/****************全局变量定义*******************/
Uchar row=0,col=0,cbyte;				/*行(页)x,列y,输出数据*/
bit xy;						        /*画线方向标志:1水平,0垂直*/

/*****************函数列表**********************/
void Lcdinit(void);				/*液晶模块初始化*/
void Delay(Uchar);				/*延时,入口数为Ms	*/
void lcdbusyL(void);				/*busy判断、等待(左区)*/
void lcdbusyR(void);				/*busy判断、等待(右区)*/
void Putedot(Uchar);				/*半角字符输出*/
void Putcdot(Uchar);				/*全角(汉字)输出*/
void Wrdata(Uchar);				/*数据输出给LCD*/
void Lcdclr(void);				/*LCD全屏幕清零(填充0)	*/
void wtcom(void);				/*公用busy等待*/
void Locatexy(void);				/*光标定位*/
void WrcmdL(Uchar);				/*左区命令输出	*/
void WrcmdR(Uchar);				/*右区命令输出	*/
void Putstr(Uchar posx,Uchar posy,Uchar *puts,Uchar i);		/*中英文字符串输出*/
void Rollscreen(Uchar x);			/*屏幕向上滚动*/
void Rddata(void);				/*从液晶片上读数据*/
void Linehv(Uchar posx,Uchar posy,Uchar length,Uchar XY);			/*横(竖)方向画线*/
void point(Uchar posx,Uchar posy);					/*打点*/
void Linexy(Uchar posx,Uchar posy,Uchar endx,Uchar endy);
void WR_rowcol(Uchar x,Uchar y);           /*把x,y的坐标值写到行列对应的值中*/
/******************数组列表*********************/
Uchar code Ezk[];				/*ASCII常规字符点阵码表	*/
Uchar code Hzk[];				/*自用汉字点阵码表*/
Uchar code STR1[];				/*自定义字符串*/
Uchar code STR2[];
Uchar code STR3[];
Uchar code STR4[];
Uchar code STR5[];
/****************************************主程序*****************************************/
void main(void)
{
 	Uchar x=0;
	Delay(40);					/*延时大约40Ms,等待外设准备好*/
	Lcdinit();					/*液晶模块初始化,包括全屏幕清屏*/
	Putstr(0,48,STR1,9);				/*第一行字符输出,12字节*/
	Putstr(2,2,STR2,14);				/*第二行字符输出,14字节*/
	Putstr(4,2,STR3,15);				/*第三行字符输出,11字节*/
	Putstr(6,2,STR4,14);				/*第四行字符输出,12字节*/
	Putstr(2,18,STR5,1);
	Linehv(0,0,128,1);				/*画一条横线(0,0)-(0,127)*/
	Linehv(16,0,128,1);				/*画一条横线(15,0)-(15,127)*/
	Linehv(32,0,128,1);				/*画一条横线(32,0)-(32,127)*/
    Linehv(48,0,128,1);	
    Linehv(63,0,128,1);	
    Linehv(0,47,16,0);	
	Linehv(1,0,63,0);				/*画一条竖线(1,0)-(31,0)*/
	Linehv(1,127,63,0);				/*画一条竖线(1,127)-(31,127)*/
	Linexy(0,0,16,48);				/*画一段斜线(63,0)-(31,44)	*/
    point(10,3);
	point(10,5);
	point(10,7);
    point(10,9);
    point(10,11);
    
 	while(1){
		Rollscreen(x);			/*定位新的显示起始行*/
		x++;
		Delay(100);			/*延时,控制滚动速度*/
		};
}

/*************************************液晶屏初始化**************************************/
void Lcdinit(void)
	{   
		cbyte = DISPOFF;			/*关闭显示屏*/
		WrcmdL(cbyte);
		WrcmdR(cbyte);
		cbyte = DISPON;		    	/*打开显示屏*/
		WrcmdL(cbyte);
		WrcmdR(cbyte);
		cbyte = DISPFIRST;			/*定义显示起始行为零*/
		WrcmdL(cbyte);
		WrcmdR(cbyte);
		Lcdclr();                 /*清屏*/
		Locatexy();
	}
/*********************************制定坐标函数******************************************/
void WR_rowcol(Uchar x,Uchar y) 
  {row=x;
   col=y;
   }
/*********************************命令输出到左区控制口*********************************/
void WrcmdL(Uchar X)
	{
		lcdbusyL();			/*确定分区,返回时保留分区状态不变*/
		RS= 0;				/*命令操作*/
		RW = 0;			    /*写输出*/
		Data= X;			/*数据输出到数据口*/
		E = 1;_nop_();E= 0;	/*读入到LCD*/
	}

/*********************************命令输出到右区控制口********************************/
void WrcmdR(Uchar X)
	{
		lcdbusyR();				/*确定分区,返回时保留分区状态不变*/
		RS= 0;			     /*命令操作*/
		RW= 0;			/*写输出*/
		Data = X;			/*命令输出到数据口*/
		E = 1;_nop_();E = 0;	/*读入到LCM*/
	}
/************************分区操作允许等待,返回时保留分区选择状态*************************/
void lcdbusyL(void)
	{
        CS1 = 1; CS2 = 0;	/*置CS1为1,CS2为0,选择左区*/
	   wtcom();				/*等待使能*/
	}
void lcdbusyR(void)
	{
        CS1= 0; CS2=1;	/*置CS1为0,CS2为1,选择右区*/
        wtcom();	    /*等待使能*/
	}
void wtcom(void)
	{
	     RS= 0;				/*清零RS*/
	     RW = 1;			/*置RW为1*/
          Data = 0xFF;
	     E= 1;_nop_();	
     	while(Data & Lcdbusy);
      	E = 0;
	}
/************************************清屏,全屏幕清零***********************************/
void Lcdclr( void )
	{
	for(row=0;row<8;row++)
   		for(col=0;col<LCDLIMIT;col++) Wrdata(0);
	}
/******************根据设定的坐标数据,定位LCD上的下一个操作单元位置******************/
void Locatexy(void)
	{  Uchar  x,y;
	   switch (col&0x40)				/* col与0xC0*/
		{						/*条件分支执行	*/

case 0:	{lcdbusyL();break;}	/*左区*/
case 0x40:	{lcdbusyR();break;}	/*右区*/
		}
	   	x = row&0x07|SETX;
y = col&0x3F|SETY;
	    wtcom();				/*等待使能*/
	    RS= 0;					/*清零rs	*/
		RW= 0;				    /*清零RW*/
		Data = x;			
		E= 1;_nop_();E = 0;
		wtcom();				
     	RS = 0;					
		RW= 0;				
		Data= y;			
		E = 1;_nop_();E = 0;
	}
/*************************************数据写输出/**************************************/
void Wrdata(Uchar X)
	{
	    Locatexy();			/*坐标定位,返回时保留分区状态不变*/
		RS= 1;				/*数据输出*/
		RW = 0;			/*写输出*/
		Data = X;			/*数据输出到数据口*/
		E = 1;				/*读入到LCD*/
		_nop_();
		E = 0;
	}
/***********************画线,任意方向的斜线,不支持垂直的或水平线***********************/
void Linexy(Uchar posx,Uchar posy,Uchar endx,Uchar endy)
{   
    Uchar t;
	int xerr=0,yerr=0,delta_x,delta_y,distance;
	Uchar incx,incy;
	WR_rowcol(posx,posy) ;
	delta_x=endy-row; 			/*计算两个方向的距离*/
	delta_y=endx-col;
	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(row,col);
 	   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 posx,Uchar posy,Uchar length,Uchar XY)
	{   Uchar xs,ys;
	    if(XY==0x00)
	      xy=0;
		else xy=1;
	    WR_rowcol(posx,posy); 
		if (xy)
		   {ys = col;
			for (xs=0;xs<length;xs++)
			   { col = ys + xs;
				 point(row,col);}
			}
		else	{xs = row;
			for (ys=0;ys<length;ys++)
{
					row = xs + ys;
					point(row,col);}
				 }
}

/*****************************************画点******************************************/
void point(Uchar posx,Uchar posy)
	{  	Uchar x1,y1,x,y; 
	    WR_rowcol(posx,posy);	
		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);
		WrcmdR(cbyte);
	}

/**************************************一个字串的输出***********************************/
void Putstr(Uchar posx,Uchar posy,Uchar *puts,Uchar i)
	{   Uchar j,X;
	    WR_rowcol(posx,posy); 
		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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -