要求:

1、计时范围:0~59分59.59秒,整数四位数和小数两位数显示;

2、计时精度10毫秒;

3、复位按钮,计时器清零,并做好下次计时准备;

4、可以对两个对象(A、B)计时,具有启/停控制;

3、设开始、停止A、停止B、显示A、显示B、复位按钮。

获取该 程序+protues 的方式:

2、关注微信公众号下载:

     ① 关注微信公众号:Tech云  

     ②

课程设计题六:秒表_定时器计数器应用

3、可以关注点赞并在下方评论,我给你邮箱发过去。

一、Protues仿真图:

课程设计题六:秒表_protues_02

课程设计题六:秒表_动态数码管显示_03

课程设计题六:秒表_定时器计数器应用_04

课程设计题六:秒表_动态数码管显示_05

课程设计题六:秒表_按键扫描调试代码_06

二、程序源码:

因为注释非常的全,这里就不再进行讲解了。

/*******************************************************************************
================================================================================
【平 台】STC89C51_sumjess平台
【编 写】sumjess
【软件版本】V2.0
【最后更新】2019年06月10日
【相关信息参考下列地址】
【网 站】
http://www.51hei.com/bbs/mcu-2-1.html
---------------------------------------------------------------------------------
【dev.env.】MDK4.02及以上版本
【Target 】STC89C51
第一次修订:2019/05/09
第二次修订:2019/05/21
第三次修订:2019/06/10
【problem 】
(1)库内补充的不全面;
(2)库内解释部分不全面;
(3)库内还存在一定的bug;
【direction】
下一步的目标就是把库继续集成!
【explain 】
为了方便使用,我也自己写了很多的库,和优化了算法和表示方式!
【warning】
目前程序中暂无错误 !
---------------------------------------------------------------------------------
没有完美的代码,只有不断的奉献,大家一起努力;
赠人玫瑰手留余香,欢迎大家反馈bug!
================================================================================
********************************************************************************/
#include <reg52.h>
#define uint unsigned int //宏定义无符号整型数据
#define uchar unsigned char //宏定义无符号字符型数据

sbit key1=P3^6; //开始按键
sbit key2=P3^0; //停止按键A
sbit key3=P3^1; //停止按键B
sbit key4=P3^2; //显示按键A
sbit key5=P3^3; //显示按键B
sbit key6=P3^4; //复位按键

sbit dula=P2^6; //段
sbit wela=P2^7; //位

uchar code table[]={ //0~f段码
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar Cntus=0,Cnt10ms=0,Cnt1s=0,Cnt1min=0;//中断计时变量
uchar Cntus_A=0,Cnt10ms_A=0,Cnt1s_A=0,Cnt1min_A=0;//存储A的数据
uchar Cntus_B=0,Cnt10ms_B=0,Cnt1s_B=0,Cnt1min_B=0;//存储B的数据

bit stop=0; //停止标志
void display(); //显示程序声明
void keyscan(); //按键扫描程序声明
/***********按键扫描程序****************/
void keyscan()
{
if(key1==0) stop=1; //开始计时
if(key6==0) //复位计时
{
stop=0;
Cntus=0;
Cnt10ms=0;
Cnt1s=0;
Cnt1min=0;
}
if(key2==0){ //A停止,存储数据
Cntus_A=Cntus;Cnt10ms_A=Cnt10ms;Cnt1s_A=Cnt1s;Cnt1min_A=Cnt1min;}
if(key3==0){ //B停止,存储数据
Cntus_B=Cntus;Cnt10ms_B=Cnt10ms;Cnt1s_B=Cnt1s;Cnt1min_B=Cnt1min;}
if(stop==0){ //当复位即计时结束后,才可以进行查看
if(key4==0) //A显示
{
Cntus=Cntus_A;Cnt10ms=Cnt10ms_A;Cnt1s=Cnt1s_A;Cnt1min=Cnt1min_A;
}
if(key5==0) //B显示
{
Cntus=Cntus_B;Cnt10ms=Cnt10ms_B;Cnt1s=Cnt1s_B;Cnt1min=Cnt1min_B;
}
}
}
/***********定时器初始化程序****************/
void Timer0Init(void) //2.5毫秒@11.0592MHz
{
TMOD = 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xF7; //设置定时初值
TR0 = 1; //定时器0开始计时
EA=1; //开总中断
ET0=1; //开定时器0中断
}
/***************主程序****************/
void main()
{
Timer0Init(); //定时器初始化
while(1)
{
keyscan(); //按键扫描
display(); //显示程序
}
}
/**************中断服务程序*****************/
void timer0() interrupt 1 //2.5毫秒@11.0592MHz
{
TL0 = 0x00; //设置定时初值
TH0 = 0xF7; //设置定时初值
Cntus++; //中断变量Cntus自+1
if(Cntus>=4) //10ms
{
Cntus=0; //清0
if(stop==1) //启动的前提是计时按键按下
Cnt10ms++; //10毫秒计数
if(Cnt10ms>=100)
{
Cnt10ms=0;
Cnt1s++; //秒计数
if(Cnt1s>=60)
{
Cnt1s=0;
Cnt1min++; //分计数
if(Cnt1min>=100)
Cnt1min=0;
}
}
}
}
void display()//显示程序
{
static uchar count=0; //计数变量 作用是是函数一直在循环
P0=0x00; //消隐
dula=1;
dula=0;
switch(count)
{
case 0:
P0=table[Cnt1min/10]; //显示十分位
dula=1;
dula=0;

P0=0x7e;
wela=1;
wela=0;
count++;
break;
case 1:
P0=table[Cnt1min%10]|0x80;//显示分位加点
dula=1;
dula=0;

P0=0x7d;
wela=1;
wela=0;
count++;
break;
case 2:
P0=table[Cnt1s/10]; //显示十秒位
dula=1;
dula=0;

P0=0x7b;
wela=1;
wela=0;
count++;
break;
case 3:
P0=table[Cnt1s%10]|0x80;//显示秒个位加点
dula=1;
dula=0;

P0=0x77;
wela=1;
wela=0;
count++;
break;
case 4:
P0=table[Cnt10ms/10]; //显示十分秒位
dula=1;
dula=0;

P0=0xef;
wela=1;
wela=0;
count++;
break;
case 5:
P0=table[Cnt10ms%10]; //显示百分秒位
dula=1;
dula=0;

P0=0xdf;
wela=1;
wela=0;
count=0;
break;
}
}