可调电子时钟设计.docx

上传人:b****5 文档编号:3562277 上传时间:2022-11-23 格式:DOCX 页数:22 大小:239.47KB
下载 相关 举报
可调电子时钟设计.docx_第1页
第1页 / 共22页
可调电子时钟设计.docx_第2页
第2页 / 共22页
可调电子时钟设计.docx_第3页
第3页 / 共22页
可调电子时钟设计.docx_第4页
第4页 / 共22页
可调电子时钟设计.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

可调电子时钟设计.docx

《可调电子时钟设计.docx》由会员分享,可在线阅读,更多相关《可调电子时钟设计.docx(22页珍藏版)》请在冰豆网上搜索。

可调电子时钟设计.docx

可调电子时钟设计

 

 

单片机综合实验课程报告

题目可调电子时钟设计

学生姓名

学号

院系

专业

指导教师

 

二O一二年五月十五日

可调电子时钟设计

 

南京信息工程大学信息与控制学院,江苏南京210044

摘要:

用AT89C51作为最小系统设计可调电子时钟,用液晶显示屏LCD102输出显示,用时钟芯片DS1302管理时间。

可以显示年、月、日、星期、时、分、秒,并且均可通过按键调整。

当按第一个键时开始调整时间,第二个键是加键,第三个键是减键。

单片机具有集成度高、功能强、通用好、特别是它能耗低、价格便宜、可靠性高、抗干扰能力强和使用方便等独特的优点,所以单片机现在广泛的应用到家用电器、机电产品、儿童玩具、机器人、办公自动化产品等领域。

数字电子时钟电路设计系统,以AT89C51单片机为控制核心,由按键、液晶显示屏和LED灯显示等功能模块组成。

基于题目基本要求,本系统对时间显示和定时报警进行了重点设计。

本系统大部分功能由软件来实现,吸收了硬件软件化的思想,大部分功能通过软件来实现,使电路简单明了,系统稳定性大大提高本系统成功的实现了要求的基本功能。

关键词:

AT89C51;LCD1602;DS1302

 

DesignofAdjustableElectronicClock

 

NUIST,Nanjing210044,China

Abstract:

This paper introduced the design of the adjustable digital clock based on AT89C51, the specific process of how the system hardware and software achieved were detailed description through the design of adjustable digital clock. The modular design and production, which consisted of MCU module, clock module and the associated control module, weremainlyrecounted.Aswellashardwaredesignandsoftwaredesignusethesamemethod,consistssuspensionmodule,timeadjustablemodule,andthatusetheClanguagetoachievebecauseofitssampleandstrongnegotiability.Inthisdesign,thefunctionsoftimerunandchange,functionsoftheyear,monthanddaydisplayhavebeenachieved.

Keywords:

AT89C51;LCD1602;DS1302

 

一、数码管显示预期功能

1、以格式“小时-分钟-秒”显示时间。

2、每过一秒显示内容更新。

3、可以通过按键来调整时间,包括时、分、秒的增加或减小。

4、整点时,蜂鸣器或扬声器报时。

5、用时钟芯片DS1302来管理时间。

6、显示年月日,且能调整。

7、显示星期。

二、设计方案

1、51单片机最小系统设计

单片机最小系统如下图所示:

以ST89C51单片机为核心,选用12MHZ的晶振,由于晶振的频率越高,单片机的运行速度就越快,但考虑到单片机的运行速度快会导致对存储器的要求就会变高,因此12MHZ晶振为最佳选择。

外接电容的值虽然没有严格的要求,但是外接电容的大小会影响振荡器的频率高低、振荡器的稳定性和起振的快速性,因此我们选用30pF的电容作为起振电容。

复位电路为按键高电平复位,当按键按下,RES端为高电平,当高电平持续4us的时间就可以使单片机复位。

2、时间显示设计

采用液晶显示屏LCD1602显示时间:

Vss,Vdd(1,2管脚)——电源端。

液晶屏的+5V工作电压与单片机相同。

Vee(3管脚)——液晶屏驱动电源。

该管脚的电平决定了液晶屏的对比度,通常可用一个分压器控制Vee管脚的电压从而调整对比度。

RS(4管脚)——命令/数据选择线。

RS状态决定了数据总线DB0~DB7上的信号是命令还是显示数据。

RS=0时,DB0~DB7的信号视为命令数据。

RS=1时,DB0~DB7的信号则作为液晶屏的显示数据。

R/W(5管脚)——读/写控制线。

控制是从液晶屏读数据还是向液晶屏写数据。

R/W=0时,写数据。

R/W=1时,读数据。

E(6管脚)——使能端。

该管脚控制液晶屏从数据总线DB0~DB7上将数据读入液晶屏。

当该管脚上的电平由1向0变化时,数据总线DB0~DB7的数据被读入液晶屏。

DB0~DB7(7~14管脚)——数据总线。

这8位数据总线是数据交换的通道,单片机向液晶屏送入的命令或数据都通过这8位数据总线进行。

单片机需要先向液晶屏输出一些显示设置命令,然后再输出显示数据。

当单片机向液晶屏输出显示设置命令时,RS管脚应该清0。

当设置完成后,需要使RS管脚置1以向液晶屏输入显示数据。

同时,R/W管脚也接低电平,液晶屏接收数据从DB0~DB7写入。

当RS管脚和R/W管脚设置妥当后,执行对E管脚清0,就会在E管脚上形成一个由高向低的跳变,这个跳变就使得命令或显示数据从数据总线DB0~DB7进入液晶屏。

3、时间管理设计

采用时钟芯片DS1302管理时间:

DS1302是DALLAS公司推出的涓流充电时钟芯片内含有一个实时时钟/日历和31字节静态RAM可通过简单的串行接口与单片机进行通信可提供:

秒分时日日期月年的信息;每月的天数和闰年的天数可自动调整;可通过AM/PM指示决定采用24或12小时格式。

三、硬件电路设计

整体电路图:

连线如下:

液晶显示器LCD1602的D0~D7分别与P2口相连,RS、RW、E分别与P1.0、P1.1、P1.2口相连,3个时间调整按键分别与P3.0、P3.1和P3.2相连,整点报时的二极管与P3.7口相连,时钟芯片的/RST、SCLK、I/O分别与P1.3、P1.4、P1.5相连。

四、软件设计

 

1、主程序流程图:

 

 

 

2、中断服务程序流程图

 

 

五、仿真结果

总体仿真图:

整点报时:

仿真结果如图所示,运行后,液晶显示器显示年月日、星期和时分秒,所有显示时间均可通过按键修改,并具有整点报时功能。

六、小结

课程设计是培养学生综合运用所学知识,发现实际问题、提出实际问题、分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际学习能力、动手能力的具体训练和考察过程。

 

在此次数字钟设计过程中, 在学习新知识的同时,把在课程中学到的理论知识运用到实际作品设计、操作中,更进一步地熟悉了单片机芯片的结构及掌握了其工作原理和具体的使用方法与相关元器件的使用方法,了解了电路的开发和制作及课程设计报告的编写。

加深了对相关理论知识及专业知识的掌握度,增强自身的动手能力,锻炼及提高了理解问题、分析问题、解决问题的能力,更深刻的体会到了理论联系实际的重要性。

 

通过此次单片机课程设计不仅仅将我们一学期在单片机课程上的所学很好的应用到了实际设计中,更是将理论知识应用到了实践中,这才是真正的学习,不仅仅是读万卷书,更要行万里路,讲知识与实践有机的结合。

也十分感谢老师为我们提供了这次单片机课程设计的机会,我们也通过此次课程设计,更清晰更实际的接触到了单片机。

参考文献

[1] 李广弟等编, 单片机基础,北京航空航天大学出版社              

[2] 吴金戌等编, 8051 单片机实践与应用,清华大学出版社           

[3] 王洪庆编 ,微型计算机控制技术,机械工业出版社               

[4] 付家才编 ,单片机控制工程实践技术,化学工业出版社           

[5] 鲍宏亚编,MCS51系列单片机应用系统设计及实用技术,中国宇航出版社                        

[6] 杨文龙,单片机原理及应用[M],西安电子科技大学出版社      

[7] 赵文博,刘文涛.单片机语言C51程序设计[M],人民邮电出版社        

 

附录

源程序:

(1)主程序:

#include

#include"LCD1602.H"

#include"DS1302.h"

#include"intrins.h"

#include"keyscan.h"

sbitbeep=P3^7;

ucharshan=0;//设置时间时闪烁,用于计时

ucharshan_time=15;//闪烁时间

ucharshan_max=35;//闪烁周期,亮-灭

voiddelay(uintz)//延时函数

{

uintx,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

voiddi(uintx)//蜂鸣器发声函数

{

beep=0;

delay(x);

beep=1;

delay(x);

}

/**********************显示处理程序**************************************/

voidshanshuo(ucharaddr,ucharcount_1,uchartime_num)//闪烁显示子程序

{

w_com(0x80+addr);//闪烁显示,格式:

写入1602地址,设置的位号,显示的位号

if(count==count_1&(shan

{

w_data('');

w_data('');

}

else//显示时钟

{

w_time(time[time_num]/10);

w_time(time[time_num]%10);

}

}

voiddeal()//对时间进行显示处理

{

ucharaddr=0x44;

shanshuo(addr,3,2);//时

addr+=3;

shanshuo(addr,2,1);//分

addr+=3;

shanshuo(addr,1,0);//秒

addr=0x02;

shanshuo(addr,7,6);//年

addr+=3;

shanshuo(addr,6,4);//月

addr+=3;

shanshuo(addr,5,3);//日

addr+=3;

if(count==4&(shan

{

w_com(0x80+addr);

w_string(0xff,"");

}

elsew_string(11,week[time[5]]);

}

/*********************初始化程序***************************************/

voidinit_lcd()//1602初始化

{

w_com(0x38);

w_com(0x0c);

w_string(0x00,"20--");//年月日格式

w_string(0x44,"--:

--:

--");//时间格式

}

voidinit1302()//1302初始化

{

if(read1302(0x81)&0x80)settime(0x80,0);

}

voidinit_timer0()//最大定时时间65.536ms

{

TH0=0;

TL0=0;

TR0=1;

ET0=1;

EA=1;

}

/*********************主程序***************************************/

voidmain()

{

uchari=0,addr=0x82;

init_lcd();//LCD1602初始化

init1302();//DS1302初始化

init_timer0();

while

(1)

{

keyscan();

if(num1>num2)//num1>num2,说明设置时间完成,将新时间写入DS1302

{

t[0]=set_time[0];//读取新时间,将其转换为DS1302内部时间序列

t[1]=set_time[1];

t[2]=set_time[2];

t[5]=set_time[3];

t[3]=set_time[4];

t[4]=set_time[5];

t[6]=set_time[6];

addr=0x82;//DS1302分地址,其他时间依次加2

for(i=1;i<7;i++)//写入时间

{

settime(addr,t[i]);

addr+=2;

}

num2++;//确保不在设置情况下不执行此写时间程序

if(num1>=100)num1=num2=0;//防止溢出

sure=1;//时间设置完成,sure置位,从DS1302读取时间

}

//if(time[1]==0)

if((time[1]==0)&&(time[0]<=5))//整点报时

{

di

(1);//调用蜂鸣器发声函数

}

}

}

/***********************中断服务程序*************************************/

voidtimer0()interrupt1//定时器0处理程序

{

TH0=0;

TL0=0;

shan++;

if(shan>=shan_max)shan=0;

if(sure)//sure置位时,set复位,正常走时

{

gettime();

}

deal();//如果设置键按下,执行闪烁程序

}

(2)LCD1602.h:

sbitRS=P1^0;

sbitRW=P1^1;

sbitE=P1^2;

#defineuintunsignedint

#defineucharunsignedchar

/*******************LCD1602********************************/

voiddelay_xus(uintx)//读写延时,12+(x-1)*5us

{

while(x--);

}

voidw_com(ucharcom)//写命令,RS=0

{

RW=0;

RS=0;

E=1;

P2=com;

E=0;

RW=1;

delay_xus

(2);//12+1*5=17us

}

voidw_data(uchardat)//写数据,RS=1

{

RW=0;

RS=1;

E=1;

P2=dat;

E=0;

RW=1;

delay_xus

(2);

}

voidw_onebyte(ucharaddr,uchardat)//向某一地址写数据

{

w_com(0x80+addr);

w_data(dat);

}

voidw_time(uchardat)//写1302的时间,将时间转换为十六进制

{

w_data(dat+'0');

}

voidw_string(ucharaddr,ucharcode*p)//向某一地址写字符串

{

uchari=0;

if(addr<=0x67)w_com(0x80+addr);//若addr>0x67则超出1602地址范围,则不进行写地址

while(*(p+i)!

='\0')

{

w_data(*(p+i));

i++;

}

}

(3)DS1302.h:

sbitRST=P1^3;

sbitSCLK=P1^4;

sbitIO=P1^5;

uchartime[7]=0;//从1302获取的时间暂存单元,格式:

sec,min,h,day,month,week,year

ucharcode*week[9]={"***","SUN","MON","TUE","WEN","THU","FRI","SAT"};//周日-周六

voidw_byte(uchardat)//向DS1302写一字节

{

uchari=8;

while(i--)

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

{

IO=dat&0x01;

SCLK=1;

SCLK=0;

dat>>=1;

}

}

ucharr_byte()//读一字节

{

uchari=8,dat=0;

while(i--)

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

{

dat>>=1;

if(IO)dat|=0x80;//Therewasamistake!

SCLK=1;

SCLK=0;

}

returndat;

}

voidwrite1302(ucharaddr,uchardat)//向某一地址写数据

{

RST=0;

SCLK=0;

RST=1;

w_byte(addr);

w_byte(dat);

SCLK=1;

RST=0;

}

ucharread1302(ucharaddr)//从某一地址读数据

{

uchardat;

RST=0;

SCLK=0;

RST=1;

w_byte(addr|0x01);

dat=r_byte();

SCLK=1;

RST=0;

dat=dat/16*10+(dat&0X0F);

returndat;

}

voidsettime(ucharaddr,uchardat)//设置时间,注意格式转换

{

write1302(0x8e,0x00);//禁止写保护(即允许向1302写数据),WP=0

write1302(addr,((dat/10)*16)|(dat%10));//格式转换

}

voidgettime()//从1302获取时间

{

uchari=0;

ucharaddr=0x81;//秒的读取地址,其他地址依次加2

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

{

time[i]=read1302(addr);

addr+=2;

}

}

(4)keyscan.h:

/***********************按键扫描程序*************************************/

bitset=0,add=0,sub=0,sure=1;//标志位:

设置,加,减及确定

ucharnum1=0,num2=0;

charset_time[7];//sec,min,h,week,day,month,year

ucharcode*t[7];//用于将设置的时间转化为按DS1302时间顺序排列

sbitset_key=P3^0;//设置键

sbitadd_key=P3^1;//加一键

sbitsub_key=P3^2;//减一键

ucharidatacount=0;//count从1到7为设置时钟位(s,min,h……六位)

voiddelay_ms(uintx)//消抖延时

{

uinty=110;

for(;x>0;x--)

for(y=110;y>0;y--);

}

voidkeyscan()

{

if((P3&0x07)!

=0x07)

{

delay_ms(90);//这里为了set键考虑,设置小点

if((P3&0x07)!

=0x07)//确认有键按下

{

if(set_key==0)//设置键被按下

{

count++;//count从1到7为设置时钟位(s,min,h……六位)

set=1;//set为设置标志位,sure为确定标志位

sure=0;//set置位时不读取DS1302内部时间,sure置位时开始读取DS1302内部时间

if(count>=8)

{

count=0;

set=0;

num1++;

}

}

if(set&(count==1))//在进入设置时间时,读取当前时间,在此时间基础上进行修改

{

set_time[0]=time[0];

set_time[1]=time[1];

set_time[2]=time[2];

set_time[3]=time[5];

set_time[4]=time[3];

set_time[5]=time[4];

set_time[6]=time[6];

}

if((!

add_key)&(!

sure)&sub_key)//'+'键,时间加1

{

add=1;

delay_ms(10);//补偿消抖时间,否则按一下会增加很多

switch(count)

{

case1:

set_time[0]++;

if(set_time[0]>=60)set_time[0]=0;break;//sec

case2:

set_time[1]++;

if(set_time[1]>=60)set_time[1]=0;break;//min

case3:

set_time[2]++;

if(set_time[2]>=24)set_time[2]=0;break;//h

case4:

set_time[3]++;

if(set_time[3]>=8)set_time[3]=1;break;//week

case5:

set_time[4]++;

if(set_time[4]>=32)set_time[4]=1;break;//day

case6:

set_time[5]++;

if(set_time[5]>=

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1