基于单片机可调节数字电子钟设计设计性实验报告.docx
《基于单片机可调节数字电子钟设计设计性实验报告.docx》由会员分享,可在线阅读,更多相关《基于单片机可调节数字电子钟设计设计性实验报告.docx(17页珍藏版)》请在冰点文库上搜索。
基于单片机可调节数字电子钟设计设计性实验报告
综合性、设计性实验报告
姓名学号
姓名学号
专业通信工程
实验课程名称单片机原理与应用
指导教师及职称赵全友副教授
开课学期2014至2015学年上学期
上课时间2015年9月2日
湖南科技学院教务处编印
一、实验设计方案
实验名称:
可调节数字电子钟设计
实验时间:
2016-1-4
小组合作:
是●否○
小组成员:
1、实验目的:
1)学习数码管的基本知识。
2)学会如何控制动态数码管扫描显示。
2、实验设备及材料:
硬件设备:
单片机实验箱、USB烧录线
机器配置:
计算机一台
操作系统:
Win7
开发工具:
KeilC、Proteus、FlashMagic一套
3、实验内容:
①问题描述
利用共阴极的6位LED数码管进行显示,然后用定时器T0实现定时,实现一个数字电子钟,实现时、分、秒,并用“.”隔开显示。
②编程任务
1.利用通过修改电路实现对数字电子钟实现控制,即能适时地设置时间,并完成相应的程序。
2.利用通过修改电路实现一个电子秒表,启动秒表,暂停秒表,秒表清零,秒表显示到毫秒。
③样例
1.定时1秒,采用16位定时50ms,共定时20次才可达到1秒,进一步可实现分时。
2.利用小延时或者另一个定时器实现对8个数码管的动态扫描显示。
3.时间设置采用外部中断。
4、实验方法步骤及注意事项:
(注意:
此部分为本实验的关键部分,请自行填写,不得雷同!
)
①实验步骤(自行填写)
1、打开电脑并运行KeilC建立工程;
2、编辑C51程序文本文件,写入核心代码并添加到sourcegroup里;
3、把实验箱接通电源及烧录线,打开FlashMagic软件把程序下载到芯片里面;
4、验证实验结果。
②解题思路(注意:
以下部分仅为提示,请自行填写;若表格不够,可自行拉伸。
)
1.如何实现定时1秒,1分,1小时
2.如何实现对动态数码管的动态扫描显示
3.如何实现多功能的电子表。
解题思路:
1、使用定时器0作为实时时钟每隔50ms产生一次脉冲(即给定时器0赋初值为TH0=(65536-50000)/256;TL0=(65536-50000)%256;),计数20次就是1秒;当计数到60秒时,秒钟全部清零给分钟计数加一;同理当分钟计数到60时给小时加一,分钟全部清零;小时计数到24才清零。
2、先对动态数码管进行段选编码0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f分别对应0、1、2、3、4、5、6、7、8、9,然后对数码管进行位选依次亮不同的数码管,在短暂的时间里由于人眼的余辉效应可以看到数码管是同时亮的。
3、利用中断0计数进行模式切换已达到多功能的目的,然后用中断1合理配合标志位对相应功能进行操作。
5.参考文献:
《单片机原理与接口技术》张毅刚主编,人民邮电出版社,2008
《单片机原理及应用》(第二版),曹巧媛主编,电子工业出版社,2004
指导老师对实验设计方案的意见:
指导老师签名:
年月日
二、实验报告
1、实验目的、设备与材料、实验内容、实验方法步骤见实验设计方案
2、实验程序(请自行填写,可拉大表格)
实验核心代码:
#include
#defineuintunsignedint
#defineucharunsignedchar
ucharaa,ss,bb,num1,num2,flag1,flag2,p1,p2,flag3,flag4,flag5,flag6;
ucharmms1,mms2,ms1,ms2,mm1,mm2,s1,s2,m1,m2,h1,h2,h;
sbitdula=P2^6;
sbitwela=P2^7;
sbitk1=P3^2;//外部中断0
sbitk2=P3^3;//外部中断1
sbitk3=P3^5;//定时器中断1
sbitled=P0^0;
sbitalarm=P2^3;
ucharcodetable1[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
voiddisplay0(uchars1,uchars2,ucharm1,ucharm2,ucharh1,ucharh2);
voiddelay(uintz);
voidinit();
voidmain()
{
init();//初始化子程序
while
(1)
{
switch(num1)
{
case1:
//调时
{
flag3=1;
led=0;
display0(s1,s2,m1,m2,h1,h2);
break;
}
case2:
//秒表
{
flag3=0;
display0(mms1,mms2,ms1,ms2,mm1,mm2);
break;
}
case3:
//闹钟
{
flag3=0;
break;
}
default:
display0(s1,s2,m1,m2,h1,h2);//计时
}
if(flag2==1)//秒表清零
{
mms1=0;mms2=0;ms1=0;ms2=0;mm1=0;mm2=0;flag1=0;flag2=0;
}
if(h==1&&s1<=3)//整点报时
{
alarm=p2;
h=0;
}
}
}
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voiddisplay0(uchars1,uchars2,ucharm1,ucharm2,ucharh1,ucharh2)
{
dula=1;
P0=table1[h2];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay
(1);//h2
dula=1;
P0=table1[h1]|0x80;//显示小时后的小数点
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay
(1);//h1
dula=1;
P0=table1[m2];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
delay
(1);//m2
dula=1;
P0=table1[m1]|0x80;//显示分钟后的小数点
dula=0;
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
delay
(1);//m1
dula=1;
P0=table1[s2];
dula=0;
P0=0xff;
wela=1;
P0=0xef;
wela=0;
delay
(1);//s2
dula=1;
P0=table1[s1];
dula=0;
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
delay
(1);//s1
}
voidinit()
{
wela=0;
dula=0;
num1=0,num2=0;flag1=0;flag2=0;flag3=0;flag4=0;flag5=0;flag6=0;p1=0;p2=0;
aa=0;ss=0;bb=0;s1=0;s2=0;m1=0;m2=0;h1=0;h2=0;
mms1=0;mms2=0;ms1=0;ms2=0;mm1=0;mm2=0;
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TH1=(65536-10000)/256;
TL1=(65536-10000)%256;
EA=1;//开放总中断
ET0=1;//开放定时器0中断
TR0=1;
ET1=1;//开放定时器1中断
TR1=0;
EX0=1;//开放外部中断0,k1
EX1=1;//开放外部中断1,k2
}
voidtimer0()interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;bb++;//h=h1;
if(aa==20)
{
aa=0;
if(s1==9)
{
s1=0;//m2++;
if(s2==5)
{
s2=0;
if(m1==9)
{
m1=0;
if(m2==5)
{
m2=0;
if(h1==9)
{
h1=0;
h2++;
h=1;//闹钟标志位
}
else
{
if(h1==3&&h2==2)
{
h1=0;
h2=0;
}
else
h1++;//endif6
}//endif5
}
else
m2++;//endif4
}
else
m1++;//endif3
}
else
s2++;//endif2
}
else
s1++;//endif1
}
if(bb==5)//设置一定频率的闹钟铃声
{
p2=~p2;
bb=0;
}
}
voidtimer1()interrupt3
{
TH1=(65536-10000)/256;
TL1=(65536-10000)%256;
if(flag4==0)
{
ss++;
if(ss==1)
{
ss=0;
if(mms1==9)
{
mms1=0;
if(mms2==9)
{
mms2=0;
if(ms1==9)
{
ms1=0;
if(ms2==5)
{
ms2=0;
if(mm1==9)
{
mm1=0;
if(mm2==5)
{
mm2=0;
}
else
mm2++;//endif6
}
else
mm1++;//endif5
}
else
ms2++;//endif4
}
else
ms1++;//endif3
}
else
mms2++;//endif2
}
else
mms1++;//endif1
}
}
else
{
if(!
k3)
{
if(flag6==0)
{
TR0=0;m1++;flag5=1;//调分
}
else
{
TR0=0;h1++;flag4=0;flag5=0;flag6=0;//调时
}
TR0=1;
}
}
}
voidinter0()interrupt0
{
if(k1==0)
{
delay(20);
if(k1==0)
if(flag1==0)
{
num1++;
if(num1==4)
num1=0;
}
else
{
flag2=1;
}//endif1
}
}
voidinter1()interrupt2
{
if(k2==0)
{
delay(20);
if(k2==0)
{
if(flag3==0)
{
p1=~p1;
flag1=1;
if(p1)
TR1=1;
else
TR1=0;
}
else
{
if(flag5==0)
flag4=1;
elseflag6=1;
}
}
}
}
3、对实验现象、数据及观察结果的分析与讨论:
经过不断调试实验最终现象及数据结果都正常,可以正常以秒为单位进行24小时制计时,当秒钟计数到60时向分钟进位,秒钟自动清零;当分钟计数到60时向小时进位,分钟自动清零,同时整点报时启动;当小时计数到24时自动全部清零。
同时秒表也可以正常运行毫秒计数到100自动向秒钟进位且毫秒自动清零,同理秒计数到60自动向分进位,当分计数到60时自动清零;若按下k2键则秒表暂停,此时若再按下k1则秒表清零;在按一次k1模式切换键则回到时钟主界面。
4、结论:
实验设计方案基本可以完全符合题目要求,可以实现设计基本功能;
在设计执行调时功能方案时还可以在定时器里设置标志位实现数码管位选延迟以达到调时闪烁醒目目的。
5、实验总结
1)、本次实验成败之处及其原因分析:
注:
从技术角度来分析实验的成功或失败,分析实验过程中出现了哪些问题,程序出现了什么错误,出现错误的具体原因是什么,以及是如何解决的。
问题:
数码管显示亮度存在模糊现象,按键按的不准;
原因:
数码管没有消影,按键没有实现防抖;
解决:
在数码管进行位选时立马屏蔽(P0=0xff)或者增加一定短暂的延时;对按键进行消抖,即可以延时15ms再做判断。
2)、本实验的关键环节及改进措施:
做好本实验需要把握的关键环节:
1、对定时器初值的设定以及使用,这样才能精确到秒以及毫秒;
2、数码管的动态显示原理的理解及实现的掌握;
3、两个中断接口的配合使用,以及合理利用标志位这样才能实现多功能。
若重做本实验,为实现预期效果,仪器操作和实验步骤应如何改善:
在进行数码管位选时可以在头文件加#include利用intrinsic函数移位的功能可以很方便实现数码管的位选而不需要手动编码。
3)、对实验的自我评价:
(注:
自己的体会、感想和收获等)
刚开始对实验设计的整体理解的不是很全面,但在做的时候遇到不懂的就不断的查阅相关资料,尤其在多功能这一块,需要对标志位深刻理解和灵活使用,配合两个外部中断开关以实现好几个功能,由于本身也有单片机开发板,所以在开发板上不断的调试不断的修改,可以很方便的看到自己设计的实验结果,最终经过两天不断的努力终于弄出来了,实验设计的要求都得以实现,并扩展了整点报时功能。
指导老师评语及得分:
签名:
年月日