10 秒定时报警器
1 训练内容及要求
1.1 训练内容
设计出一个用于控制时钟的控制器。准确地理解有关要求,独立完成系统设
计,要求所设计的电路具有以下功能:
(1)可以显示 10 秒内的计时时间。
(2)当计数时间到 10 秒时,蜂鸣器发出报警器。
2 系统工作原理
2.1 设计思路
电路总体上分为控制、显示和报警部分。由单片机作为核心器件来控制 2 位数码
管的显示,具体显示内容及方式由软件来完成,分别控制它的个位和十位;复位
电路采用按键复位,结合程序控制;报警部分是蜂鸣器。
2.2 设计原理
单片机 P0 口的 P0.0~P0.6 分别接到数码管的 A~G,用来控制数码管显示的数值大
小,而 P0.7 口接数码管的 DP 端,并且这 8 个管脚接到 RESPACK8 接到电源,相
当于一个上拉电阻;P2 口的 P2.0 和 P2.1 通过反相器 74LS04 分别接到数码管的
1、2 端,控制数码管的个位和十位的显示;P3.0 口通过按键接地,这是系统中
唯一的按键,结合程序来完成三个按键的功能:当第一次按下按键时,系统暂停;
当第二次按下按键时,系统开始;当第三次按下按键时,系统复位清零;P3.7
口直接接到蜂鸣器 Speaker,控制系统满足一定要求时的报警。
3 程序设计方案
3.1 对主程序的分析:
在主程序中,首先设定定时器的工作方式为方式 1,再设定计数的初值,打
开中断和定时器,通过 while(1)语句来调用 display(sun)和 keycan()来
控制系统的显示和按键。
void main()
{
%设定定时器工作方式为方式 1
%设定计数器计数的初值
%打开中断
%启动定时器
TMOD=01;
TH0=-50000/256;
TL0=-50000%256;
EA=1;
ET0=1;
TR0=1;
t=0;
while(1)
{
display(sun);
keycan();
}
}
3.2 对子程序的分析:
(1)延时子程序
设置两个变量 x、y 设置循环次数来达到延时的作用。
void delay(uint z)
%定义 z
{
}
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
%给 x 和 y 赋值来决定延时时间
(2)显示子程序
分别定义个位和十位,并且调用以定义的数组中的 0~9 的数码值来显示数码,当
把 P0 口定义为个位,P2=0xfe 时,使得 P2.0=0,P2.1=1,进而使得数码管的 1
端为 1,2 端为 0,控制个位的数值;当把 P0 口定义为十位,P2=0xfd 时,使得
P2.0=1,P2.1=0,进而使得数码管的 1 端为 0,2 端为 1,控制十位的数值。在
显示中加入了延时 delay(5)来防止视觉暂留。
2
图 1 显示部分接线图
void display(uchar sum)
{
uchar ge,shi;
%定义个位和十位
ge=table[sum%10];
shi=table[sum/10];
P0=0;
P2=1;
P0=ge;
P2=0xfe;
delay(5);
P0=0;
P2=1;
P0=shi;
P2=0xfd;
delay(5);
%通过对 P2 口的设定决定显示个位的数值
%调用延时程序,防止视觉暂留
%通过对 P2 口的设定决定显示十位的数值
%调用延时程序,防止视觉暂留
(3)按键扫描子程序
在按键时会遇到一个问题:当不小心碰到了按键致使按键闭合时,电路会接通。
因此在写程序时,加入一个防抖动的延迟 delay(30),这样只有当按键长按达到
一定时间时,电路才会接通。然后设置变量 i,通过 i 的自加和 switch 语句来
决定系统的状态是暂停、开始还是复位。
void keycan()
3
{
uint i;
if(s1==0)
{
delay(30);
if(s1==0)
{
i++;
switch(i)
{
case 1:TR0=0;break;
case 2:TR0=1;i=0;break;
case 3:sun=0;break;
default:break;
}
while(!s1);
}
}
}
%调用延时程序防止按键抖动
%当 i=1 时,关定时器,系统处于暂停状态
%当 i=2 时,开定时器,系统处于开始状态
%当 i=3 时,将数码管清零,复位
图 2 按键扫描子程序流程图
(3)中断子程序
图 3 按键开关接线图
应为中断子程序主要为主程序服务,随意开始对程序中计数值进行人为重装,重
4
新定义变量 i=0,通过 i 的自加,比较 i 和计时点 10 的大小,当 i 比 10 小时,
返回主程序进行数码的显示输出,同时 i 加 1;当 i 等于 10 时,此时满足条件,
程序不返回,继续往下执行,设定单片机的 P0 口和 P2 口都为 0,根据预先设定
的报警时间长度通过 while 语句进行蜂鸣器的报警设置,数码管显示全为 0。
void T0_time() interrupt 1
{
uint i,t;
TH0=-50000/256;
TL0=-50000%256;
i++;
if(i==20)
{
i=0;
sun++;
if(sun==10)
{
t=110;
P0=0x3f;
P2=0;
sun=0;
while(t--)
%由于定时器工作在方式 1,所以需要重新装入计数初值
%设定 t 值来控制蜂鸣器的报警时就爱你
{_Speak=~_Speak;
%当 i 值达到 10 时,数码管清零,发出报警声
delay(10);}
}
}
}
5
4 运行结果
图 4 中断子程序流程图
图 5 运行结果图
6
5 结果分析
在 keil 和 proteus 两个软件中,编出的程序能将计数值显示出来,并且可
以在 10 秒计数值到的时候蜂鸣器发出报警声。当第一次按下按键开关时,计数
停止;当第二次按下按键开关时,系统又开始计数;当第三次按下按键开关时,
系统复位清零。实验观测的结果与先前编程过程中预计的结果完全一样,因此可
知实验里所得到的结果完全正确。使我们更加亲切的体会到了 keil 和 proteus
软件的强大的运行程序等功能,利用这两个软件我们可以很快,很准确的得到结
果,这正体现了 keil 和 proteus 的强大功能,而且它很容易掌握,很适合大学
生学习单片机使用。
心得体会
通过这次课程设计,让我收获了很多:自己对课本上的知识可以应用于实际,
使的理论与实际相结合,加深自己对课本知识的更好理解,能够充分利用图书馆
去查阅资料,利用网络搜索有用的资料,了解了许多课本以外的知识。总之,这
次实习收获是很大的,我会利用实习所得有效地搞好我的学习。
7
附录一
程序代码
#include·
#define uchar unsigned char
#define uint unsigned int
sbit s1=P3^0;
sbit _Speak=P3^7;
uchar sun,t,label=0;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
void delay(uint z)
{
}
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
/***************显示子程序************************/
void display(uchar sum)
8