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

📄 lcm16x16.c

📁 此源程序可以点亮驱动NT7534的12864黑白液晶显示屏
💻 C
📖 第 1 页 / 共 2 页
字号:
/*--------------------------------------------
主题:LCM-NT7534显示程序
功能:将输入的字符内码显示在LCM上,支持全角字符。字库存于SRAM中
LCM驱动IC型号为:NT7534
MCU型号为:STC89LE52
晶振频率为11.0592MHz    
;连线图:
;*LCM---89S52*  *LCM---89S52*   *LCM-------89S52*     *LCM----------89S52* *
;*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*                           *
-------------------------------------------------*/
/*#pragma src   /*生成ASM文件开关,必要时打开 */
#include <reg52.h>
#include <stdarg.h>
#include<INTRINS.H>
#define Uchar unsigned char
/***********液晶显示器接口引脚定义***************/
/*说明:由于LCM的CS1端是通过74HC138控制的,当P2.0/P2.1/P2.2均为0时是选中LCM
的CS1端,LCM被激活,如果单片机I/O直接控制CS1端,则请取消下面的CS_2/CS_3两
项,并修改下LCM读写函数即可。*/
sbit CS_1=P2^0;   //74HC138控制端口A
sbit CS_2=P2^1;   //74HC138控制端口B
sbit CS_3=P2^2;   //74HC138控制端口C
sbit Alcm= P2^4;  //LCD命令和数据控制口,为1时是读写数据;为0时写入命令
sfr  Data= 0x80;  //数据口为P0
/***********LCM常用操作命令和参数定义***************/
#define  DISPON  0xAf /*显示on  */
#define  DISPOFF 0xAe /*显示off  */
#define  DISPFIRST 0x40 /*显示起始行定义 */
#define  SETX1  0x00 /*X定位低4位设定指令(列) */
#define  SETX2  0x10 /*X定位高4位设定指令(列) */
#define  SETY  0xb0 /*Y定位设定指令(页) */
#define  Lcdbusy 0x80 /*LCM忙判断位,当读出数据的最高位为1时,表示正忙。 */
#define  DISCURRENT  0x81 /*进入到电流量设定 */
/*初始化LCD时用到的指令和参数定义*/
#define  DISADC  0xA0 /*LCM显示ADC设定,顺方向 */
#define  DISVOL  0xA2 /*LCM显示偏压设定(取中间值) */
#define  DISCOM  0xCF /*LCM公共输出模式选择,逆方向 */
#define  DISNORMAL  0xA6 /*一般显示指令 */
#define  DISREVERSE  0xA7 /*反显指令 */
#define  DISVR  0x24 /*调整V0电阻比率,这里折中*/
#define  DISCURVUL  0x5D /*设定电流量值,这里折中 */
#define  DISfrequency   0xE4 /*设定LCM工作频率,这里是最大值 */
#define  DISPOWER   0x2F /*LCM电源控制项设定,这里全开 */
#define  LCMLIMIT    132   /*本程序驱动13264LCM,所以这里为132.

/****************全局变量定义*******************/
Uchar col,row;  /*列x,行(页)y,输出数据 */
bit Reverse;  /*反显控制标志位,=1时反显 */
/*****************函数列表**********************/
void Lcminit(void);  /*液晶模块初始化 */
void wtcom(void);  /*busy判断、等待 */
void Lcmcls( void );  /*LCM全屏幕清零(填充0) */
void Loadxy (void);  /* 写入地址函数  */
void Wrcmd(Uchar);  /*命令输出  */
void Wrdata(Uchar);  /*数据输出  */
void Wrcom(Uchar);   /*写入数据函数*/
Uchar Rddata(void);  /*  从液晶片上读数据 */
Uchar Rdcmd(void);  /*  从液晶片上读出状态 */
Uchar Rdcom(void); /* 从LCM上读数据和状态的共享函数 */
void Putcdot(unsigned int Order);  /* 向LCM写入全角字符 */
void Outcdata (unsigned long x);     /*写入全角点陈函数 */
void Putedot(Uchar Order);  /* 向LCM写入半角字符 */
unsigned int Outedata (unsigned int x);     /*写入半角点陈函数 */
void Alldot(Uchar i,Uchar r);  /* 判断当前行及列是否足够显示函数  */
void show_enter(Uchar i); /*  显示入口字符型数函数 */
void show_long(unsigned long i); /*  显示入口长整型数函数 */
void show_HEX(Uchar i);	 /*  将入口数(字符型)直接以HEX格式显示在LCM上  */
void myprintf(const char *format,...); /*   字符串显示输出  */
void M_address(Uchar high,Uchar mid,Uchar low);	/* 对ROM/SRAM写地址函数 */
void Lcm_dot (Uchar i,bit j); /*LCM显示功能点函数*/
/******************数组列表*********************/
Uchar code Ezk[];  /*ASCII常规字符点阵码表 */

 /****************************************/
/*   字符串显示输出  */
/*  本函数是可变函数,入口数为要显示的字符串 */
/****************************************/
void myprintf(const char *format,...)
{
  va_list ap;//说明变量ap
  Uchar  c,d;
  c=*format;  //取第一个值。
  va_start(ap,format);//ap被初始化为指向format第一个参数
  while(c!='%')
   { // 利用指针取数。
	  if (c<0x80) 
	    {
		 Alldot(8,2);
		 Putedot(c-0x20);  /*ascii码表从0x20开始*/
		}
   	  else
	   {   
	    ++format; /*继续取下一个*/
	    d=*format; //取出位码
		Alldot(16,2);
	    Putcdot(((c-0xA1)*94)+(d-0xA1));   /*全角字符码表从0xA1A1开始*/
	   }
	  ++format;
	  c=*format;
   }
  va_end(ap);//清除变量x
}
/****************************************/
/*  将入口数直接以HEX格式显示在LCM上  */
/*  显示HEX入口数函数 */
/****************************************/
void show_HEX(Uchar i)
{
  Uchar a,n=2;
  while(n!=0)  /*当n=0时退出函数*/
    {
     if(n!=1) {a=(i>>4);}  /*显示高位*/
	 else {a=(i&0x0f);}	  /*第二次显示低位*/
     if (a<10)
      {
	   Putedot(a+(0x30-0x20)); /*0x30是字符0内码,0x20是自带字库的首地址*/
	  }
     else
	  {  /*如果入口数小于10,则直接显示*/
	   a=a-10;
	   Putedot(a+(0x41-0x20)); /*0x41是字符A内码,0x20是自带字库的首地址*/
      }
	 --n;  /*n减1以显示下一轮及判断是否完成。*/
	}  
}
/****************************************/
/*  将入口数转换成十进制数字显示在LCM上  */
/*  显示入口长整型数函数 */
/****************************************/
void show_long(unsigned long i)
{
   Uchar a;
   unsigned long b;
   if (i<10) 
     {  /*如果入口数小于10,则直接显示*/
	  Putedot(i+(0x30-0x20)); /*0x30是字符0内码,0x20是自带字库的首地址*/
	  return; /*返回*/
	 }
   for (b=i;b>9;b=(b/10))
     {
	  a=b%10;  /*求b的每次除10后的最低个位的值*/
      Putedot(a+(0x30-0x20)); /*显示数值*/
	  col=(col-16); /*列地址减16即两个半角字符的宽度,以便后面的高位数显示在后面*/
     }
   Putedot(b+(0x30-0x20)); /*显示最高位数值*/
}
/****************************************/
/*  将入口数转换成十进制数字显示在LCM上  */
/*  显示入口字符型数函数 */
/****************************************/
void show_enter(Uchar i)
{
   Uchar a,b;
   if (i<10) 
     {  /*如果入口数小于10,则直接显示*/
	  Putedot(i+(0x30-0x20)); /*0x30是字符0内码,0x20是自带字库的首地址*/
	  return; /*返回*/
	 }
   for (b=i;b>9;b=(b/10))
     {
	  a=b%10;  /*求b的每次除10后的最低个位的值*/
      Putedot(a+(0x30-0x20)); /*显示数值*/
	  col=(col-16); /*列地址减16即两个半角字符的宽度,以便后面的高位数显示在后面*/
     }
   Putedot(b+(0x30-0x20)); /*显示最高位数值*/
}
/****************************************/
/*   全角字符点阵码数据输出  */
/*   入口数Order是指要输出的汉字序号  */
/****************************************/
void Putcdot(unsigned int Order)  /* 向LCM写入全角字符 */
{
/*这里开始输出字符 */
    Uchar bakerx,bakery;   /*定义2个局部变量*/
    unsigned long x;    /*偏移量,字符量少的可以定义为int或char*/
	Alldot(16,2);    /* 调用列、行判断函数 */
    bakerx = col;  /*暂存x,y坐标,备下半个字符使用 */
    bakery = row;
	x=Order;  //这里必须先赋值给x再进行下面的乘法运算,不然会高位丢失。
    x=x * 0x20;  /*每个字符32字节 */
/*上半个字符输出,16列 */
    Loadxy();   /*输入当前字符的首地址*/
    Outcdata(x);
/*上半个字符输出结束 */
    col = bakerx;     /*列对齐  */
    row = bakery+1;     /*指向下半个字符行 */
    Loadxy();   /*输入当前字符下半个字符的首地址*/
/*下半个字符输出,16列 */
    x=(x+16);
    Outcdata(x);
/*整个字符输出结束 */
    col = (bakerx+16);  /*列增加16,便于输入下个字符*/
    row=bakery;   /*恢复原来的row值*/
}
/****************************************/
/*   全角字符点阵码数据输出  */
/*   入口数x是要输出的点阵首地址量 */
/****************************************/
void Outcdata (unsigned long i)     /*写入全角点陈函数 */
{  //字库存于SRAM中
  Uchar high,mid,low;
  low = i;
  mid =(i>>8);
  high=(i>>16); 

/*写入SRAM中该字符的初始地址*/
  CS_1=1;CS_2=1;CS_3=1;	/*选中第三个74HC373*/
  Data=high; /*改变高位地址*/    
  CS_1=0;CS_2=1;CS_3=1;	/*选中第二个74HC373*/
  Data=mid; /*改变中位地址*/
  CS_1=1;CS_2=0;CS_3=1;	/*选中第一个74HC373*/
  Data=low; /*改变低位地址*/
  WR = 1;  //开始读出
  for(i=0;i<16;i++)
   {
    CS_1=1;CS_2=1;CS_3=0;	//片选SRAM的CE端
    Data = 0xFF;  
    Wrdata(Data);    //写输出一字节
    if(low==0xff)
	  {
	   if(mid==0xff)
	     {
		  ++high;    
		 }
	   ++mid;
	  }
	++low;
    M_address(high,mid,low); //写入地址 
   }
}
/****************************************/
/*   半角字符点阵码数据输出  */
/*   入口数Order是指要输出的半角字序号,比如输出"空格",那么Order=0 */
/****************************************/
void Putedot(Uchar Order)
{
/*这里开始输出字符 */
    Uchar bakerx,bakery;   /*定义3个局部变量*/
    int x;    /*偏移量,字符量少的可以定义为UCHAR*/
    Alldot(8,2);    /* 调用列、行判断函数 */
    bakerx = col;  /*暂存x,y坐标,备下半个字符使用 */
    bakery = row;
    x=Order * 0x10;  /*半角字符,每个字符16字节 */
/*上半个字符输出,8列 */
    Loadxy();   /*输入当前字符的首地址*/
    x=Outedata(x);
/*上半个字符输出结束 */
    col = bakerx;     /*列对齐  */
    row = bakery+1;     /*指向下半个字符行 */
    Loadxy();   /*输入当前字符下半个字符的首地址*/
/*下半个字符输出,8列 */
    Outedata(x);
/*整个字符输出结束 */
    col = (bakerx+8);  /*列增加8,便于输入下个字符*/
    row=bakery;   /*恢复原来的row值*/
}
/****************************************/
/*   半角字符点阵码数据输出  */
/*   入口数x是要输出的点阵首地址量 */
/****************************************/
unsigned int Outedata (unsigned int x)    /*写入全角点陈函数 */
{
  Uchar i;
  for(i=0;i<8;i++)
   {
    Wrdata(Ezk[x]);    /*取点阵码,并写输出一字节  */
    x++;
   }
  return x;
}
/*************************************************/
/* 对ROM/SRAM写地址函数 */
/* 入口数i是读或写的地址*/
/*************************************************/
void M_address(Uchar high,Uchar mid,Uchar low)
{
  CS_1=1;CS_2=0;CS_3=1;	/*选中第一个74HC373*/
  Data=low; /*输出低位地址*/
  CS_1=0;CS_2=1;CS_3=1;	/*选中第二个74HC373*/
  Data=mid; /*输出中位地址*/
  CS_1=1;CS_2=1;CS_3=1;	/*选中第三个74HC373*/
  Data=high; /*输出高位地址*/
}
/****************************************/
/* 判断当前行及列是否足够显示函数  */
/* 入口数i是要输出的图形总列数,r是图形的总页数 */
/****************************************/
void Alldot(Uchar i,Uchar r)
{
   if((LCMLIMIT-col)<i)	 /*判断当页所剩的列数是否小于i*/
     {
	     col=0;	  /*如果所剩列数不够显示,则换行*/
         row=(2+row);
     }
   if((8-row)<r)	 /*判断所剩的页数是否小于r*/
     {
	     Lcmcls();	 /*清屏处理*/
         Loadxy(); /*输入当前字符首地址*/
     }
}
/****************************************/
 /*LCM显示功能点函数*/
 /*入口数i是指定要显示的点的列数,j为1时表示点亮该点,为0时消隐*/
/****************************************/
void Lcm_dot (Uchar i,bit j)
{
   Uchar bakerx,bakery;  //定义两个变量,用于存放col及row的初值
   bakerx=col;bakery=row; //备份地址
   col=i;  /*写入标志的列地址*/
   row=8;  /*功能点都在第8页,即第65行*/
   Loadxy();     /* 写入地址 */
   if (j)
      {Wrdata(0xFF);}   /*j=1,则点亮此点*/
   else
      {Wrdata(0);}  /*j=0,关掉此点*/
   col=bakerx;row=bakery; //还原地址
}
/****************************************/
/* 清屏,全屏幕清零  */
/****************************************/
void Lcmcls( void )
{
  row=0,col=0;
  for(row=0;row<8;row++) /*这里不清功能指示行*/
    {
	 col=0;   /*回归到初始值0*/
     Loadxy();     /* 写入页首地址 */
     for(;col<LCMLIMIT;col++)Wrdata(0);    /* 写入数据0 */
	}
  row=0,col=0;    /* 地址归位 */
}
/****************************************/
/* 写入地址函数 */
/****************************************/
void Loadxy(void)
{
 Uchar cbyte;
 cbyte=row;
 cbyte=cbyte | SETY;  /* 合成命令 */
 Wrcmd(cbyte);  /* 写入页地址 */
 cbyte =((col>>4) | SETX2);  /* 合成命令 */
 Wrcmd(cbyte);  /*写入列地址的高4位*/
 cbyte =((col & 0x0F) | SETX1);  /* 合成命令 */
 Wrcmd(cbyte);  /* 写入列地址的低4位 */
}
/****************************************/
/*  从液晶片上读数据,保留在全局变量中 */
/****************************************/
Uchar Rddata(void)
{
  Alcm = 1;   /*读数据操作 */
  Rdcom();  /*调用读数据共享程序,假读一次*/
  return(Rdcom());  /*调用读数据共享程序*/
}
/****************************************/
/*  读出LCD状态,保留在全局变量中 */
/****************************************/
Uchar Rdcmd(void)
 {
  Alcm = 0;   /*读状态操作 */
  return(Rdcom());  /*调用读数据共享程序*/
}
/****************************************/
/*  读LCD状态、数据共享函数 */
/****************************************/
Uchar Rdcom(void)
{
  Uchar cbyte;
  Data=0xFF;   /* P0口全置1*/
  CS_1 = 0;   /*74HC138的A端置0  */

⌨️ 快捷键说明

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