C51单片机对液晶片的驱动

keil c51编写的192*64液晶片驱动程序,感谢很多网友提供了参考源程序,
本程序是在网友们提供的程序基础上改写而成,有很多地方得到高手们的耐
心指导,在此深表谢意。这是一个完整的c51源程序,我觉得对一位初学c51
的人来说,提供一个完整的简单程序比较容易上手。
--------------------------------------------------------------------------------------------------*/
/*写汉字液晶子程 液晶屏分为4行*12列汉字,全部使用模拟接口方式。
/* tglcmlimit64a接口程序(模拟方式)
液晶模块供应商:
email:
;***************************************************************************
;连线图:
;*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; //数据口
/***********常用操作命令和参数定义***************/
#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(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(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;
/* 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;xscol = ys + xs;
point();}
}
else {xs = row;
for (ys=0;ysrow = 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;
} /*整个字符输出结束 */
/****************************************/
/* 全角字符点阵码数据输出 */
/****************************************/
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}
/****************************************/
/* 从液晶片上读数据,保留在全局变量中 */
/****************************************/
void rddata(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;
}
/****************************************/
/* 数据写输出 */
/****************************************/
void wrdata(uchar x)
{
locatexy(); /*坐标定位,返回时保留分区状态不变 */
// wtcom();
dilcm = 1; /*数据输出*/
rwlcm = 0; /*写输出 */
datalcm = x; /*数据输出到数据口 */
elcm = 1; /*读入到lcm*/
_nop_();
elcm = 0;
}

力劲科技2023年实现营收58.96亿港元
如何解决EMI传导干扰
74hc138应用电路
以访问外部SDRAM为例来说明降低外部存储系统功耗的方法
静脉识别技术开始得到市场的广泛关注
C51单片机对液晶片的驱动
全新的汽车内饰材料轻量化解决方案
LED发光二极管灯珠公司 还是深圳海隆兴光电子好
蚂蚁区块链最近有什么新的动静
NVIDIA 知乎精彩问答甄选 | 探索 AI 如何推动工作流升级相关精彩问答
什么是励磁绕组?励磁绕组有什么作用?
深度学习如何进行MRI图像右心室分割
在WINDOWS操作系统下基于PCI总线开发WDM驱动程序
使用万用表测量电阻的方法
期待已久的宝骏310W今日正式上市,售价为4.28-5.68万元
led显示屏怎样抓住发展机遇
高级速度控制功能块MC_VelocityProfile介绍(2)
什么是光耦继电器,它的运用优点是什么
吉时利推出高功率高性能可编程直流电源
美军战斗机项目设计欲配人工智能“副驾驶”