数字电子时钟实验报告.docx
- 文档编号:266690
- 上传时间:2023-04-28
- 格式:DOCX
- 页数:13
- 大小:45.68KB
数字电子时钟实验报告.docx
《数字电子时钟实验报告.docx》由会员分享,可在线阅读,更多相关《数字电子时钟实验报告.docx(13页珍藏版)》请在冰点文库上搜索。
数字电子时钟实验报告
重庆理工大学
嵌入式接口技术综合实验报告
题目:
数字时钟程序设计
二级学院计算机科学与工程
专业计算机科学与技术
班级37-3
学生姓名许鸿兴
教师
时间
成绩
一、实验名称
二、实验目的
三、实验设备与环境
四、实验基本原理
五、实验内容(包括主要算法分析与流程图)
六、实验源程序及分析
七、实验运行结果及分析
八、实验心得体会
1、实验名称
数字时钟程序设计
2、实验目的
熟悉单片机数码管、按键等的应用,了解并掌握单片机中断、定时的使用等。
三、实验设备与环境
微机、AT89S52单片机、KeiluVision4软件等。
4、实验基本原理
本实验采用的数码管为共阳极数码管。
数码管是一种把多个LED显示段集成在一起的显示设备。
有两种类型,一种是共阳型,一种是共阴型。
共阳型就是把多个LED显示段的阳极接在一起,又称为公共端。
共阴型就是把多个LED显示段的阴极接在一起,即为公共端。
阳极即为二极管的正极,又称为正极,阴极即为二极管的负极,又称为负极。
通常的数码管又分为8段,即8个LED显示段,这是为工程应用方便如设计的,分别为A、B、C、D、E、F、G、DP,其中DP 是小数点位段。
而多位数码管,除某一位的公共端会连接在一起,不同位的数码管的相同端也会连接在一起。
即,所有的A段都会连在一起,其它的段也是如此,这是实际最常用的用法。
数码管显示方法可分为静态显示和动态显示两种。
动态显示:
所谓动态显示,就是一位一位的轮流点亮各个位,对于显示器的每一位来说,每隔一段时间点亮一次。
利用人的视觉暂留功能可以看到整个显示,但必须保证扫描速度足够快,字符才不闪烁。
显示器的亮度既与导通电流有关,也于点亮时间与间隔时间的比例有关。
调整参数可以实现较高稳定度的显示。
动态显示节省了I/O口,降低了能耗。
5、实验内容(包括主要算法分析与流程图)
整个系统采用AT89S52作为时钟控制芯片,利用单片机内部的定时器\计数器来实现的,它的处理过程如下:
首先设定单片机内部的一个定时器\计数器工作于定时方式,对机器周期计数形成基准时间,然后用另一个定时器\计数器或软件计数的方法对基准时间计数形成秒,秒计60次形成分,分计60次形成小时,小时计24次则计满一天,再通过判断平年、闰年,计数相应的月份天数以及年份天数。
然后通过数码管把它们的内容在相应位置显示出来即可。
数码管显示采用动态显示方法,动态显示方法线路相对简单,但需动态扫描,扫描频率要大于人眼视觉暂留频率,信息看起来才稳定。
在具体处理时,定时器计数器采用中断方式工作,对时钟的形成在中断服务程序中实现。
在主程序中只需对定时器计数器初始化、调用显示子程序和控制子程序。
另外,为了使用方便,设计了简单的按键,可以通过按键实现时间调整和复位。
函数Jude_Show();进行时间判断并输出显示。
首先使用定时器0方式2进行计时,计时1S后Sec自加,Sec自加至60(60秒)后Min自加并将Sec置零,Min自加至60(60分)后Hour自加,并将Min置零,Hour自加至24(24小时)Day自加并将Hour清零。
此时进行平年闰年的判断,如果年份为闰年,则2月天数为28天,如果为平年,则2月的天数为29天,其余相同。
当天数记满相应的一个月后,Month自加,当月数自加至12(12月)后,年份自加。
而后刷新显示缓存输出显示。
主要流程图如下:
1、主流程图:
方式二动态扫描
闹钟判断
2、万年历:
秒=60
分=60
时=24
天=相应月份天数
月份=12
6、实验源程序及分析
#include
unsignedintYear=0,Month=0,Day=0,Sec=0,Min=0,Hour=0;//初始显示的时间
unsignedintFir_year=0,Fir_month=0,Fir_day=0,Fir_Sec=0,Fir_Min=0,Fir_Hour=0;//设置闹钟的时间1
unsignedintSec_year=0,Sec_month=0,Sec_day=0,Sec_Sec=0,Sec_Min=0,Sec_Hour=0;//设置闹钟的时间2
unsignedintThi_year=0,Thi_month=0,Thi_day=0,Thi_Sec=0,Thi_Min=0,Thi_Hour=0;//设置闹钟的时间3
unsignedintFou_year=0,Fou_month=0,Fou_day=0,Fou_Sec=0,Fou_Min=0,Fou_Hour=0;//设置闹钟的时间4
unsignedintOs=0;//系统时钟
unsignedintshift=0xfe,pDG=0;//初始位码以及动态扫描初值
unsignedcharDis[8];//缓存显示码
sbitbeep=P3^7;//蜂鸣器
unsignedcharcodedisplay[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF};//0-9以及”-”段码
voidFirst_Time()//设置初始显示的时间
{
Year=2016;
Month=4;
Day=3;
Hour=12;
Min=23;
Sec=35;
}
voidSet_Time()
{
Fir_year=2016;//设置闹钟1时间
Fir_month=4;
Fir_day=3;
Fir_Hour=12;
Fir_Min=23;
Fir_Sec=40;
Sec_year=2016;//设置闹钟2时间
Sec_month=4;
Sec_day=3;
Sec_Hour=12;
Sec_Min=23;
Sec_Sec=45;
Thi_year=2016;//设置闹钟3时间
Thi_month=4;
Thi_day=3;
Thi_Hour=12;
Thi_Min=23;
Thi_Sec=50;
Fou_year=2016;//设置闹钟4时间
Fou_month=4;
Fou_day=3;
Fou_Hour=12;
Fou_Min=23;
Fou_Sec=55;
}
voidJude_Time()//判断时间是否到闹钟时间
{
if(Year==Fir_year&&Month==Fir_month&&Day==Fir_day&&Hour==Fir_Hour&&Min==Fir_Min&&Sec<=Fir_Sec+2&&Sec>=Fir_Sec)
{
beep=!
beep;//蜂鸣器响3秒
}
elseif(Year==Sec_year&&Month==Sec_month&&Day==Sec_day&&Hour==Sec_Hour&&Min==Sec_Min&&Sec<=Sec_Sec+2&&Sec>=Sec_Sec)
{
beep=!
beep;//蜂鸣器响3秒
}
elseif(Year==Thi_year&&Month==Thi_month&&Day==Thi_day&&Hour==Thi_Hour&&Min==Thi_Min&&Sec<=Thi_Sec+2&&Sec>=Thi_Sec)
{
beep=!
beep;//蜂鸣器响3秒
}
elseif(Year==Fou_year&&Month==Fou_month&&Day==Fou_day&&Hour==Fou_Hour&&Min==Fou_Min&&Sec<=Fou_Sec+2&&Sec>=Fou_Sec)
{
beep=!
beep;//蜂鸣器响3秒
}
}
voidJude_Show()//判断显示
{
Sec++;
if(Sec==60)
{
Min++;
Sec=0;//秒自加到60自身置零,分+1
if(Min==60)
{
Hour++;
Min=0;//分自加到60自身置零,时+1
if(Hour==24)
{
Day++;
if((Year%400==0)||(Year%4==0)&&(Year%100!
=0))//判断闰年
{
if(Month==1||Month==3||Month==5||Month==7||Month==8||Month==10||Month==12)//每个有月31天的月份
{
if(Day==31)//天数增至31,月份加1,Day置零
{
Month++;
Day=0;
}
}
elseif(Month==4||Month==6||Month==9||Month==11)//每个月有30天的月数
{
if(Day==30)//天数增至30,月份加1,Day置零
{
Month++;
Day=0;
}
}
else//二月
{
if(Day==28)//天数增至28,月份加1,Day置零
{
Month++;
Day=0;
}
}
if(Month==12)//月份增至12,年份自加
{
Year++;
}
}
else//平年
{
if(Month==1||Month==3||Month==5||Month==7||Month==8||Month==10||Month==12)//每个有月31天的月份
{
if(Day==31)//天数增至31,月份加1,Day置零
{
Month++;
Day=0;
}
}
elseif(Month==4||Month==6||Month==9||Month==11)//每个月有30天的月数
{
if(Day==30)//天数增至30,月份加1,Day置零
{
Month++;
Day=0;
}
}
else//二月
{
if(Day==29)//天数增至29,月份加1,Day置零
{
Month++;
Day=0;
}
}
if(Month==12)//月份增至12,年份自加
{
Year++;
}
}
}
}
}
//刷新显示缓冲区
Dis[6]=display[Hour%10];//时个位显示码
Dis[7]=display[Hour/10];//时十位显示码
Dis[3]=display[Min%10];//分个位显示码
Dis[4]=display[Min/10];//分十位显示码
Dis[0]=display[Sec%10];//秒个位显示码
Dis[1]=display[Sec/10];//秒十位显示码
}
voidTask1ms()
{
P2=0xff;//初始关闭显示
P0=Dis[pDG];//送段码
P2=shift;//送位码
shift=(shift<<1)|1;//左移一位,修改位码
pDG++;
if(pDG==8)//循环动态扫描
{
pDG=0;
shift=0xfe;//位码加至8循环至1
}
}
voidintt()//初始化
{
TMOD=0x02;//工作方式2
TH0=TL0=0x1A;//250us定时常数256-(250*11.0592/12)=25.6(D)=1A(H)
TR0=1;//开启Timer0中断
ET0=1;//允许Timer0中断
EA=1;//允许总中断
}
voidmain(void)
{
P0=0xff;//端口初始化
P1=0xff;
P2=0xff;
P3=0xff;
intt();//初始化
Dis[5]=Dis[2]=display[10];//显示"-"
Dis[0]=Dis[1]=Dis[3]=Dis[4]=Dis[6]=Dis[7]=display[0];//显示"0"
First_Time();//设置初始时间
Set_Time();//设置闹钟时间
while
(1)
{
Jude_Time();
Jude_Show();
}
}
voidTime0(void)interrupt1//Time0中断服务子函数(负责计时1s)
{
Os++;
if(Os==4000)
{
Sec++;
Os=0;
}
Task1ms();
}
7、实验运行结果及分析
数码管稳定显示以秒为基本单位的时间显示,到达设定的闹钟时间,蜂鸣器响三秒,内部生成万年历。
8、实验心得体会
通过这次试验设计,我更加熟悉、掌握了一定的有关单片机的程序设计开发,加固了多编写代码的好习惯。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数字 电子 时钟 实验 报告