目录
一、设计背景
二、实现功能
三、仿真结果
四、源程序
一、设计背景
随着科技的不断发展,电子设备在我们生活中扮演着愈加重要的角色。这些电子设备不仅使我们的生活更加便利,还帮助我们提高工作效率和精确度。其中,电子秒表是常用的计时设备之一,用于精确测量时间的消逝。本设计的数字电子秒表系统采用51单片机为中心器件,利用其定时器/计数器定时和记数的原理,结合显示电路、LED数码管以及外部中断电路来设计电子秒表。将软、硬件有机地结合起来,使得系统能够实现三位LED显示,倒计时精度为0.1秒,能正确地进行计时,复位后重新回到初始状态。其中软件系统采用C语言编写程序,包括显示程序,定时中断服务,外部中断服务程序,延时程序等,并在KEIL5中调试运行,硬件系统利用PROTEUS8.11强大的功能来实现,简单切易于观察,在仿真中就可以观察到实际的工作状态。
二、实现功能
本设计以51单片机为核心,,采用常用电子器件设计,两个按键、三个数码管显示,开机后显示0,每秒循环左移一位,即“口口0->”口0口”->”0口口”,按A键开始显计时,实时显示所经历的时间,按B键停止计时并显示从开始到当前的时间,按键采用中断方式,按键A接INT0,按键B接INT1,要求精确到0.1秒,量程为0-99.9秒.
三、仿真结果
开机显示0。
每秒循环左移一位。
按A键开始显计时,实时显示所经历的时间,按B键停止计时。
四、源程序
#include <reg51.h>
#define uchar unsigned char //0——255
#define uint unsigned int //0——65535
#define ulong unsigned long //0——4294967295
uchar disCode[10] = {0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; //数码管段码 0~9
uchar disDotCode[10] = {0x02,0x9e,0x24,0x0c,0x98,0x48,0x40,0x1e,0x00,0x08}; //数码管段码 0~9(无数码管)
uchar locCode[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码
void displayTime(void); //刷新时间显示
void disPlay(uchar num, uchar loc); //数码管、led显示函数
void Exint_Init(void);
void Timer_Init(void);
void Delay1ms(unsigned int n); //延时1ms
void Delay_us(unsigned int t);
ulong ms = 0; //存储毫秒值
uchar miao = 0; //秒数
uchar set_flag = 0;
uchar smg_c = 0; //数码管闪烁时间计数
uchar smg_f = 0; //数码管闪烁标志
uchar smg_b = 0;
void Timer_Init(void)
{
TMOD=0x11; //0110 0001 //方式一
TH0= (65536-100000)/256;
TL0= (65536-100000)%256; // 100ms
TH1= (65536-50000)/256;
TL1= (65536-50000)%256; // 50ms
TR0=1; //开启T0
TR1=1; //开启T1
//ET0=1; //T0中断允许
ET1=1; //T1中断允许
EA=1; //总中断开启
}
/*******************************************************************************
* 函 数 名 : T0_INT
* 函数功能 : T0定时器中断函数10ms
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void T0_INT0(void) interrupt 1
{
ms++;
if(ms == 10) //1s时间到
{
ms = 0;
miao++;
if(miao == 100) //秒数计时为0
{
miao=0;
}
}
displayTime();
}
/*******************************************************************************
* 函 数 名 : T0_INT1
* 函数功能 : T0定时器中断函数50ms
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void T0_INT1(void) interrupt 3
{
smg_c++;
if(smg_c == 20)
{
smg_b++;
smg_f=smg_b%3;
smg_c = 0;
}
displayTime();
}
/*********外部中断0、1初始化***********/
void Exint_Init()
{
IT0 = 1;
IT1 = 1; //下降沿触发
EX0 = 1;
EX1 = 1;
PX0 = 1; // 中断优先级设置
PX1 = 0;
}
/*********外部中断0服务函数***********/
void Exint0_Service() interrupt 0
{
ET0 = 1; //T0中断允许打开,开始计时
set_flag = 1;
smg_b=0;
smg_f=0;
ms=0;
miao=0;
}
/*********外部中断1服务函数***********/
void Exint1_Service() interrupt 2
{
ET0 = 0;
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main(void)
{
Timer_Init();
Exint_Init();
P1=0xff;
while(1)
{
displayTime(); //刷新时间显示
}
}
void displayTime(void) //刷新时间显示
{
if((smg_f == 2)||set_flag==1)
{
disPlay(miao/10, 3); //显示秒数的个位
}
if((smg_f == 1)||set_flag==1)
{
disPlay(miao%10, 4); //显示秒数的十位
}
if((smg_f == 0)||set_flag==1)
{
disPlay(ms%10, 5); //显示秒数的个位
}
}
void disPlay(uchar num, uchar loc) //数码管、led显示函数
{
P0 = 0xff; //消除重影
P2 = locCode[loc]; //位码输出
if((loc==4)&&(set_flag==1)){ P0 = disDotCode[num];} //段码输出
else{P0 = disCode[num];}
Delay_us(200); //增加显示时间,防止显示过暗
}
void Delay_us(unsigned int t)
{
while(t--);
}
keil源码工程及Protues源文件百度网盘链接:https://pan.baidu.com/s/1WeaZmNS1-RsRYijD65EQHQ 提取码:77xd