1)设计任务:完成倒计时时钟的设计。


2)指标要求


(1)能够分钟级的倒计时,分钟和秒显示。


(2)倒计时的起始值可以设置。


(3)具有暂停和清零按钮,倒计时结束报警。


(4)供电电压3.3V/5V。


一、Protues仿真图:

二、程序源码:

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

/*******************************************************************************

================================================================================

【平    台】STC89C51_sumjess平台

【编    写】sumjess

【E-mail  】1371129880@qq.com

【软件版本】V2.0

【最后更新】2019年06月10日

【相关信息参考下列地址】

【网    站】

           https://blog.csdn.net/qq_38351824

           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

 

#define uchar unsigned char

#define uint  unsigned int

 

#define duan P1 //段选

#define wei  P3 //位选

sbit key1 = P2^3;   //设置

sbit key2 = P2^4;   //加

sbit key3 = P2^5;   //减

sbit key4 = P2^6;   //启动

sbit key5 = P2^7;   //手动

sbit out  = P2^2;   //输出控制 ,低电平有效

sbit di   = P2^0;   //蜂鸣器

 

bit flag=0,flag1=0,shan=0;

uchar knum,shan_cont,i;

uchar shi=0,fen=0,miao=0;  //时分秒

uint cont,cont1,cont2;

uchar code duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴段码表

                   //  0  1 2   3    5 6 7   8   9

uchar code weima[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};           //位码        加反相器

   //  1   2    3    4   5     6    7    8

uchar LedBuff[]={0,0,0,0,0,0,0,0};                                      //数码管显示缓冲区

 

void init() //定时器初始化

{

TMOD |= 0x01;             //设置定时器0为工作方式1(M1M0为01)

TH0 = (65536-1000)/256;   //1ms初值 @12MHz

TL0 = (65536-1000)%256;

EA = 1;   //开总中断

ET0 = 1;   //开定时器0中断

TR0 = 1;          //启动定时器0

}

 

void dis()          //显示函数

{

        LedBuff[0] = duanma[miao%10];

        LedBuff[1] = duanma[miao/10];

        LedBuff[2] = 0x40;

        LedBuff[3] = duanma[fen%10];

        LedBuff[4] = duanma[fen/10];

        LedBuff[5] = 0x40;

        LedBuff[6] = duanma[shi%10];

        LedBuff[7] = duanma[shi/10];

}

 

 

void keysan() //按键扫描函数

{

static bit  kf1=0,kf2=0,kf3=0;   //自锁标志,这里一定要加static(或者用全局变量),否则按键不灵

static uint i=0,j=0,k=0,l=0,m=0; //消抖延时变量

//////////////////////////////////////启动/暂停键//////////////////////////////////////

if(knum==0)    //只要时分秒都不等于0

{

    if(key4 == 1)    //启动 暂停键

    {

        m=0;    //按键消抖计时变量清零

        kf2=0;    //按键自锁标志清零

    

    }

    else if(kf2 == 0 ) //有按键按下,且是第一次被按下

    {

        ++m;  //消抖

        if( (m>20) && ((miao != 0) || (fen != 0) || (shi != 0)) )

        {       

   //时分秒都为0时,不能启动输出,只要其中之一不为0,就能启动输出

                m=0;    //按键消抖计时变量清零

                kf2=1;    //自锁按键置位,避免一直触发

                flag = !flag;  //启动、暂停计时标志

                out  = !out;   //LED状态取反

        }

    }        

}          

 

//////////////////////////////////////启动/暂停键//////////////////////////////////////         

if(out==1)            //加这句,只有在输出关闭的时候,才能设置计时时间,在倒计时的过程中是不能设置的

{

    if(key1==1)   //设置   //IO是高电平,说明按键没有被按下,这时要及时清零一些标志位

    {

        i=0;           //按键消抖计时变量清零

        kf1=0;         //按键自锁标志清零

    }

    else if(kf1 == 0)  //有按键按下,且是第一次被按下

    {

        ++i;    //消抖

        if(i>12)

        {

            i=0;    //按键消抖计时变量清零

            kf1=1;         //自锁按键置位,避免一直触发

            knum++;    //调节时分秒--->123

            if(knum==4) knum = 0;  //按第四次关闭设置

        }        

    }

}

//////////////////////////////////////加1按键//////////////////////////////////////

if(key2==0)                     //加1按键 快速加数

{

        j++;

        if(j >= 3000)           //长按,数码管扫描放中断里面,这里的值就要取得大才行

        {                       //因为没用delay延时,CPU跑的很快

                if(knum==1)

                {

                    miao++; //秒钟加1

                    if(miao==60) miao = 0; //超过60s变成0

                }

                if(knum==2)

                {

                        fen++; //分钟加1

                        if(fen==60) fen=0; //超过60变0

                }

                if(knum==3)

                {

                        shi++; //小时加1

                        if(shi==24) shi=0; //超过24变0

                }

                j=1000;           //这里j的值可以设置连加的快慢,j的值越大就越快

        }                         //因为初值越大,加到3000的时间就越短

}          

else //慢速加数

                if(knum==1)

                {

                    miao++; //秒钟加1

                    if(miao==60) miao = 0; //超过60s变成0

                }

                if(knum==2)

                {

                        fen++; //分钟加1

                        if(fen==60) fen=0; //超过60变0

                }

                if(knum==3)

                {

                        shi++; //小时加1

                        if(shi==24) shi=0; //超过24变0

                }

                j=0;

}        

//////////////////////////////////////减1按键//////////////////////////////////////

if(key3==0)                 //减1按键 快速减数

{

        k++;

        if(k >= 3000)           //长按,数码管扫描放中断里面,这里的值就要取得大才行

        { //因为没用delay延时,CPU跑的很快

            if(knum==1)

            {

                miao--; //秒钟减1

                if(miao==255) miao = 59; //小于0就等于59

            }

            if(knum==2)

            {

                fen--; //分钟减1

                if(fen==255) fen=59; //小于0就等于59

            }

            if(knum==3)

            {

[1] [2] [3]
关键字:倒计时  时钟  STC89C51 引用地址:课程设计题九: 倒计时时钟设计

上一篇:课程设计题十:简易电子琴设计
下一篇:课程设计题八:篮球比赛计分器

推荐阅读

在知道了取模方式之后,我们就可以根据取模的方式来编写显示字符的代码了,这里我们针对以上取模方式的显示字符代码如下: //在指定位置显示一个字符,包括部分字符//x:0~127 y:0~63//mode:0,反白显示;1,正常显示 //size:选择字体 12/16/24 void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode){ u8 temp,t,t1,y0...
自动驾驶出租车,上路了。9月26日,百度在长沙宣布,自动驾驶出租车队Robotaxi试运营正式开启。首批45辆Apollo与一汽红旗联合研发的“红旗EV”Robotaxi车队在长沙部分已开放测试路段开始试运营。即日起,普通长沙市民即可登录Apollo官网申请成为种子用户,并有机会试乘体验。“出租车司机该下岗了?”此次长沙开放Robotaxi试运营,在国内尚属首例。在此之...
9月27日新疆克拉玛依市白碱滩区体育健身中心内,KOB铁甲格斗全球巡回赛克拉玛依站在观众的助威声中落下帷幕,经过三天共4轮16场比赛的精彩对决,最终七拼八凑战队荣获本站赛事的冠军。克拉玛依站的精彩赛事在抖音和虎牙两大平台同步直播,连续三天的赛事直播共吸引了53.4万人次观看。此次赛事不仅将铁甲格斗文化和精神带来了克拉玛依,也为推动沪克两地多...
  磁翻板液位计以其使用简便、读数直观、功能齐全的特点,被广泛应用于容器内液体介质的液位、界面测量。但普通的磁翻板液位计在使用中经常会出现各种问题,导致故障现象频发。  据分析,故障产生的原因各种各样,有些是由单个部件故障引起的,有些是由多个部件同时故障引起的。现对磁翻板液位计的一些常见问题和故障现象产生的具体原因简析如下:磁翻...

史海拾趣

问答坊 | AI 解惑

找人陪我一同参加美国NI公司的电源开关研讨会,我已经报名了。

美国NI公司将于2009年08月14日在东莞举办消费电子测试——开关电源测试专题免费技术研讨会。这次是中国电子工程科技网主办的,大家可以到http://www.360eet.com/em/dg0814/报名。以前参加过她们的会议,感觉很不错的哦。 要不是觉得论坛里的人好, ...…

查看全部问答∨

求助怎么计算其放大倍数

如题:       想请教各位大哥,如何具体计算其放大电路…

查看全部问答∨

如何进入单片机这行,前辈赐教

大家好: 小弟机电类本科毕业1年多了,现在决定从事单片机研发类工作,但是没有相关工作经验,也没项目经历,这样的情况应该怎样才能踏入这行,迈过这个门槛呢? 望前辈们赐教啊…

查看全部问答∨

建了个《Linux内核0.11完全注释/剖析》学习群:33261729 顺便散点分,呵呵!

首先声明我很菜的(业余时间正在自学保护模式和引导部分),以前学过点Win32 SDK/MFC,可惜从未有机会用过,目前做Window应用(C#.Net) 在Windows下做开发,总有种蒙蒙眬眬,说不清道不明的感觉,所以想看看Linux,希望能找到答案,当然也是从个 ...…

查看全部问答∨

基于ARM的水轮机组转速测量

摘要 :介绍了一种基于LPC2104微控制器及嵌入式实时操作系统 IzC/OS2的转速测量装置。说明其工作原理的同时,着重分析了测量精度;并就系统总体结构、硬件选择、txC/OS2的应用作了论述。 I  前言     频率 (转速)是电力 ...…

查看全部问答∨

加速度传感器mm7455资料,有程序,1602显示

有程序,1602显示X,Y,Z坐标,51单片机写的,不是我自己写的,别人的资料…

查看全部问答∨

eZdsp F2812的AD采样问题?

我使用的是eZdsp F2812,通过AD采样得到的值一直为零,请问各位大侠,是否这款开发板上的AD需要一些特殊的连接,或是其他的解决方案…

查看全部问答∨

字节对齐详解

一.什么是字节对齐,为什么要对齐?     现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved