智能电子钟LCD显示剖析.docx
《智能电子钟LCD显示剖析.docx》由会员分享,可在线阅读,更多相关《智能电子钟LCD显示剖析.docx(37页珍藏版)》请在冰豆网上搜索。
![智能电子钟LCD显示剖析.docx](https://file1.bdocx.com/fileroot1/2023-4/19/46e18bf4-57d6-4882-bc7c-e9de7ecb9712/46e18bf4-57d6-4882-bc7c-e9de7ecb97121.gif)
智能电子钟LCD显示剖析
课程设计
课程名称单片机原理与接口技术
题目名称智能电子钟
学生学院材料与能源学院
专业班级
学号
学生姓名
指导教师
2016年06月15日
广东工业大学课程设计任务书
题目名称
智能电子钟(LCD显示)
学生学院
材料与能源学院
专业班级
姓名
学号
一、课程设计的内容
用STC89C52RC单片机制作一智能电子钟:
1.设计并绘制硬件电路图;
2.绘制PCB板图(条件许可的话可进行PCB板的制作)并焊接好元器件;
3.编写程序并将调试好的程序固化到单片机中。
二、课程设计的要求与数据
以STC89C52RC单片机为核心,制作一个LCD显示的智能电子钟:
(1)计时:
秒、分、时、天、周、月、年。
(2)自由调整时间。
(3)定时输出,可任意关断,重置。
(4)倒计时功能,最高可定时100小时。
(5)计时功能,最高可计时100小时。
(6)计时精度:
误差≤1秒/月(具有微调设置)。
(7)键盘采用动态扫描方式查询。
所有的查询、设置功能均由矩阵键盘完成。
三、课程设计应完成的工作
1.完成下载线的制作,为程序下载到单片机芯片中做好准备;
2.完成软件、硬件的设计,并进行硬件的焊接制作,并将调试成功的程序固化到单片机中,最后进行硬件与软件的调试;
3.撰写设计说明书。
四、课程设计进程安排
序号
设计各阶段内容
地点
起止日期
1
硬件、软件设计
大学城工学三号馆317
6月6-8日
2
焊接电路板
大学城工学三号馆317
6月9-11日
3
软件、硬件调试
大学城工学三号馆317
3月12-13日
4
撰写说明书
宿舍
3月14-15日
5
答辩
大学城工学三号馆317
3月16-17日
摘要
随着时代的进步和发展,单片技术已经普及到我们的生活、工作、科研等各个领域,已经成为一种比较成熟的技术,本文将介绍一种基于单片机控制的LCD显示时钟的设计,时间可由键盘调整。
主要用到的芯片有单片机STC89C52RC、液晶显示屏LCD1602A模块、时钟芯片DS1302模块。
关键词:
单片机STC89C52RC、LCD1602A模块、DS1302模块
1系统需要分析
1.1智能电子钟研究背景及意义
20世纪末,电子技术得到了飞速发展,在此推动下现代电子产品几乎渗透到了社会的各个领域,有力地推动和提高了社会生产力的发展和信息化程度,同时现代电子产品性能进一步提升,产品的更新迭代也越来越快。
时间对人们来说是那么宝贵,工作的忙碌和繁杂易使人们忘记当前的时间。
然而遇到重大事情的时候,一旦忘记时间,就会给自己和他人造成很大的麻烦。
平时我们要求上班准时,约会或者召开会议必然要提及时间,火车要准时到达,航班要准时起飞,工业生产中的很多环节也需要时间来确定工序替换时刻,等等。
所以说能随时知道准确的时间是我们生活中必不可少的一件事情。
想知道时间,收表当然是很好的选择,但是在忙碌中,我们还需要一个“助理”时不时的给我们提醒时间。
所以,手表最好有一个定时系统,随时提醒忘记时间的人。
最早能够定时、报时的时钟属于机械式钟表,但这种时钟收到机械结构、动力和体积的限制,在功能性以及造价上都没有办法与电子时钟相媲美。
电子时钟是采用电子电路实现对时、分、秒进行数字显示的计时装置,广泛应用于个人、家庭、车站、办公室等场所,成为人们日常生活中的必需品。
由于集成电路的发展和石英晶振的广泛应用,使得电子时钟的精度远远超过老式钟表,钟表的数字化跟人们生产和生活带来了极大的方便,而且大大扩展了钟表的功能。
诸如整点报时、定时报警、定时广播、自动启闭路灯、定时开关烘箱、同多动力设备、甚至各种定时电器的自动启动等,所有这些,都是以电子时钟为基础的。
因此,研究电子时钟及其扩展应用,都有非常重要的现实意义。
1.2系统实用功能分析
本文研究的数字时钟是一种利用单片机原理实现对时、分、秒计时的装置,与机械时钟相比具有更高准确性和直观性,且无机械装置,具有更长的使用寿命。
其实现了对时、分、秒的准确及时、计时及定时功能。
2设计要求与方案
2.1设计要求
以STC89C52RC单片机为核心,制作一个LCD显示的智能电子钟:
(1)计时:
秒、分、时、天、周、月、年。
(2)自由调整时间。
(3)定时输出,可任意关断,重置。
(4)倒计时功能,最高可定时100小时。
(5)计时功能,最高可计时100小时。
(6)计时精度:
误差≤1秒/月(具有微调设置)。
(7)键盘采用动态扫描方式查询。
所有的查询、设置功能均由矩阵键盘完成。
2.2系统基本方案选择
2.2.1芯片的选择
采用STC89C52,其是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。
STC89C52使用经典的MCS-51内核,但做了很多的改进使得芯片具有传统51单片机不具备的功能。
在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
具有以下标准功能:
8k字节Flash,512字节RAM,32位I/O口线,看门狗定时器,内置4KBEEPROM,MAX810复位电路,3个16位定时器/计数器,4个外部中断,一个7向量4级中断结构(兼容传统51的5向量2级中断结构),全双工串行口。
另外STC89X52可降至0Hz静态逻辑操作,支持2种软件可选择节电模式。
空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。
掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
最高运作频率35MHz,6T/12T可选。
2.2.2显示模块选择
采用LCD显示,电路较为简单,且在软件设计上也相对简单,功耗较低,能满足设计最优的要求。
LCD1602A模块集成了驱动电路和背光等,能够显示16*02(16列2行)即32个字符。
2.2.3时钟信号的选择
采用DS1302时钟芯片实现时钟计时。
DS1302时钟芯片是一种高性能的时钟芯片,可自动实现对秒、分、时、日、周、月、年及闰年补偿的年进行计数,精度较高,256位的RAM作为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA。
且硬件电路较为简单,程序设计容易实现。
DS1302模块接有32.768K晶振和纽扣电池作为备用电源,可实现长时间不停地计时。
2.2.4按键选择
选择4*4矩阵键盘作为功能实现和调节按键。
矩阵键盘又称行列式键盘,它是用4条I/O线作为行线,4条IO线作为列线组成的键盘。
在行线和列线的每一个交叉点上,设置一个按键。
这样键盘中按键个数是4*4个。
这种行列式键盘结构能够有效地提高单片机系统中I/O的利用率。
2.3电路设计最终方案
宗上所述,对此次智能电子钟的方案选择为:
采用STC89C52SC芯片作为主控制系统并提供定时,并由DS1302模块提供时钟,LCD1602A模块作为显示时间。
3系统硬件设计与实现
3.1智能电子钟设计框图
3.2系统硬件概述
该电路是由STC89C52SC单片机为控制核心,具有在线编程功能,低功耗,能在3V超低工作;晶振电路外接晶振;复位电路接按键复位系统;矩阵键盘由4*4行列式键盘构成;LCD显示模块由LCD1602A构成;时钟电路模块由DS1302芯片等组成。
3.3硬件电路结构设计
3.3.1单片机主控制模块的设计
图1为用proteus软件画的时钟系统原理图。
3.3.2LCD显示模块
图2为LCD显示模块原理图。
如图所示,时钟信号显示在LCD上,文字清晰可见而且
图1时钟原理
图2LCD1602A
省电也易于控制。
数据的传输采用P0口,其引脚VSS接地,VDD接VCC,RS、RW、E端分别接单片机引脚P2.0、P2.1、P2.2。
而VEE作为液晶显示器的灰度调节引脚,接一变阻器来改变其显示的清晰度。
3.3.3矩阵键盘模块
图3为矩阵键盘模块。
矩阵键盘又称行列式键盘,它是用4条I/O线作为行线,4条IO线作为列线组成的键盘,8条线接到P1口上。
在行线和列线的每一个交叉点上,设置一个按键。
这样键盘中按键个数是4*4个。
这种行列式键盘结构能够有效地提高单片机系统中I/O的利用率。
矩阵键盘是嵌入式计算机系统中不可缺少的外围电路,是实现人机对话的纽带,借助键盘可以向计算机输入程序、置数、逻辑操作以及写入程序和程序检测等,可实现调试、计时、倒计时等功能。
图3矩阵键盘
3.3.4时钟系统模块
图4是时钟系统模块原理图。
DS1302是美国DALLAS公司推出的一种
图4时钟系统DS1302
高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。
实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。
工作电压宽达2.5~5.5V。
采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。
DS1302的RST端接P2.5口,SCLK端接P2.6口,I/O端接P2.7口,VCC1端接备用电源纽扣电池,VCC2接5.0V电源,X1、X2接32.768K晶振。
3.3.5蜂鸣器模块
图5蜂鸣器模块
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于电子产品中作为发声器件。
蜂鸣器I/O端接到P2.4口上,用三极管驱动,给低电平就能持续发声。
3.3.6复位电路
图6复位电路
图6为复位电路。
只要按下按钮,给单片机RST口加上超过2个机器周期的高电平,就能把单片机复位。
3.3.7晶振电路
图7为晶振电路。
STC19C51RC单片机时钟信号由内部时钟方式产生,在XTAL1和XTAL2引脚外接晶振。
图中,电容C1和C2的作用是稳定频率和快速起振,电容值22pF。
晶振CXY的振荡频率为11.0592Hz。
图7晶振电路
4系统软件设计
4.1程序流程框图
4.2程序
具体程序见附录。
5系统调试
5.1软件调试
打开程序调试软件KeiluVision4,在里面新建一个工程,命名为:
clock。
接着新建文件,编写相应程序。
编写好的程序进行编译。
如有错误,按照提示修改错误,直到程序编译通过。
5.2硬件调试
用proteus画好电路原理图,加上KeiluVision4生成的HEX文件进行仿真,并修改程序逻辑错误,直到仿真无错误。
参考文献
[1].李朝青.单片机原理及接口技术(第3版).北京航天航空大学出版社,2005年10月.
[2].求是科技.单片机典型外围器件及应用实例.北京:
人民邮电出版社,2006年2月.
[3].谭浩强.C语言程序设计(第二版).北京:
清华大学出版社,1999年12月.
[4].阎石.数字电子技术基础(第五版).高等教育出版社,1983年4月.
附录
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitrs=P2^0;
sbitrw=P2^1;
sbite=P2^2;//1602
sbitrst=P2^5;
sbitsclk=P2^6;
sbitio=P2^7;//1302
sbitbee=P2^4;//蜂鸣器
uchartable[]="2016-06-12MON";//日期格式
uchartable1[]="00:
00:
00A";//时间格式
uchartime[]={11,1,11,11,00,00,00};//年周月日时分秒
ucharcodewrite_add[]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//1302写数据地址
ucharcoderead_add[]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};//1302读数据地址
ucharn1,n2,y1,y2,r1,r2,s1,s2,f1,f2,m1,m2,xq;
ucharkey;//矩阵键盘数值
ucharsp,sn1,sn2;
voiddelay(uintz)//延时函数
{
uinti,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
voidwrite_com(ucharcom)//写1602命令
{
rs=0;
rw=0;
e=0;
P0=com;
delay(5);
e=1;
delay(5);
e=0;
}
voidwrite_data(uchardat)//写1602数据
{
rs=1;
rw=0;
e=0;
P0=dat;
delay(5);
e=1;
delay(5);
e=0;
}
voidstart()//1602初始化
{
write_com(0x01);//清屏
write_com(0x38);//16*2显示,5*7点阵,8位数据
write_com(0x0c);//显示开,光标关
write_com(0x06);//显示方式:
AC加一,光标右移一格
}
voidshow_init()//在1602显示时间格式
{
ucharnum;
write_com(0x80);//第一行显示数据
for(num=0;num<16;num++)
{
write_data(table[num]);
};
write_com(0x80+0x40);//第二行显示
for(num=0;num<10;num++)
{
write_data(table1[num]);
}
}
voidwrite_byte(uchardat)//向1302写1byte数据
{
uchari;
for(i=8;i>0;i--)
{
io=dat&0x01;
sclk=1;
sclk=0;
dat=dat>>1;
}
}
voidwrite_1302(ucharadd,uchardat)//按地址向1302写数据
{
rst=0;
sclk=0;
rst=1;
write_byte(add);
write_byte(dat);
sclk=1;
rst=0;
}
unsignedcharread(ucharadd)//按地址读取1302数据
{
uchari,value=0x00;
rst=0;
sclk=0;
rst=1;
write_byte(add);
for(i=0;i<8;i++)
{
value=value>>1;
sclk=0;
if(io)value=value|0x80;
sclk=1;
}
sclk=1;
rst=0;
return(value);
}
voidtime_pors()//取时间函数
{
m1=time[6]/16;//秒
m2=time[6]%16;
f1=time[5]/16;//分
f2=time[5]%16;
s1=time[4]/16;//时
s2=time[4]%16;
r1=time[3]/16;//日
r2=time[3]%16;
y1=time[2]/16;//月
y2=time[2]%16;
n1=time[0]/16;//年
n2=time[0]%16;
xq=time[1];//星期
}
voidshow_date()//显示日期
{
write_com(0x83);
write_data(0x30+n1);
write_data(0x30+n2);
write_com(0x86);
write_data(0x30+y1);
write_data(0x30+y2);
write_com(0x89);
write_data(0x30+r1);
write_data(0x30+r2);
}
voidshow_xq()//显示星期
{
write_com(0x8d);
if(time[1]==1)//SUN
{
write_data(0x53);
write_data(0x55);
write_data(0x4e);
}
if(time[1]==2)//MON
{
write_data(0x4d);
write_data(0x4f);
write_data(0x4e);
}
if(time[1]==3)//TUE
{
write_data(0x54);
write_data(0x55);
write_data(0x45);
}
if(time[1]==4)//WED
{
write_data(0x57);
write_data(0x45);
write_data(0x44);
}
if(time[1]==5)//THU
{
write_data(0x54);
write_data(0x48);
write_data(0x55);
}
if(time[1]==6)//FRI
{
write_data(0x46);
write_data(0x52);
write_data(0x49);
}
if(time[1]==7)//SAT
{
write_data(0x53);
write_data(0x41);
write_data(0x54);
}
}
voidkeyscan()//键盘扫描函数
{
uchartemp;
P1=0xfe;//第一行
delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delay(5);
temp=temp&0xf0;
if(temp!
=0xf0)
{
temp=P1;
switch(temp)
{
case0x7e:
key=10;break;
case0xbe:
key=3;break;
case0xde:
key=2;break;
case0xee:
key=1;break;
}
while(P1!
=0xfe)
{
P1=0xfe;
delay(5);
}
}
}
P1=0xfd;//第二行
delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delay(5);
temp=temp&0xf0;
if(temp!
=0xf0)
{
temp=P1;
switch(temp)
{
case0x7d:
key=11;break;
case0xbd:
key=6;break;
case0xdd:
key=5;break;
case0xed:
key=4;break;
}
while(P1!
=0xfd)
{
P1=0xfd;
delay(5);
}
}
}
P1=0xfb;//第三行
delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delay(5);
temp=temp&0xf0;
if(temp!
=0xf0)
{
temp=P1;
switch(temp)
{
case0x7b:
key=12;break;
case0xbb:
key=9;break;
case0xdb:
key=8;break;
case0xeb:
key=7;break;
}
while(P1!
=0xfb)
{
P1=0xfb;
delay(5);
}
}
}
P1=0xf7;//第四行
delay(5);
temp=P1;
temp=temp&0xf0;
if(temp!
=0xf0)
{
delay(5);
temp=temp&0xf0;
if(temp!
=0xf0)
{
temp=P1;
switch(temp)
{
case0x77:
key=15;break;
case0xb7:
key=14;break;
case0xd7:
key=0;break;
case0xe7:
key=13;break;
}
while(P1!
=0xf7)
{
P1=0xf7;
delay(5);
}
}
}
}
voidshow_time()//显示时间
{
write_com(0x82+0x40);
write_data(0x30+s1);
write_data(0x30+s2);
write_com(0x85+0x40);
write_data(0x30+f1);
write_data(0x30+f2);
write_com(0x88+0x40);
write_data(0x30+m1);
write_data(0x30+m2);
}
voidchoose1()//指定位置
{
sn1++;
switch(sn1)
{
case1:
write_com(0x84);break;//年个位
case2:
write_com(0x86);break;//月十位
case3:
write_com(0x87);break;//月个位
case4:
write_com(0x89);break;//日十位
case5:
write_com(0x8a);break;//日个位
case6:
write_com(0x8d);break;//星期
case7:
write_com(0x82+0x40);break;//时十位
case8:
write_com(0x83+0x40);break;//时个位
case9:
write_com(0x85+0x40);break;//分十位
case10:
write_com(0x86+0x