基于DS1302和LCD1602的可调数字钟Word下载.docx
《基于DS1302和LCD1602的可调数字钟Word下载.docx》由会员分享,可在线阅读,更多相关《基于DS1302和LCD1602的可调数字钟Word下载.docx(29页珍藏版)》请在冰豆网上搜索。
![基于DS1302和LCD1602的可调数字钟Word下载.docx](https://file1.bdocx.com/fileroot1/2023-1/31/087c6f5c-0856-479f-86c0-6cb6cd39e1d7/087c6f5c-0856-479f-86c0-6cb6cd39e1d71.gif)
的不亮。
这样一来就组成某个字符。
但由于内带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。
汉字的显示:
汉字的显示一般采用图形的方式,事先从微机中提取要显示的汉字的点阵码(一般用字模提取软件),每个汉字占32B,分左右两半,各占16B,左边为1、3、5……右边为2、4、6……根据在LCD上开始显示的行列号及每行的列数可找出显示RAM对应的地址,设立光标,送上要显示的汉字的第一字节,光标位置加1,送第二个字节,换行按列对齐,送第三个字节……直到32B显示完就可以LCD上得到一个完整汉字.
2。
3。
1。
2、1602字符型LCD简介
字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。
一般1602字符型液晶显示器实物如图
(1):
图
(1)1602字符型液晶显示器实物图
1602LCD分为带背光和不带背光两种,其控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别。
1602LCD主要技术参数:
显示容量:
16×
2个字符;
芯片工作电压:
4。
5—5。
5V;
工作电流:
2.0mA(5。
0V);
模块最佳工作电压:
5。
0V;
字符尺寸:
2.95×
35(W×
H)mm
引脚功能说明:
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表1所示:
第1脚:
VSS为地电源.
第2脚:
VDD接5V正电源.
第3脚:
VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度.
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器.
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令.
第7~14脚:
D0~D7为8位双向数据线。
第15脚:
背光源正极。
第16脚:
背光源负极。
表11602LCD引脚接口说明
编号
符号
引脚说明
1
VSS
电源地
9
D2
数据
2
VDD
电源正极
10
D3
3
VL
液晶显示偏压
11
D4
4
RS
数据/命令选择
12
D5
5
R/
W
读/写选择
13
D6
6
E
使能信号
14
D7
7
D0
15
BL
A
背光源正极
8
D1
16
K
背光源负极
3、1602LCD的指令说明及时序
1602液晶模块内部的控制器共有11条控制指令,如表2所示:
表2:
控制命令表
序号
指令
R/W
功能
复位显示器
清屏,光标归位
光标返回
*
设置地址计数器清零,DDRAM数据不变,光标移到左上角
字符进入模式
I/D
S
设置字符进入时的屏幕移位方式
显示开/关控制
D
C
B
设置显示开关,光标开关,闪烁开关
光标或字符移位
S/C
R/L
*
设置字符与光标移动
功能设置
DL
N
F
设置DL,显示行数,字体
设置字符发生存贮器地址
字符发生存贮器地址
设置6位的CGRAM地址以读/写数据
设置数据存贮器地址
显示数据存贮器地址
设置7位的DDRAM地址以读/写数据
读忙标志或地址
BF
计数器地址
读忙标志及地址计数器
写数据到CGRAM或DDRAM)
写入一字节数据,需要先设置RAM地址
向CGRAM/DDRAM写入一字节的数据
从CGRAM或DDRAM读数据
读取入一字节数据,需要先设置RAM地址
从CGRAM/DDRAM读取一字节的数据
I/D=1递增,I/D=0递减.
S=0时显示屏不移动,S=1时,如果I/D=1且有字符写入时显示屏左移,否则右移。
D=1显示屏开,D=0显示屏关。
C=1时光标出现在地址计数器所指的位置,C=0时光标不出现。
B=1时光标出现闪烁,B=0时光标不闪烁.
S/C=0时,RL=0则光标左移,否则右移。
S/C=1时,RL=0则字符和光标左移,否则右移。
DL=1时数据长度为8位,DL=0时为使用D7-D4共4位,分两次送一字节。
N=0为单行显示,N=1时为双行显示。
F=1时为510点阵字体,F=0时为57点阵字体。
BF=1时LCD忙,BF=0时LCD就绪.
1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
(说明:
1为高电平、0为低电平)
指令1:
清显示,指令码01H,光标复位到地址00H位置.
指令2:
光标复位,光标返回到地址00H。
指令3:
光标和显示模式设置I/D:
光标移动方向,高电平右移,低电平左移S:
屏幕上所有文字是否左移或者右移。
高电平表示有效,低电平则无效。
指令4:
显示开关控制。
D:
控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:
控制光标的开与关,高电平表示有光标,低电平表示无光标B:
控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:
光标或显示移位S/C:
高电平时移动显示的文字,低电平时移动光标.
指令6:
功能设置命令DL:
高电平时为4位总线,低电平时为8位总线N:
低电平时为单行显示,高电平时双行显示F:
低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
指令7:
字符发生器RAM地址设置。
指令8:
DDRAM地址设置。
指令9:
读忙信号和光标地址BF:
为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:
写数据。
指令11:
读数据。
与HD44780相兼容的芯片时序表如下:
表3:
基本操作时序表
读状态
输入
RS=L,R/W=H,E=H
输出
D0—D7=状态字
写指令
RS=L,R/W=L,D0—D7=指令码,E=高脉冲
无
读数据
RS=H,R/W=H,E=H
D0—D7=数据
写数据
RS=H,R/W=L,D0—D7=数据,E=高脉冲
读写操作时序如图3和4所示:
图3读操作时序
图4写操作时序
2.3.1.41602LCD的RAM地址映射及标准字库表
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志位,如果该位为低电平,表示不忙,否则此指令失效.要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,图5是1602的内部显示地址。
图51602LCD内部显示地址
例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?
这样不行,因为写入显示地址时要求最高位D7恒定为高电平1所以实际写入的数据应该是01000000B(40H)+10000000B(80H)=11000000B(C0H)。
在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的,无需人工干预。
每次输入指令前都要判断液晶模块是否处于忙的状态.
1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,如图6所示,这些字符有:
阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A"
的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”
图6字符代码与图形对应图
2.3.2硬件电路设计
硬件主要使用了DS1302和LCD1602,电路结构简单,具体如下图所示:
图7硬件电路
3软件设计
软件设计中主要是针对DS1302芯片和LCD1602进行程序的设计,而DS1302的驱动程序在上个项目中我们已经作了详细介绍,在此不再赘述.我们主要编制LCD的驱动程序。
根据对LCD资料的分析,程序编制主要有:
读取LCD的状态,忙检查,向LCD写入命令,向LCD写入数据,LCD初始化,设置LCD液晶的显示位置,显示字符等,具体如下:
1、读取LCD的状态
//——-——-—--—读取LCD的状态—-—-—--*/
ucharRead_LCD_State()
{
ucharstate;
RS=0;
RW=1;
EN=1;
DelayMS
(2);
state=P0;
EN=0;
returnstate;
}
2、忙检查
//——-————-—————忙检查--——-—---—--—-*/
voidLCD_Busy_Wait()
while((Read_LCD_State()&0x80)==0x80);
DelayMS(5);
}
3、向LCD写入命令
//---——--—-—-写LCD命令—-—-—-——--—-———--*/
voidWrite_LCD_Command(ucharcmd)
{
LCD_Busy_Wait();
RS=0;
RW=0;
P0=cmd;
EN=1;
4、向LCD写入数据
//--————----—向LCD写入数据--——---——---—----*/
voidWrite_LCD_Data(uchardat)
RS=1;
RW=0;
EN=0;
P0=dat;
}
5、LCD初始化
//—-————---—-LCD初始化——-—-———-—-----—-*/
voidInitialize_LCD1602()//液晶初始化函数
Write_LCD_Command(0x38);
DelayMS
(2);
//功能设置,数据长度为8位,双行显示5×
7点//阵字体
Write_LCD_Command(0x01);
//清屏
Write_LCD_Command(0x06);
//字符进入模式:
屏幕不动,字符后移
Write_LCD_Command(0x0c);
//显示开,关光标
6、设置LCD液晶的显示位置
//—----———---设置液晶显示位置—-—————--———-—-——*/
voidSet_LCD_Position(ucharpos)
Write_LCD_Command(pos|0x80);
//设置7位的DDRAM地址值
7、显示字符
//—------——--在LCD上显示字符串-————--———-——---—*/
voidLCD_Display(ucharp,uchar*str)
uchari;
Set_LCD_Position(p);
for(i=0;
i〈16;
i++)
{
Write_LCD_Data(str[i]);
DelayMS
(2);
}
除此之外,还有年、月、日、时、分等的设置函数,显示函数,键盘处理函数等,在此不在详细介绍,同学们可参考完整程序中的代码。
☆完整程序代码
1、LCD1602。
c源程序
//-—---———------————---LCD1602。
c——-————-——-—--—-—-—-—-—--—
//液晶控制与显示驱动程序
//—----———--——-—---—-—----—-——-———----—-—--————--—-—--—-——
#include〈reg51。
h〉
#include<
intrins。
h>
#defineucharunsignedchar
#defineuintunsignedint
sbitRS=P2^0;
//LCD寄存器选择
sbitRW=P2^1;
//LCD读写控制
sbitEN=P2^2;
//LCD启动
//*-—-—-——-延时子程序--—-————*//
voidDelayMS(uintK)
while(K-—)
{
for(i=0;
i〈120;
i++);
}
//--—————--—读取LCD的状态-------*/
ucharstate;
DelayMS
(2);
//--——--—--———-忙检查—-—--—-—--—-—-*/
while((Read_LCD_State()&
0x80)==0x80);
DelayMS(5);
//-—-----—--—写LCD命令----—-—-—---————-*/
LCD_Busy_Wait();
P0=cmd;
//—-——--——-——向LCD写入数据-—--———-———-—--—-*/
RS=1;
}
//—————————--LCD初始化——-————-—---—--——*/
Write_LCD_Command(0x38);
DelayMS
(2);
//功能设置,数据长度为8位,双行显示,5×
7点阵字体
Write_LCD_Command(0x06);
屏幕不动,字符后移
//-——---—----设置液晶显示位置—--———-———-—-----*/
//--—--——————在LCD上显示字符串---————-—————-—--*/
voidLCD_Display(ucharp,uchar*str)
i<
16;
{
Write_LCD_Data(str[i]);
2、main.c源程序
//—-——-————-————-—----——--—-——----——--——----—--——---——————--—--—-—-—-——--—
//名称:
用DS1302和1602液晶显示的实时时钟
//-—--—-—--——--————-—-———--—-—-——————--—————-——--—--——-——-——-—-—-—————-——--
//说明:
本程序运行时会以PC时间为默认时间开始运行,运行过程中可以通过K1按键选择调节对象,用K2、K3
//按键进行加减,用K4按键保存。
//——————---—-—-———-——---———--————----—-----—--—-------—---—-—-———----—-———--———----—-—-——
reg51.h>
#include〈string。
#include〈intrins.h>
voidInitialize_LCD1602();
//液晶初始化函数
voidLCD_Display(ucharp,uchar*str);
sbitSDA=P1^0;
//DS1302数据线
sbitCLK=P1^1;
//DS1302时钟线
sbitRST=P1^2;
//DS1302复位线
sbitk1=P3^3;
//选择按键
sbitk2=P3^4;
//加
sbitk3=P3^5;
//减
sbitk4=P3^6;
//确定
uchartcount=0;
ucharMonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31};
//一年中每个月的天数,二月的天数由年份决定
uchar*Week[]={”SUN"
,"
MON”,"
TUS"
"
WEN”,"
THU"
FRI"
SAT”};
//周日,周一到周六
//LCD显示缓冲
ucharLCD_DSY_BUFFER1[]={"
DATE00-00—00"
};
ucharLCD_DSY_BUFFER2[]={"
TIME00:
00:
00"
ucharDateTime[7];
//所读取的日期时间
charAdjust_Index=-1;
//当前调节的时间对象:
秒,分,时,日,月,年(0,1,2,3,4,6)
ucharChange_Flag[]="
-MHDM-Y"
;
//(分,时,日,月,年)不调节秒和周
//函数声明
voidWrite_Byte_TO_DS1302(ucharX);
//向DS1302写入一个字节
ucharRead_Byte_FROM_DS1302();
//从DS1302中读取一个字节
ucharRead_Data_FROM_DS1302(ucharaddr);
//从DS1302指定位置读取数据,读数据
v