单片机电子时钟设计报告.docx

上传人:b****3 文档编号:4851164 上传时间:2022-12-10 格式:DOCX 页数:28 大小:210.30KB
下载 相关 举报
单片机电子时钟设计报告.docx_第1页
第1页 / 共28页
单片机电子时钟设计报告.docx_第2页
第2页 / 共28页
单片机电子时钟设计报告.docx_第3页
第3页 / 共28页
单片机电子时钟设计报告.docx_第4页
第4页 / 共28页
单片机电子时钟设计报告.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

单片机电子时钟设计报告.docx

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

单片机电子时钟设计报告.docx

单片机电子时钟设计报告

电子时钟实验报告

全部代码在文档末尾:

51单片机,LCD1602液晶显示屏平台下编程实现,可直接编译运行目录:

实验目的

,实验要求三,实验基本原理四,实验设计分析五,实验要求实现

A.电路设计.

1.整体设计

2.分块设计

输入部分输出部分晶振与复位电路

B.程序设计.

程序主要模块

五.实验总结及感想

实验目的

20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。

现代生活的人们越来越重视起了时间观念,可以说是时间和金钱划上了等号。

麻烦,所以电子钟是以其小巧,价格低廉,走时精度高,使用方便,功能多,便于集成化而受广大消费的喜爱,得到了广泛的使用。

1.学习8051定时器时间计时处理、按键扫描及LCD液晶显示的设计方法。

2.设计任务及要求利用实验平台上LCD1602液晶显示屏,设计带有闹铃功能的数字时钟二,实验要求

A.基本要求:

1.在LCD1602液晶显示屏上显示当前日期,时间。

2.利用按键可对时间及闹玲进行设置,并可显示设置闹玲的时间。

闹玲时间到蜂鸣

器发出声响,一分钟后闹铃停止。

B.扩展部分:

1.日历功能(能对年,月,日,星期进行显示,分辨平年,闰年以及各月天数,并调整)实现年月日时分秒的调整,星期准确的随着日期改变而改变进行显示。

2.定时功能(设定一段时间长度,定时到后,闹铃提示)

C.可扩展部分:

1.闹铃重响功能(闹铃被停止后,以停止时刻开始,一段时间后闹铃重响,且重响时间的间隔可调)

2.可进行备忘录提示,按照年月日,可在设定的某年某月进行闹铃提示。

三,实验基本原理

利用单片机定时器完成计时功能,定时器0计时中断程序每隔中断一次并当作一个计数,设定定时1秒的中断计数初值为20,每中断一次中断计数初值加1,当

减到20时,则表示1s到了,秒变量加1,同理再判断是否1min钟到了,再判断是否1h到了,是否一天到了,是否一个月到了,是否一年到了。

将时间在LCD液晶屏上显示,降低了程序的编写难度。

LCD的固定显示特性是

我们省去了数码管的动态扫描显示。

四,实验设计分析

针对要实现的功能,采用AT89S5单片机进行设计,AT89S52单片机是一款低功

MCS-51指令

耗,高性能CMOS位单片机,片内含4KB在线可编程(ISP)的可反复擦写1000次的Flash只读程序存储器,器件采用高密度、非易失性存储技术制造,兼容标准系统及80C51引脚结构。

这样,既能做到经济合理又能实现预期的功能。

在程序方面,采用分块设计的方法,这样既减小了编程难度、使程序易于理解,又能便于添加各项功能。

程序可分为闹钟的声音程序、时间显示程序、日期显示程序,秒表显示程序,时间调整程序、闹钟调整程序、定时调整程序,延时程序等。

运用这种方法,关键在于各模块的兼容和配合,若各模块不匹配会出现意想不到的错误。

首先,在编程之前必须了解硬件结构尤其是各引脚的用法,以及内部寄存器、存储单元的用法,否则,编程无从下手,电路也无法设计。

这是前期准备工作。

第二部分是硬件部分:

依据想要的功能分块设计设计,比如输入需要开关电路,输出

需要显示驱动电路和数码管电路等。

第三部分是软件部分:

先学习理解C语言的编程方法再根据设计的硬件电路进行分块的编程调试,最终完成程序设计。

第四部分是软件画图部分:

设计好电路后进行画图,包括电路图和仿真图的绘制。

第五部分是软件仿真部分:

软硬件设计好后将软件载入芯片中进行仿真,仿真无法完成时检查软件程序和硬件电路并进行修改直到仿真成功。

第六部分是硬件实现部分:

连接电路并导入程序检查电路,若与设计的完全一样一般能实现想要的功能。

最后进行功能扩展,在已经正确的设计基础上,添加额外的功能!

五,实验要求实现

A.电路设计

1.整体设计

此次设计主要是应用单片机来设计电子时钟,硬件部分主要分以下电路模块:

显示电路用lcd1602显示,年份,月份,星期,小时、分钟和秒(日),使电路更加简单。

单片机采用AT89S5係列,这种单片机应用简单,适合电子钟设计。

电路的总体设计框架如下:

 

分样例:

P0口。

对于P0口,由

在本实验中主要用用P3口输入按键信号,还用到了特殊的于其存在高阻状态,为了实现幵关功能,给其添加上拉电阻,具体如下图所示:

输出部分本电路的输出信号LCD勺写入命令和写入数据,闹铃脉冲信号。

闹铃由端输出,模块如下:

日期时间由LCD1602俞出,模块如下:

晶振与复位电路

本实验单片机时钟用内部时钟,模块如下:

复位电路为手动复位构成,模块如下:

B.程序设计

程序总体设计本实验用汇编程序完成.

程序总的流程图如下:

程序主要模块中断服务程序:

/******************

一秒定时中断函数*****************/

voidtimer0()interrupt1using1

ET0=0;

验总结及感想

分耕耘,一分收获。

只有亲自用实践来验证这句话,在能得其要领。

经过这

次单片机课程设计,我从一个单片机实践的门外汉,已经越升为略知一二的新手。

虽然还有很多有关单片机的应用有待学习,但万变不离其宗,只要深入了解单片的原理,全部知识点,各个细节,一切设计皆有可能。

在实验的开始几天,基本上没有收获,不知何从下手,不知所措。

为了看得更

远,不妨站在前人的肩膀上,我在整体思路模糊的情况下,在网上大量招资粮,各种与电子时钟相关的文章,我阅读了不少。

随着涉猎的点滴积累,我对电子时钟的设计方案已经慢慢酝酿而成。

有了方向和不少知识储备后,在接下来的几天,几乎每天都有突破,虽然有时只是一句程序的修改或诞生,但那种收获的感觉很暖人心。

实验中遇到了不少问题,接下来总结一下,共同探讨。

1,PO口幵关问题。

PO口比较特殊,它存在高阻态,要使其输入不是高电平就

是低电平,就要接上拉电阻,给其高电平输入。

的过程就是一个解决问题的过程,每天都解决一些问题,我的实验也就解决了,当然结果不重要,功利化的追求结果,会使人浮躁,还是享受那份疑难迎刃而解的快感吧!

全部完整代码:

此代码未经本人优化,可以根据自己的需求优化代码。

盗版不究,可直接引用。

/****************************************************************/

基于STC89S52单片机以及液晶1602显示的万年历项目

/***************************************************************/

#include<>

#include<>#defineucharunsignedchar#defineuintunsignedint

/***************

液晶1602相关参数***************/

#definedata_portP0

//液晶屏指令、数据通信接口

指令寄存器,rs=1时选择数据寄存器)

入,rw=1时选择读出)

 

sbiten=P1八2;

//

液晶屏使能接口(en=0时通信接口中

断,en=1时通信接口接通)

液晶屏第一行要显示的字符串

液晶屏第二行要显示的字符串

ucharcodeline1_str[]={"Welcome!

"};//ucharcodeline2_str[]={"madeby:

MCU"};//

 

/***************

按键设置的相关参数************/

 

//蜂鸣器

sbittimer二卩1八5;

sbitsound二卩3八4;

//进入闹铃设置状态键

 

ucharsflag=0,ssflag=0;

//闹铃设置标志位;闹铃工作标

志位

sbitset_key二卩3八7;

//

进入设置

sbitup_key=卩3八6;

//

加号键

sbitcancle_key=P3八5;

//

完成设置键

 

 

ucharset=0;

//是否进行了设置

ucharflag=0;

//设置选择标志

 

ucharyear=0x00;

//"年"寄存器

ucharmonth=0x01;

//"月"寄存器

ucharday=0x01;

//"日"寄存器

 

 

ucharweek=0x06;

//"星期"寄存器

 

ucharhour;

//"时"寄存器

ucharminite;

//"分"寄存器

ucharsecond;

//"秒"寄存器

ucharjiamiao=0;

//

加秒参数

ucharfen1,fen2;

//

数据交换)分定时寄存器

ucharshi1,shi2;

//

数据交换)时定时寄存器

 

依次存储:

年,月,

uchardis_val[7]={0x00,0x01,0x01,0x06,0x00,0x00,0x00};//

日,星期,时,分,秒

 

/******************

子函数部分

*****************/

voidlcd_int();

//

初始化1602液晶

voidwelcome();

//

欢迎界面

 

 

//向液晶屏输入命令

voidin_command(ucharcom);

 

voidin_data(uchardat);

//

向液晶屏输入数据

voiddelay(uintms);

//

延时函数

voidkey();

//

按键设置函数

ucharcalculate_week();

//星期计算函数

voidweek_disp(ucharx);

//LCD1602显示星期值子函数声明

 

 

voidlcd_disp_string(ucharstr[]);

//液晶屏显示一串字符子函数声明

 

voidbrush_lcd();

//

刷新液晶屏显示内容子函数声明

voidrun();

//

万年历正常运行函数

 

 

/**********************************************/

voidmain()

TMOD=0x01;

//OOOO0001使用定时器TO的模式1(16位模式)

THO=(65536-5OOOO)/256;//设定每次中断间隔5Oms

TLO=(65536-5OOOO)%256;

jiamiao=1;

lcd_int();

welcome();

delay(1OOO);

while

(1)

key();

if(jiamiao==2O)

//刷新"秒"

second++;

dis_val[6]=((second/10)<<4)|(second%10);

jiamiao=0;

run();

if(flag==0)

 

if(dis_val[0]==0x00

&&

dis_val[1]==0x01

&&

dis_val[2]==0x01)//2000年1月1日为星期六

{dis_val[3]=0x06;}

brush_lcd();

//刷新液晶屏显示内容

if(hour==shi2&&minite==fen2&&ssflag==1)

timer=0;

else

timer=1;

/********延时子函数************/

voiddelay(uintms)

uchari;

while(ms--)

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

 

voidlcd_int()

delay(30);//延时15MS等待LCD初始化

in_command(0x01);

//清显示屏

in_command(0x38);

//8位通信,2行显示,5*7点阵

in_command(0x0c);

//开显示,关光标,关闪烁

in_command(0x06);

//字符不动,光标右移动,地址加一

/**********液晶屏显示一串字符**********/voidlcd_disp_string(ucharstr[])

uchari=0;

while(str[i]!

='\0')

in_data(str[i]);

//显示数据(字符)

i++;

/***************

欢迎界面函数***************/

voidwelcome()

uchari;

in_command(0x80);

//

设定第一行字符串起始显示位置

while(line1_str[i]!

='\0')

delay(100);

in_data(line1_str[i]);

//

显示数据(字符)

i=0;

i++;

in_command(0xc0);

//

设定第二行字符串起始显示位置

 

while(line2_str[i]!

='\0')

delay(100);

i++;

/********向液晶屏输入命令子函数************/voidin_command(ucharcom)

delay

(2);

en=0;//关闭通信,为设置参数做准备

rs=0;//选择指令寄存器

rw=0;//写入液晶

_nop_();

data_port=com;

en=1;//开始通信

_nop_();

en=0;//关闭通信,为设置参数做准备

/********向液晶屏输入数据子函数************/voidin_data(uchardat)

delay

(2);

en=0;//关闭通信,为设置参数做准备

rs=1;//选择数据寄存器

rw=0;//写入液晶

_nop_();

data_port=dat;

_nop_();

en=1;//开始通信

_nop_();

en=0;//关闭通信,为设置参数做准备

/***********计算星期值子函数**************/ucharcalculate_week()

uintdays_number;//存储天数值

uchari;

if(year>=1)

days_number=days_number+(year*365);//从00年到year-1年的总天数

else

days_number=0;

for(i=1;i

switch(i)

case1:

case3:

case5:

case7:

case8:

case10:

case12:

days_number+=31;//大月31天

break;

case4:

case6:

case9:

case11:

days_number+=30;//小月30天

 

case2:

if(year%4==0)//闰年2月29天

{days_number+=29;}

 

else

//平年2月28天

 

{days_number+=28;}

break;

{return(7);}

else

{return((days_number+5)%7);}

/*********LCD1602显示星期值子函数************/voidweek_disp(ucharx)

switch(x)

case1:

lcd_disp_string("MON");

//

显示"星期一"

 

 

//显示"星期二"

break;

case2:

lcd_disp_string("TUE");

break;

 

break;

 

//显示"星期五"

break;

case5:

lcd_disp_string("FRI");

break;

 

//显示"星期日"

break;

case7:

lcd_disp_string("SUN");

 

/*****************

按键设置函数**************/

voidkey()

if(set_key==0)

//检测"设置"键是否按下

delay(5);

//延时消抖

if(set_key==0)

ET0=0;

//打开定时器T0中断允许位

TR0=0;

//启动定时器T0

if(flag<6)

{flag++;}

else

 

时"

分"

秒"

{flag=0;}

switch(flag)

case0:

if(set==1)

set=0;

//检测时间是否更改

//时间更改标志复位

dis_val[0]=((year/10)<<4)|(year%10);

dis_val[1]=((month/10)<<4)|(month%10);//

dis_val[2]=((day/10)<<4)|(day%10);

dis_val[3]=week;

//

//刷新"年"

刷新"月"

//刷新"日"

刷新"星期"

dis_val[4]=((hour/10)<<4)|(hour%10);

dis_val[5]=((minite/10)<<4)|(minite%10);

dis_val[6]=((second/10)<<4)|(second%10);

//

//

//

刷新"

刷新"

刷新"

 

in_command(0x0c);//

开显示,关光标,关闪烁

 

break;

 

位闪烁

case1:

in_command(0x83);

//设定显示(光标)位置"

年"低

in_command(0x0d);

//开显示,关光标,开闪烁

year=((dis_val[0]>>4)*10)+(dis_val[0]&0x0f);

//

预设

 

调节变量初始值为当前时刻

month=((dis_val[1]>>4)*10)+(dis_val[1]&0x0f);

day=((dis_val[2]>>4)*10)+(dis_val[2]&0x0f);

hour=((dis_val[4]>>4)*10)+(dis_val[4]&0x0f);

minite=((dis_val[5]>>4)*10)+(dis_val[5]&0x0f);

second=((dis_val[6]>>4)*10)+(dis_val[6]&0x0f);

break;

 

位闪烁

case2:

in_command(0x86);

//设定显示(光标)位置"

月"低

break;

case3:

in_command(0x89);

//设定显示(光标)位置"

日"低

 

位闪烁

break;

case4:

in_command(0xc5);

//设定显示(光标)位置"时"低

位闪烁

break;

case5:

in_command(0xc8);

//设定显示(光标)位置"分"低

位闪烁

break;

case6:

in_command(0xcb);//

设定显示(光标)位置"秒"低位

闪烁

break;

while(set_key==0);

if(up_key==0&&flag!

=0)

//检测"设置时间"启动时,"上升"键是否

按下

 

delay(5);

//延时消抖

 

if(up_key==0)

switch(flag)

case1:

if(sflag==1)

{break;}if(year<99){year++;}else{year=0;}

if(year%4!

=0&&month==2)//平年的2月

if(day>28)

"日"高位

位闪烁

day=28;

in_command(0x88);

//设定显示(光标)位置

in_data(num_tab[day/10]);//修正"日"

in_data(num_tab[day%10]);

week=calculate_week();

in_command(0x8c);

week_disp(week);

in_command(0x82);

in_data(num_tab[year/10]);

//计算星期值

//设定显示(光标)位置"星期"

//LCD1602显示星期值

//

in_data(num_tab[year%10]);

in_command(0x83);

//

break;

设定显示(光标)位置"年"高

//显示正在调节的"年"

设定显示(光标)位置"年"低

 

高位

日"

case2:

if(sflag==1)

{break;}if(month<12){month++;}else{month=1;}if(month==4||month==6||month==9||month==11)

if(day>30)

day=30;

in_command(0x88);//设定显示(光标)位置"

in_data(num_tab[day/10]);//修正"日"

in_data(num_tab[day%10]);

if(month==2)

 

"日"高位

in_data(num_tab[day/10]);//修正"日"

in_data(num_tab[day%10]);

if(day>28)

day=28;

in_command(0x88);//设定显示(光标)位置

"日"高位

if(day>29)

day=29;

in_command(0x88);//设定显示(光标)位置

in_data(num_tab[day%10]);

week=calculate_week();//计算星期值

//显示正在调节的"月"

in_data(num_tab[month/10]);

in_data(num_tab[month%10]);

闪烁

break;

case3:

if(sflag==1)

{break;}if(month==4||month==6||month==9||month==11)

if(day<30){day++;}else{day=1;}

elseif(month==2)

 

if(year%4!

=0)

//平年

if(day<

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

当前位置:首页 > 法律文书 > 调解书

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

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