基于1602LCD数字时钟.docx
《基于1602LCD数字时钟.docx》由会员分享,可在线阅读,更多相关《基于1602LCD数字时钟.docx(31页珍藏版)》请在冰点文库上搜索。
基于1602LCD数字时钟
单片机课程设计报告
基于1602LCD数字时钟
专业班级07电子01班
时间15周~16周
指导教师
2010年6月16日
任务书
1设计要求
■大体范围:
能显示年月日、时秒分、礼拜
■精度误差小于5um
■LCD1602显示
2扩展功能
■实现整点提示(蜂鸣器响3s),流水灯每隔1s移动一次。
■实现断电时能保留月、日、礼拜、时、分、秒的数据即掉电爱惜。
基于1602数字时钟
电子071
摘要:
随着时期的进步和进展,单片机技术已经普及到咱们生活,工作,科研,各个领域,已经成为一种比较成熟的技术,本文将介绍一种基于单片机操纵LCD1602来显示时刻和日期,本产品属于多功能时钟,能够实现显示日期及礼拜,流水灯,蜂鸣器整点提示,断电时保留数据。
关键词:
单片机,时钟,LCD1602,STC89C52,AT24C02
1引言
随着人们生活水平的不断提高,单片机操纵无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,其中数字时钟确实是一个典型的例子,但人们对它的要求愈来愈高,要为现代人工作、科研、生活、提供更好的更方便的设施就需要从数单片机技术入手,一切向着数字化操纵,智能化操纵方向进展。
本设计所介绍的数字时钟与传统的时钟相较,除大体的显示年月日、时分秒还能实现断电保留数据,流水灯,蜂鸣器整点提示
2整体设计方案
数字时钟设计方案论证
方案一
由于本设计是数字时钟电路,能够利用数码管显示数据,可是进一步讨论能够发觉,咱们做的时钟要显示年月日、时分秒,和礼拜,若是用数码管显示的话,显然是不可取的。
方案二
从方案一发觉的问题咱们能够明白,本次设计的产品要求显示很多位数据,咱们能够采纳LCD1602,他能够显示32个字符,完全能解决方案一碰到的问题。
从以上两种方案,很容易看出,采纳方案二,电路比较简单,而且它不占I/O资源,软件设计也比较简单,故采纳了方案二。
方案二的整体设计框图
时钟电路设计整体设计方框图如图1所示,操纵器采纳单片机STC89C52,用LCD1602实现显示。
主控制器
1602LCD显示
AT24C02
单片机复位
时钟振荡
按键调整时间
图1 整体设计方框图
主操纵器
单片机STC89C52具有低电压供电和体积小等特点,四个端口只需要两个口就能够知足电路系统的设计需要,而且内部有8K的ROM。
显示电路
显示电路采纳LCD1602,从P0口输出数据给LCD1602。
温度传感器是美国ATMEL公司最新推出的芯片,它的存储大小为256*8,它能直接读出数据和写入数据,在一些应用系统设计中,有时需要对工作数据进行掉电爱惜,如采纳一般存储器,在掉电时需要备用电源供电,而且需要加掉电检测电路,而采纳
总线接口的串行
器件能够专门好的解决掉电数据保留问题,各引脚功能如下:
1——
2——
3——
4——GND
5——SDL串行数据输入/输出端
6——SCL串行时钟输入端
7——WP写爱惜输入端
8——VCC电源+端
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必需维持稳固,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才许诺转变。
图2
起始和终止信号:
SCL线为高电平期间,SDA线由高电平向低电平的转变表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的转变表示终止信号。
数据传送格式
(1)字节传送与应答
每一个字节必需保证是8位长度。
数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必需跟从一名应答位(即一帧共有9位)。
若是一段时刻内没有收到从机的应答信号,那么自动以为从机已正确接收到数据。
图3
AT24C02的芯片地址如以下图,1010为固定,A0,A1,A2正好与芯片的1,2,3引角对应,为当前电路中的地址选择线,三根线可选择8个芯片同时连接在电路中,当要与哪个芯片通信时传送相应的地址即可与该芯片成立连接,TX-1B实验板上三根地址线都为0。
最后一名R/W为告知从机下一字节数据是要读仍是写,0为写入,1为读出。
图4
AT24C02与单片机的接口电路
图5
系统整体硬件电路
图6
系统整体硬件PCB电路
图7
3系统软件算法分析
系统程序要紧包括主程序,显示函数、按时中断函数、按键调整函数、对AT24C02读操作函数、对AT24C02写操作函数、蜂鸣器、流水灯函数等。
程序流程图
主程序主若是挪用显示函数、按键调整函数。
程序流程图如图8,程序见附件。
对定时器、AT24C02进行初始化
读出断电时的数据并显示
调用按键调整函数调整初值
计时、显示
1s
整点
流水灯
蜂鸣器
定时器
等待
图8
4总结与体会
通过快要2周的单片机课程设计,终于完成了我的数字时钟的设计,在做设计的时候感觉最大的压力是程序的问题,有时候一个小小的粗心就有可能致使你一天乃至是二天白做。
因此咱们在做设计的时候必然要谨慎,只有如此才能保证经最小可能犯错。
在本次设计的进程中,我还话了我设计的电路的PCB板,而且自己买做PCB的原材料,利用感光技术做板子,使得我的电路实物不要进行繁琐的连线和焊接,跟其他没做板子的同窗比我还要快一些,真的是磨刀不误砍柴工呀。
而且在这一进程中我大体熟悉了PROTEL软件的利用方式。
从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把咱们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在常常的写与读的进程中才能提高,这确实是我在这次课程设计中的最大收成。
参考文献
[1] 李朝青.单片机原理及接口技术(简明修订版).杭州:
北京航空航天大学出版社,1998
[2] 李广弟.单片机基础[M].北京:
北京航空航天大学出版社,1994
[3] 阎石.数字电子技术基础(第三版).北京:
高等教育出版社,1989
[4] 廖常初.现场总线概述[J].电工技术,1999.
附实物图:
单片机程序(keil):
#include<>
#include<>
#defineucharunsignedchar
#defineuintunsignedint
ucharcodetable2[]="MONTUEWEDTHUFIRSATSUN";
sbitlcden=P1^6;//液晶使能端
sbitlcdrs=P1^5;//液晶数据命令选择端
//sbitdula=P2^6;//申明U1锁存器的锁存端
//sbitwela=P2^7;//申明U2锁存器的锁存端
sbitbeep=P1^7;
sbits1=P1^2;
sbits2=P1^3;
sbits3=P1^4;
bitwrite=0;//写24C02的标志;
sbitsda=P1^1;
sbitscl=P1^0;
ucharcount,shi=0,fen=0,miao=0,yue=6,ri=12,xinq=15,te=0xfe;
uintnian=2020;
voiddelay0()
{;;}
voidstart()//开始信号
{
sda=1;
delay0();
scl=1;
delay0();
sda=0;
delay0();
}
voidstop()//停止
{
sda=0;
delay0();
scl=1;
delay0();
sda=1;
delay0();
}
voidrespons()//应答
{
uchari;
scl=1;
delay0();
while((sda==1)&&(i<250))i++;
scl=0;
delay0();
}
voidinit_24c02()//IIC初始化函数
{
sda=1;
delay0();
scl=1;
delay0();
}
voidwrite_byte(uchardate)//写一个字节函数
{
uchari,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay0();
sda=CY;
delay0();
scl=1;
delay0();
}
scl=0;
delay0();
sda=1;
delay0();
}
ucharread_byte()//读一个字节函数
{
uchari,k;
scl=0;
delay0();
sda=1;
delay0();
for(i=0;i<8;i++)
{
scl=1;
delay0();
k=(k<<1)|sda;
scl=0;
delay0();
}
returnk;
}
voidwrite_add(ucharaddress,uchardate)//指定地址写一个字节
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
charread_add(ucharaddress)//指定地址读一个字节
{
uchardate;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
returndate;
}
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharcom)
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_data(uchardate)
{
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_sfm(ucharadd,uchardate)//写时分秒函数
{
ucharshi,ge;
shi=date/10;//分解一个2位数的十位和个位
ge=date%10;
write_com(0x80+0x40+add);//设置显示位置
write_data(0x30+shi);//送去液晶显示十位
write_data(0x30+ge);//送去液晶显示个位
write_com(0x0c);//设置开显示,不显示光标
}
voidwrite_nian(ucharadd,uintnian)
{
uintqian,bai,shi,ge;
qian=nian/1000;
bai=(nian-qian*1000)/100;
shi=(nian-qian*1000-bai*100)/10;//分解一个2位数的十位和个位
ge=(nian-qian*1000-bai*100-shi*10);
write_com(0x80+add);//设置显示位置
write_data(0x30+qian);
write_data(0x30+bai);
write_data(0x30+shi);//送去液晶显示十位
write_data(0x30+ge);//送去液晶显示个位
write_com(0x0c);//设置开显示,不显示光标
}
voidwrite_yr(ucharadd,uchardate)//写时分秒函数
{
ucharshi,ge;
shi=date/10;//分解一个2位数的十位和个位
ge=date%10;
write_com(0x80+add);//设置显示位置
write_data(0x30+shi);//送去液晶显示十位
write_data(0x30+ge);//送去液晶显示个位
write_com(0x0c);//设置开显示,不显示光标
}
voidinit()
{
//dula=0;
//wela=0;
lcden=0;
write_com(0x38);//设置16X2显示,5X7点阵,8位数据接口
write_com(0x0c);//设置开显示,不显示光标
write_com(0x06);//写一个字符后地址指针加1
write_com(0x01);//显示清零,数据指针清零
}
voiddi()//蜂鸣器发声函数
{
beep=0;
delay(100);
beep=1;
}
voidt0init()
{
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
//TR0=1;
}
voiddistime()
{
ucharr,ri_,a=3;
if(count==20)//20次50毫秒为1秒
{
count=0;
miao++;
if(miao==60)//秒加到60那么进位分钟
{
miao=0;//同时秒数清零
fen++;
if(fen==60)//分钟加到60那么进位小时
{
fen=0;//同时分钟数清零
shi++;
if(shi==24)//小时加到24那么小时清零
{
r=((nian%400)==0||((nian%100!
=0)&&(nian%4==0)));
if((r==1)&&(yue==2))ri_=29;
if((r==1)&&((yue!
=2)&&(yue%2==0)))ri_=30;
if((r==1)&&(yue%2!
=0))ri_=31;
if((r==0)&&(yue==2))ri_=28;
if((r==0)&&((yue!
=2)&&(yue%2==0)))ri_=30;
if((r==0)&&(yue%2!
=0))ri_=31;
if((yue==8)||(yue==10)||(yue==12))ri_=31;
if((yue==9)||(yue==11))ri_=30;
shi=0;
ri++;
if(ri==ri_+1)
{
ri=1;
yue++;
if(yue==13)
{
yue=1;
nian++;
write_nian(0,nian);
write_add(7,nian);
}
write_yr(5,yue);
write_add(6,yue);
}
write_yr(8,ri);
write_add(5,ri);
if(xinq==21)xinq=0;
write_com(0x80+0x0b);
while(a)
{
write_data(table2[xinq]);
xinq++;
a--;
}
write_add(4,xinq);
}
write_sfm(0,shi);//小时假设转变那么从头写入
write_add(3,shi);
beep=0;
}
write_sfm(3,fen);//分钟假设转变那么从头写入
write_add(2,fen);
}
write_sfm(6,miao);//秒假设转变那么从头写入
write_add(1,miao);
if(miao==3)beep=1;
P2=te;
te=_crol_(te,1);
}
}
voidlogin()
{
uchara=3;
write_nian(0,nian);
write_yr(5,yue);
write_yr(8,ri);
if(xinq==21)xinq=0;
write_com(0x80+0x0b);
while(a)
{
write_data(table2[xinq]);
xinq++;
a--;
}
write_sfm(0,shi);
write_com(0x80+0x42);
write_data(':
');
write_sfm(3,fen);
write_com(0x80+0x45);
write_data(':
');
write_sfm(6,miao);
}
ucharmodfm(ucharx,uchary)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
di();
y++;
if(y==60)
{
y=0;
}
write_sfm(x,y);
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
di();
y--;
if(y==-1)
{
y=59;
}
write_sfm(x,y);
}
}
returny;
}
ucharmods(ucharx,uchary)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
di();
y++;
if(y==24)
{
y=0;
}
write_sfm(x,y);
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
di();
y--;
if(y==-1)
{
y=23;
}
write_sfm(x,y);
}
}
returny;
}
uintmodn(ucharx,uinty)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
di();
y++;
if(y==10000)
{
y=2007;
}
write_nian(x,y);
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
di();
y--;
if(y==2006)
{
y=9999;
}
write_nian(x,y);
}
}
returny;
}
ucharmodr(ucharx,uchary)
{
uchara=3;
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
di();
y++;
if(y==32)
{
y=1;
}
write_yr(x,y);
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
di();
y--;
if(y==0)
{
y=31;
}
write_yr(x,y);
}
}
returny;
}
ucharmodxinq(uchary)
{
uchara=3;
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
di();
if(y==21)
{
y=0;
}
write_com(0x80+0x0b);
while(a)
{
write_data(table2[y]);
y++;
a--;
}
write_com(0x0c);
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
di();
y=y-6;
if(y==-3)
{
y=18;
}
write_com(0x80+0x0b);
while(a)
{
write_data(table2[y]);
y++;
a--;
}
write_com(0x0c);
}
}
returny;
}
ucharmody(ucharx,uchary)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
di();
y++;
if(y==13)
{
y=1;
}
write_yr(x,y);
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
di();
y--;
if(y==0)
{
y=31;
}
write_yr(x,y);
}
}
returny;
}
voidkeyscan()
{
uchars1num,tem=1;
while(tem==1)
{
if(s1==0)
{
delay(5);
if(s1==0)
{
while(!
s1);
di();
s1num++;
switch(s1num)
{
case1:
write_com(0x80);write_com(0x0f);break;
case2:
write_com(0x80+0x05);write_com(0x0f);break;
case3:
write_com(0x80+0x08);write_com(0x0f);break;
case4:
write_com(0x80+0x0b);write_com(0x0f);break;
case5:
write_com(0x80+0x40);write_com(0x0f);break;
case6:
write_com(0x80+0x43);write_com(0x0f);break;
case7:
write_com(0x80+0x46);write_com(0x0f);break;
case8:
TR0=1;tem=0;break;
}
}
}
if(s1num!
=0)
{
switch(s1num)
{