原创 89C51控制ZY12864D点阵液晶显示数字

2008-11-11 16:19 8375 3 8 分类: MCU/ 嵌入式
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


1所示是<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />89C51单片机与LCD12864的接口电路。


其中,74HC573作为地址锁存器。ZY12864DD0~D78位双向数据线;RS为寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器;R/W为读写信号线,高电平进行读操作,低电平进行写操作;E端为使能端,当E端由高电平跳变成低电平时,液晶执行命令;CS1CS2为选屏信号,CS1高电屏选中左半屏,CS2高电屏选中右半屏。


从图中可以看出,CS2是通过CS1接的反相器得到的,所以CS1CS2不能同时为高电平,即该实验中左、右半屏不能同时控制。模块及其背光源均由外部提供+5V电源。通过调节外接的电位器的阻值,用户可以控制LCD模块显示图形的清晰度。


通过分析可知,图中LCD液晶显示写左半屏指令的地址为7FFCH,写右半屏指令的地址为7FF8H,写左半屏数据的地址为7FFDH,写右半屏数据的地址为7FF9H


点击开大图


1LCD12864P89C51的接口电路


 


12864液晶模块内部的控制器共有7条控制指令,如表1所示。它的读写操作、屏幕和光标的操作都是通过指令编程实现的。


112864液晶模块内部的控制命令




指令


RS


RW


D7


D6


D5


D4


D3


D2


D1


D0


显示


0


0


0


0


0


0


0


0


0


D


显示起始行


0


0


1


1


显示起始行(0……63


设置X地址


0


0


1


0


1


1


1


X:0….7


设置Y地址


0


0


0


1


Y地址(0…..63


读状态


0


1


BF


0


ON/OFF


RST


0


0


0


0


写显示数据


1


0


要写的数


读显示数据


1


1


读出的数据


下面简单介绍一下表中指令的功能:


指令1:显示开关控制,D高电平开显示,低电平关显示。


指令2:设置显示起始行。


指令3:设置X地址(页地址)。


指令4:设置Y地址(列地址)。。


指令5:读状态。BF:忙标志,高电平表示忙,此时模块不能接受命令或数据,低电平表示空闲;RST:复位标志位,高电平表示正处于复位初始化状态,低电平表示正常状态。ON/OFF:显示标志位,高电平表示显示关闭,低电平表示显示开。


指令6:写显示数据。写指令执行后Y地址计数器自动加1


指令7:读显示数据。写指令执行后Y地址计数器自动加1


实验程序:


/* 包含头文件 */


#include "reg52.h"


#include "absacc.h"


#include "stdlib.h"


#include "intrins.h"


 


#define   uint8              unsigned char


#define   uint16            unsigned int


 


/* 定义LCM操作地址 */


#define   LCMCS1W_COM     (*((uint8 volatile xdata *) 0x7ffc))     /* 写左半屏指令 */


#define   LCMCS1W_DAT       (*((uint8 volatile xdata *) 0x7ffd))     /* 写左半屏数据 */


#define   LCMCS2W_COM     (*((uint8 volatile xdata *) 0x7ff8))     /* 写右半屏指令 */


#define   LCMCS2W_DAT       (*((uint8 volatile xdata *) 0x7ff9))     /* 写右半屏数据 */


 


/* 定义LCM操作的命令字 */


#define   LCM_DISPON          0x3f       /* 打开LCM显示 */


#define LCM_STARTROW      0xc0       /* 显示起始行0,可以用LCM_STARTROW+x设置起始行。(x<64) */


#define   LCM_ADDRSTRX    0xb8      /* 页起始地址,可以用LCM_ADDRSTRX+x设置当前页(即行)(x<8) */


#define   LCM_ADDRSTRY    0x40      /* 列起始地址,可以用LCM_ADDRSTRY+x设置当前列。(y<64) */


 


/* LCM复位控制脚定义 */


sbit  LCM_RST    = P1^0;


 


uint8 code number[160]={


/*--  文字:  09;  此字体下对应的点阵为:宽x=8x16  --*/


0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,


0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,


0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,


0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,


0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,


0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,


0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,


0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,


0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,


0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,


};


 


/***********************************************************************


* 名称LCM_Wr1Command()


* 功能写命令子程序所选屏为左半屏(CS1)


* 入口参数command        要写入LCM的命令字


***********************************************************************/


void LCM_Wr1Command(uint8 command)          


{


       LCMCS1W_COM = command;


}


 


/***********************************************************************


* 名称:LCM_Wr2Command()


* 功能:写命令子程序,所选屏为右半屏(CS2)


* 入口参数:command        要写入LCM的命令字


***********************************************************************/


void LCM_Wr2Command(uint8 command)          


{


       LCMCS2W_COM = command;


}


 


/***********************************************************************


* 名称:LCM_Wr1Data()


* 功能:写数据子程序,所选屏为左半屏(CS1)


* 入口参数:wrdata      要写入LCM的数据


***********************************************************************/


void LCM_Wr1Data(uint8 wrdata)        


{


       LCMCS1W_DAT = wrdata;


}


 


/***********************************************************************


* 名称:LCM_Wr2Data()


* 功能:写数据子程序,所选屏为右半屏(CS2)


* 入口参数:wrdata      要写入LCM的数据


***********************************************************************/


void LCM_Wr2Data(uint8 wrdata)        


{


       LCMCS2W_DAT = wrdata;


}


 


/****************************************************************************


* 名称: delayms()


* 功能: 延时子函数


* 入口参数:


****************************************************************************/


void delayms(uint8 ms)


{


       uint8 s, t;


     for(s = 0; s < ms; s++)


          for(t = 0; t < 250; t++)


              {


                     _nop_();


                     _nop_();


                     _nop_();


                     _nop_();


              }


}


 


/***********************************************************************


* 名称:LCM_DispClr()


* 功能:LCM清屏


* 入口参数:无


* 出口参数:无


***********************************************************************/


void LCM_DispClr(void)


{


       uint8 i, j;


       for(i = 0; i < 8; i++)


       {


              LCM_Wr1Command(i + LCM_ADDRSTRX);


              LCM_Wr2Command(i + LCM_ADDRSTRX);                   /*设置左右屏页地址*/


 


              LCM_Wr1Command(LCM_ADDRSTRY);


              LCM_Wr2Command(LCM_ADDRSTRY);                        /*设置左右屏初始列地址*/


 


              for(j = 0; j < 64; j++)                /*每清一位0,列地址会自动加1*/


              {


                     LCM_Wr1Data(0x00);


                     LCM_Wr2Data(0x00);                    /*清显示屏*/


              }


       }


}


 


/***********************************************************************


* 名称:LCM_DispIni()


* 功能:LCM显示初始化。使能显示,设置显示起始行为0并清屏。


* 入口参数:无


* 出口参数:无


***********************************************************************/


void LCM_DispIni(void)


{


       LCM_RST=0;


       delayms(2);


       LCM_RST=1;


 


   LCM_Wr1Command(LCM_DISPON);         // 打开显示


   LCM_Wr1Command(LCM_STARTROW);  // 设置显示起始行为0


   LCM_Wr2Command(LCM_DISPON); 


   LCM_Wr2Command(LCM_STARTROW);        


   LCM_DispClr();                              // 清屏 


 


       LCM_Wr1Command(LCM_ADDRSTRY+0);      // 设置页()地址


   LCM_Wr1Command(LCM_ADDRSTRX+0);     // 设置列地址,即列


   LCM_Wr2Command(LCM_ADDRSTRY+0);


   LCM_Wr2Command(LCM_ADDRSTRX+0);


}


 


/***********************************************************************


* 名称:LCM_DispChar()


* 功能:指定地址显示字符。


* 入口参数:cx        显示行值(0-7)   


*                cy           显示列值(0-15)


*        dispchar         所要显示的字符(ASCII)


* 注:支持显示字符0-9,字符显示格式为5*7,模为16*8,所以


*     屏幕显示为4*16(4行,每行16个字符)


***********************************************************************/


void LCM_Dispchar(uint8 cx, uint8 cy, uint8 dispchar)


{


       uint8 h, i;


 


       if(cy < 0x08)//选择液晶控制芯片(CS1--控制前8个字符,CS2--控制后8个字符)


       {


              i = cy << 3;


              LCM_Wr1Command(LCM_ADDRSTRX + cx);         // 设置当前页地址,即行


        LCM_Wr1Command(LCM_ADDRSTRY + i);                   // 设置当前列地址,即列


 


              for(h = 0; h < 8; h++)


                     LCM_Wr1Data(number[dispchar*16 + h]);


 


              LCM_Wr1Command(LCM_ADDRSTRX + cx + 1);   // 设置当前页地址即行


        LCM_Wr1Command(LCM_ADDRSTRY + i);           // 设置当前列地址即列


 


              for(h = 0; h < 8; h++)


                     LCM_Wr1Data(number[dispchar*16 + h + 8]);


       }


       else


       {


              i = (cy & 0x07) << 3;


              LCM_Wr2Command(LCM_ADDRSTRX + cx);         // 设置当前页地址,即行


        LCM_Wr2Command(LCM_ADDRSTRY + i);                   // 设置当前列地址,即列


 


              for(h = 0; h < 8; h++)


                     LCM_Wr2Data(number[dispchar*16 + h]);


 


              LCM_Wr2Command(LCM_ADDRSTRX + cx + 1);   // 设置当前页地址即行


        LCM_Wr2Command(LCM_ADDRSTRY + i);           // 设置当前列地址即列


      


              for(h = 0; h < 8; h++)


                     LCM_Wr2Data(number[dispchar*16 + h + 8]);


       }


}


 


/* 12864上起始行显示0123456789 */


void main()


{    


LCM_Dispchar(0, 0, 0);


       LCM_Dispchar(0, 1, 1);


       LCM_Dispchar(0, 2, 2);


       LCM_Dispchar(0, 3, 3);


       LCM_Dispchar(0, 4, 4);


       LCM_Dispchar(0, 5, 5);


       LCM_Dispchar(0, 6, 6);


       LCM_Dispchar(0, 7, 7);


       LCM_Dispchar(0, 8, 8);


       LCM_Dispchar(0, 9, 9);


}


 

文章评论5条评论)

登录后参与讨论

lefthandls_164871881 2009-5-13 15:14

1602之前我也做过

anning865_772215668 2009-5-13 08:57

高手,我只做过1602的。

klyzh2003_363865542 2008-11-28 17:16

lefthandls_164871881 2008-11-12 12:11

谢谢billa夸奖,只是我做实验的一个小程序。 显示汉字也是一个道理哦!

zhigangxia2000_773407453 2008-11-11 16:47

很好
相关推荐阅读
lefthandls_164871881 2009-05-13 19:04
GPRS模块短消息发送方法
最近做了一个GPRS模块的简单测试,其中短消息方式比较简单,同时也与其他GPRS模块通用,现在将我的调试笔记写下来。短消息方式:<?xml:namespace prefix = o ns = "...
lefthandls_164871881 2009-05-07 15:48
AT91SAM9260的bootstrap(包括norflash)
公司的一个项目用AT91SAM9260的ARM,从百特买了一个AT91SAM9260的开发板,上面有一个norflash,但没有焊。公司要求用norflash,结果却发现开发板资料中并没有norfla...
lefthandls_164871881 2008-12-30 21:04
AT91SAM9260学习——用WINARM编译bootstrap
一、下载安装WinARM编译工具(winarm.rar文件)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:o...
lefthandls_164871881 2008-11-06 15:52
虚拟机下Linux和windows的文件共享――共享方式
本人使用的是vmware workstation6.0绿色版,Linux为Redhat Linux9.0。首先在虚拟机下设置windows的共享文件,然后安装vmware tools实现共享。<...
lefthandls_164871881 2008-10-25 16:56
MCS51的LED1602液晶显示控制电路及程序
图1所示是80C51单片机与LED1602的接口电路。其中,74HC573作为地址锁存器。LED1602的D0~D7为8位双向数据线;RS为寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器;R/...
我要评论
5
3
1
2
3
4
5
6
7
8
9
0
关闭 热点推荐上一条 /4 下一条