LCD数字电子钟的设计.docx
《LCD数字电子钟的设计.docx》由会员分享,可在线阅读,更多相关《LCD数字电子钟的设计.docx(37页珍藏版)》请在冰豆网上搜索。
LCD数字电子钟的设计
内蒙古科技大学
智能仪表综合训练设计说明书
题目:
LCD数字电子钟
学生姓名:
王雪利
学号:
0967112230
专业:
测控技术与仪器
班级:
2009-2
指导教师:
肖俊生
日期:
2012-10-22
LCD显示数字电子钟
摘要
随着科技的发展,单片机的应用正在不断深入,涉及到日常生活的方方面面。
本设计是基于单片机89C52为控制核心,以LCD1602为显示的数字时钟。
其主要功能是可正常显示时钟、日历、带有定时闹钟的多功能数字电子钟。
本设计采用89C52RC单片机芯片作为中央处理器,内部定时器定时计数产生时钟日历信息,星期通过编程计算自动生成,并利用液晶显示屏LCD1602来显示时钟、日历、星期、闹钟等信息,通过按键来设置或校准相关信息。
本数字时钟设计的原理相对简单,所以硬件电路也相对简单,难点和重点主要放在C语言的编程上,使用到定时器的子程序、延时程序、键盘程序、液晶模块和单片机模块的初始化程序、液晶显示的程序等,各个函数交叉调用,配合主程序的运行。
关键字:
电子钟;STC89C52;LCD1602;键盘;定时器
第一章前言
随着电子技术的不断发展,单片机技术在设计中所体现出来的优势越来越明显,它不仅是电子信息类专业的一个重要部分,而且在其他类专业工程中也是不可缺少的。
广泛地应用于家电、工业过程控制、仪器仪表、智能武器、航天和空间飞行器等领域,已成为新一代一些电子设备不可缺少的核心部件。
单片机把计算机最基本的功能电路,如CPU、程序存储器、数据存储器、I/O接口、定时、计数器、中断系统等集成到一块芯片上,形成单片形态的计算机。
单片机通常以最小系统运行,在家用电器中和常用的智能仪器仪表中常常可以“单片”工作,同时单片机在我们日常生活中叶经常见到,同时单片机在我们日常生活中也经常见到,如电子表、舞厅里的一些等国的控制、工厂一些自动化控制等。
将来只要有自动控制方面的都会离不开单片机的开发和使用,对于现代的自动化控制起着举足轻重的作用。
而数字钟正是一种用数字电路技术与单片机技术实现计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更更长的使用寿命,因此得到了广泛的使用[1]。
数字时钟是指以微处理器为核心,充分利用数字技术和软件技术,与各类脉冲信号的传感器配合,记录时间等的智能仪表。
数字时钟是日常生活、工业生产中常用的一种工具,社会拥有量和需求量都很大。
功能上要求能够完成准确走时、调时,性能上要求抗干扰能力强,稳定可靠,同时在价格上具备竞争力[2]。
结合以上几点,设计了一款数字时钟,该数字时钟设计工作原理为:
单片机上电后,定时器工作计时开始,通过按键进行调时及闹钟调整,通过LCD显示其值。
日常生活中对单片机数字钟的问题要求越来越高,本设计仅针对简单的数字钟进行研究,能够实现数字时钟的正确走时。
第二章数字电子钟整体方案设计
2.1方案原理
本系统由STC89C52RC单片机和字符点阵型LCD1602液晶显示器等器件构成。
用单片机内部定时器定时产生计数信号,单片机把数据进行处理,然后把数据传输到显示模块LCD1602液晶显示器,实现时间和日期的显示。
通过编写程序实现具体的功能,如年、月、日、星期、时、分、秒,以及时间的校准、闹钟的设置等。
再通过编写LCD液晶显示器的驱动程序,使其信息显示在LCD1602液晶显示器上。
系统方框图如图2-1所示。
图2-1系统方框图
键盘是为了完成时钟、日历的校对和日历的显示功能。
由于此电子时钟要求具有闹铃功能,所以设计有闹铃电路,进行声音响铃。
2.2所用硬件简介
2.2.1STC89C52单片机
STC系列单片机是由STMicroelectronics公司生产,并有宏晶公司做大陆代理的。
STMicroelectronics即意法半导体公司是1987年6月在意大利的SGS微电子公司和法国的汤姆逊微电子公司合并后产生的。
1998年5月,公司由原来的SGS汤姆逊(SGSTHOMSON)微电子公司改名为意法半导体公司(STMicroelectronics),简称ST公司[3]。
STC89C52RC可以代替AT89C51,功能更强,速度更快,寿命更长,价格更低。
它是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器[4]。
在单芯片上,拥有8位CPU和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
它具有以下标准功能,8k字节Flash,512字节RAM,32位I/O口线,看门狗定时器,内置4kBEEPROM,MAX810复位电路,三个16位定时器/计数器,一个6向量2级中断结构,全双工串行口[5]。
STC89C52RC的内核和AT51系列单片机一样,故引脚相同,外形及引脚排列也相同。
STC89C52RC封装图如2-2所示。
图2-2STC89C52RC封装图
2.2.2LCD液晶显示器
LCD1602液晶显示器以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,在袖珍式仪表和低功耗应用系统中得到越来越广泛的应用。
本系统使用是是LCD1602液晶显示器,它可以显示两行,每行16个字符,采用单+5V电源电,外围电路配置简单,价格便宜,具有很高的性价比[6]。
LCD1602封装图如图2-3所示。
图2-3LCD1602封装图
LCD1602采用标准的16脚接口,其中VSS为地电源,VDD接5V正电源,VEE为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
RW为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
D0~D7为8位双向数据线。
BLA背光源正极,BLK背光源负极。
LCD1602模块引脚功能图如图2-4所示。
编号
符号
引脚说明
编号
符号
引脚说明
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
BAL
背光源正极
8
D1
数据
16
BLK
背光源负极
图2-4LCD1602模块引脚功能图
2.2.3晶振的选择
这里使用的晶振频率为11.0592MHz.
第三章数字电子钟硬件设计
3.1显示电路的设计
系统的显示电路采用的是液晶显示方式。
采用1602字符点阵型液晶模块,上一行显示日期,星期,下一行显示时间或是闹钟。
使用起来比较灵活,操作简单,易控制,能够带来很大的方便。
在LCD1602液晶显示模块和单片机STC89C52RC相连接时的,具体的接法为:
将VSS接地,VDD接高电平,VEE接地。
将RS接到P1.0口,R/W接到P1.1口,E接到P1.2口。
D0~D7接到P0口来控制命令输入及数据的输入/输出。
具体的连接电路如图3-1所示。
图3-1LCD1602和单片机STC89C52RC接口电路
3.2按键电路的设计
根据功能需要,本时钟需要设置以下功能键:
时间设置键,加1键,减1键,推出确定键。
按照键盘与CPU的连接方式可分为独立式键盘和矩阵式键盘。
本设计采用独立式键盘是各个按键相互独立,每个按键占用一个I/O口线,每根I/O口线上的按键不会影响其他I/O口上按键工作状态。
独立式键盘电路配置灵活,软件结构简单,但每个按键必须占用一根I/O口,在按键数量较多时,I/O口线浪费较大,且电路结构复杂。
矩阵式键盘适合按键较多时使用。
由于本设计的电子钟最多需要4个按键,若采用矩阵式键盘时会有按键浪费,故采用的是独立式键盘。
具体的连接电路如图3-2所示。
图3-2键盘电路
单片机管脚只有在按键按下时为低电平,按键弹出后重新恢复高电平。
按键操作说明如下:
K1键:
该键为时间设置键,每次按动该键,都会使其计数变量加1。
K1计数变量为1~9次,分别调节年、月、日、星期、时、分、秒和闹钟时、分。
当按下次数为十时,计数变量清零。
K2键:
该键为加1键。
该键每次按下将使相应校对位进行加1操作。
当设置键计数变量为0时,按下此键可切换闹钟的开关状态。
K3键:
该键为减1键。
该键每次按下将使相应校对位进行减1操作。
当设置键计数变量为0时,按下此键可关闭当天的闹钟铃响状态。
K4键:
该键为退出确认键。
按下此键,K1键计数变量清零。
3.3闹铃电路设计
本设计采用蜂鸣器闹铃,如当前时刻与闹铃时间相同,单片机向蜂鸣器送出低电平,蜂鸣器发声。
采用蜂鸣器闹铃结构简单,控制方便,但是发出的闹铃声音单一。
闹铃电路与按键K4共占用单片机一根I/O口P1.7,中间用PNP型三极管连接P1.7和蜂鸣器。
当P1.7引脚为低电平时,三极管的发射极和集电极导通,使蜂鸣器发声。
当响铃标志位为“1”时,P1.7送一定频率脉冲,使蜂鸣器发出声音,电路连接如图3-3所示。
图3-3闹铃电路
3.4复位电路设计
复位是单片机的初始化操作,以便使CPU和系统中其他部件都处于一个确定的初始状态,并从这个状态开始工作。
除了进入系统的正常初始化之外,当单片机系统在运行出错或操作错误使系统处于死锁状态时,也可按复位键重新启动。
电路连接如图3-4所示。
图3-4复位电路
3.5晶振电路的设计
STC89C52单片机的时钟产生方法有两种:
内部时钟方式和外部时钟方式。
本设计采用内部时钟方式,利用芯片内部的振荡电路,在X1、X2引脚上外接定时组件,内部的震荡电路会产生自激震荡。
本设计采用常用的内部时钟方式,即用外接晶体和电容组成的并联谐振回路。
震荡晶体选择可在1.2MHz到12MHz之间选择。
电容值无严格要求,但电容取值对震荡频率输出的稳定性、大小、震荡电路起震速度有少许影响,C1、C2可在20pF到100pF之间取值,但在60pF到70pF时震荡器会有较高的频率稳定性。
所以在本设计中,震荡晶体选择11.0592MHz,电容选择30pF,电路连接如图3-5所示。
图3-5晶振电路
第四章数字电子钟的软件设计
4.1定时器模块部分
产生时间函数流程图如图4-1所示。
图4-1时间产生程序流程图
4.2LCD显示模块部分
4.2.1基本操作程序
读状态:
输入:
RS=L,RW=H,E=H输出:
D0~D7=状态字
读数据:
输入:
RS=H,RW=H,E=H输出:
无
写指令:
输入:
RS=L,RW=L,D0~D7=指令码,E=高脉冲输出:
D0~D7=数据
写数据:
输入:
RS=H,RW=L,D0~D7=数据,E=高脉冲输出:
无
4.2.2状态字说明
1602的状态字说明如下表4-2所示。
其中,STA0~STA6为当前地址指针的数值,STA7读写操作使能,1是禁止,0是允许,每次对控制器进行读写操作之前,必须进行读写检测,确保STA7为0。
STA7
STA6
STA5
STA4
STA3
STA2
STA1
STA0
D7
D6
D5
D4
D3
D2
D1
D0
表4-2LCD1602状态说明表
4.2.3显示部分程序流程图
1忙检测函数流程图,如图4-3所示。
图4-3忙检测程序流程图
2写指令数据函数流程图,如图4-4所示。
图4-4写指令数据程序流程图
3LCD初始化函数流程图,如图4-5所示。
图4-5LCD初始化程序流程图
4.3键盘模块部分
程序设计流程如图4-6所示。
图4-6键盘程序流程图
4.4闹铃模块部分
闹铃程序流程图如图4-7所示。
图4-7闹铃程序流程图
4.5主程序设计流程
1主程序流程图如图4-8所示。
图4-8主程序流程图
2星期显示程序流程图如图4-9所示。
图4-9星期显示程序流程图
3显示类程序流程图如图4-10所示。
图4-10显示类程序流程图
第五章PCB板的制作
ProtelDXP是进行印制电路板(PBC)设计的重要工具。
原理图设计工作主要包括电路板规划、元器件的选择、布局和连线,构成了制版的基础内容。
电路设计的最终目的是生产制作电子产品,各种电子产品的使用功能与物理结构都是通过印制电路板来实现的。
本设计制作PCB印刷电路板基本流程如图5-1所示。
图5-1制作PCB板流程图
用protelDXP制作LCD显示电子钟原理图如图5-2所示。
图5-2数字电子钟原理图
用protelDXP制作PCB印刷电路板如图5-3所示。
图5-3数字电子钟PCB板
第六章软件调试与分析
系统仿真分析电路原理图在proteus里设计完成,并将系统软件编译成.Hex文件,再进行电子时钟的系统虚拟仿真。
观察显示结果,根据显示的结果和课题的要求再修改程序,再运行检测,直到满足要求。
(1)在proteus的原理图中,右键单击AT89C51将其选中,然后单击左键打开AT89C51的EditComponent对话框,
(2)选择相应的.Hex文件,再在ProteusISIS编辑窗口的File菜单中选择SaveDesign选项,保存设计,生成.DSN文件。
在ProteusISIS的Debug菜单中选择Execute,运行程序,系统仿真结果如图6-1所示。
图6-1数字电子钟仿真结果图
实现功能的具体方法:
按下第一个键K1键时钟进入调整功能时,按第二个键K2进行加1运算,按第三个键K3进行减1运算。
按次数按下第一个键K1,等数字闪烁后,按一二键进行加减,从而可以依次进行具体日期时间调整,按K4键退出调整。
当K1按键次数为零时,K2键有切换闹钟开关功能,K3键有关闭此次闹钟功能。
日期显示格式为:
年-月-日-星期;时间显示格式为:
时-分-秒。
整个数字电子钟具有显示时间日期,定闹钟的功能。
参考文献
[1]李群芳.单片机原理、接口及应用[M].北京:
清华大学出版社,2005,3:
27-31,178-186
[2]许兴存,曾琪琳.微型计算机接口技术[M].北京:
电子工业出版社,2005,7:
308-329
[3]丁元杰.单片微机原理及应用[M].北京:
机械工业出版社,2006,3:
1-10,166-180
[4]刘文涛.单片机应用开发实例[M].北京:
清华大学出版社,2005,9:
19-26,42-156
[5]郭天祥.新概念51单片机C语言教程[M].北京:
电子工业出版社,2009,6:
312-331
[6]王兆安.黄俊.电力电子技术[M].机械工业出版社,2005,9:
43
[7]张友德,涂时亮,赵志英.单片微型机原理、应用与实验(C51版):
复旦大学出版社,2010,8
[8]贾振国,许琳.智能化仪器仪表原理与应用。
中国水利水电出版社,2011,3
[9]PROTEL+DXP2004教程_XX文库
[10]Proteus在MCS-51&ARM7系统中的应用百例[J].电子工业出版社,2006,10:
5-7
附录A:
数字电子钟硬件原理图
附录B:
数字电子钟源程序
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitlcd_rs=P1^0;
sbitlcd_rw=P1^1;
sbitlcd_en=P1^2;//液晶控制端
sbitkey_set=P1^4;
sbitkey_up=P1^5;
sbitkey_down=P1^6;//同时也是闹钟停止按钮
sbitkey_out=P1^7;//键盘控制端口,同时也是闹钟输出端口
ucharcount;//定时器计数变量
ucharhour,min,sec,hour1,hour2,sec1,sec2,min1,min2;//时间变量
ucharyue,ri,nian1,nian2,nian3,nian4,yue1,yue2,ri1,ri2;//月日变量
uintnian;//年变量
ucharnao1=0,nao2=0,nao3=0,nao11,nao12,nao21,nao22;//设置闹钟变量
ucharcount1;//星期计数变量
ucharww=0,qq=0,nao=1;//键盘设置端口计数变量,闹铃标志变量
voidlcd_delay(uintm)//延时函数
{
while(m--);
}
voidread1602(charcom)//忙检测
{
uchari;
i=254;
P0=0xff;
lcd_rs=0;//读写命令
lcd_rw=1;//读命令/数据
lcd_en=1;
while((i--)&&(P0&0x80));//若一段时间以后仍低,则认为是不忙
lcd_en=0;
}
voidwrite1602(ucharwdata,bitrw)//向LCD1602写数据(rw=1)或者命令(rw=0)
{
read1602();
lcd_rs=rw;
P0=wdata;
lcd_rw=0;
lcd_delay
(1);
lcd_en=1;
lcd_delay
(1);
lcd_en=0;
}
voidlcd_init()//LCD1602液晶的初始化
{
lcd_delay(1500);
write1602(0x38,0);//置功能,8位数据,2行显示,5x7字符
write1602(0x0c,0);//只打开屏显
write1602(0x06,0);//左到右显示,自加1
write1602(0x01,0);//清屏
write1602(0x80,0);
}
voidinit()//定时器初始化
{
count=0;
hour=23;//小时初值
min=59;//分钟初值
sec=50;//秒初值
nian=2012;//年初值
yue=10;//月初值
ri=12;//日初值
count1=5;//星期初值
TMOD=0x01;//中断T0工作方式
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;//计数器初值,为50ms
TR0=1;
ET0=1;
EA=1;//开中断
}
voidlcd_printf(uchar*str)//显示字符串
{read1602();
while(*str!
='\0')
{
write1602(*str,1);//写入数据
str++;
lcd_delay
(1);
}
}
voidlcd_moveto(ucharx,uchary)//指定显示的行列坐标
{
if(x==0)
write1602(0x80|y,0);
if(x==1)
write1602(0xc0|y,0);
}
voidfengjie1(uchara,ucharb,ucharc)//将时分秒两位数分解为两个数
{
hour1=a/10;
hour2=a%10;
min1=b/10;
min2=b%10;
sec1=c/10;
sec2=c%10;
}
voidfengjie2(uinta,ucharb,ucharc)//将年月日分解为两个数
{
nian4=a%10;
a=(a-nian4)/10;
nian3=a%10;
a=(a-nian3)/10;
nian2=a%10;
nian1=a/10;
yue1=b/10;
yue2=b%10;
ri1=c/10;
ri2=c%10;
}
voidfengjie3(uchara,ucharb)//将闹钟分解为两个数
{
nao11=a/10;
nao12=a%10;
nao21=b/10;
nao22=b%10;
}
voiddisplay1(ucharhour1,ucharhour2,ucharmin1,ucharmin2,ucharsec1,ucharsec2)//显示时间程序
{
lcd_moveto(1,0);//定位在第二行第一列
write1602(hour1+48,1);
write1602(hour2+48,1);
lcd_printf(":
");
write1602(min1+48,1);
write1602(min2+48,1);
lcd_printf(":
");
write1602(sec1+48,1);
write1602(sec2+48,1);
}
voiddisplay2(ucharnian1,ucharnian2,ucharnian3,ucharnian4,ucharyue1,ucharyue2,ucharri1,ucharri2)//显示日期程序
{
lcd_moveto(0,0);//定位在第一行第一列
write1602(nian1+48,1);
write1602(nian2+48,1);
write1602(nian3+48,1);
write1602(nian4+48,1);
lcd_printf("-");
write1602(yue1+48,1);
write1602(yue2+48,1);
lcd_printf("-");
write1602(ri1+48,1);
write1602(ri2+48,1);
}
voiddisplay3(ucharwe)//星期送显示
{
lcd_moveto(0,12);
switch(we)
{
case1:
lcd_printf("M");
lcd_printf("0");
lcd_printf("N");
break;
case2:
lcd_printf("T");
lcd_printf("U");
lcd_printf("E");
break;
case3:
lcd_printf("W");
lcd_printf("E");
lcd_printf("D");
break;
case4:
lcd_printf("T");
lcd_printf("H");