基于51单片机的倒计时器设计

发布者:码农闲散人最新更新时间:2015-07-22 来源: 51hei关键字:51单片机  倒计时器 手机看文章 扫描二维码
随时随地手机看文章
//  本程序的电路很简单就不画图了,就是8位数码管的段选接在P0口,
//为了节约端口8个位接在了74hc138上,由P2.1 P2.0 P2.2控制译码器输出位选.
//本程序完全测试通过.完整代码下载地址: http://www.51hei.com/f/djsq.rar 
/************************************************************************/
/************8位数码管倒计时显示 时间格式24—00—00~~00-00-00**************/
/************************************************************************/
#include
#define  uchar unsigned char
#define  uint  unsigned int
                        
sbit D0=P2^0;                         //定义数码管片选参数
sbit D1=P2^1;
sbit D2=P2^2;
sbit D3=P1^2;       //定义蜂鸣器输出引脚
#define  CLOCK_NUM    4      //动态定义闹钟的个数
struct SAVE_TIME {
 uint save_hour;
 uint save_minute;
 uint save_second;
};
void key_scan_pro(void);
void Displaypro(void);
void Print_play_pro(void);
struct SAVE_TIME save_time[CLOCK_NUM]={0};
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};        //共阴极数码管0—9
uchar StrTab[8];                                  //定义缓冲区
static uint  minute=0,hour=24,second=0;                //定义并初始化为 24:00:00
static uchar num=0;               
static uchar temp,count1=1;
static uchar time_save_value=0;
void delay(uint z)                           //按键消抖延时函数
{
 uint x,y;
    for(x=z; x>0; x--)
  for(y=110; y>0; y--);
}
void hour_add_pro(void)               //小时加一减一处理函数 KEY0
{
 if(24==hour)  { hour=24; minute=0; second=0; } //小时为24时,将分钟和秒置零
 else    { hour++;  }
 Displaypro();
}
void hour_sub_pro(void)             //KEY1
{
 if(0==hour)   { hour=0; }
 else      { hour--; }
    Displaypro();
}
void minute_add_pro(void)            //分钟加一减一处理函数 KEY2
{
 if(59==minute)  { minute=59; }
 else    
 {
  if((24==hour)&&(minute==0)){}     //分钟边界压力判断,当24:00:00,不允许往上加
  else            { minute++; }  
 }
    Displaypro();
}
void minute_sub_pro(void)             //KEY3
{
 if(0==minute)  { minute=0; }
 else     { minute--; }
 Displaypro();
}
void second_add_pro(void)                //秒加一减一处理函数  KEY4
{
  if(60==second)  { second=60; }
     else               //秒边界压力判断 当24:00:00,不允许往上加
  { 
   if((24==hour)&&(minute==0)) {}
  else     { second++; } 
  }
  Displaypro();
}      
void second_sub_pro(void)           //KEY5
{
 if(0==second)  { second=0; }
 else    { second--; }
    Displaypro();
}
void begin_suspend_pro(void)             //开始/暂停处理函数
{ TR0 ^=0x1; }
void time_save_pro(void)              //定时值保存函数
{
 if(time_save_value  {
  save_time[time_save_value].save_hour   = hour;
     save_time[time_save_value].save_minute = minute;
  save_time[time_save_value].save_second = second; 
  time_save_value++;
  if(CLOCK_NUM==time_save_value)        //循环调用闹钟
  { time_save_value=0; }                   
 }               
}
void clock_judge_pro(void)           //闹钟值判断函数
{
 uchar i;
 for(i=0; i< CLOCK_NUM; i++)
 { if((hour==save_time[i].save_hour)&&(minute==save_time[i].save_minute)&&(second==save_time[i].save_second))
 { TR0=0; TR1=1; } }
}
void time_init_pro(void)           //定时器初始化函数
{
   TMOD |=0x01;                      //定时器0  10ms  inM  crystal  用于计时
      TH0=0xd8;                          //定时器初值10ms
      TL0=0xf0;
      ET0=1;                             //定时器/计数器T0中断允许位
      TR0=0;                               //TCON寄存器的TR0位 1:启动T1/0 0:停止T1/0
      TMOD |=0x10;                       //定时器1用于处理蜂鸣器
      TH1=0xd8;                         //初值20ms
      TL1=0xf0;
      ET1=1;
      TR1=0;                             //定时器的允许位
      EA =1;                             //开总中断
}
/********************************主函数***************************************/
void main(void)
{
  time_init_pro();                //调用定时器初始化函数
     Displaypro();           //调用显示函数
  while(1)
  {
    key_scan_pro();         //不断扫描按键
  }
}
/********************************主函数***************************************/
void key_scan_pro(void)            //键盘扫描函数
{
  D3=1;
  Print_play_pro();                  //调用显示处理函数
  P1=0xfe; temp=P1; temp&=0xf0;
 
  while(temp!=0xf0)               //按键消抖
  {
   delay(6); temp=P1; temp&=0xf0;
   while(temp!=0xf0)
   {
    temp=P1;
    switch(temp)
    {
      case 0xee: num=0;
       hour_add_pro();         //按键0,1控制小时
      break;
      case 0xde: num=1;
       hour_sub_pro();
      break;
      case 0xbe: num=2;   //按键2,3控制分钟
       minute_add_pro();
      break;
      case 0x7e: num=3;
       minute_sub_pro();
      break;
      default:
      break;
     }
     while(temp!=0xf0)
     { temp=P1; temp&=0xf0; }
     delay(6);
     while(temp!=0xf0)
     { temp=P1; temp&=0xf0; }
    }   
   }
   P1=0xfd; temp=P1; temp&=0xf0;
   while(temp!=0xf0)
   {
    delay(6); temp=P1; temp&=0xf0;
    while(temp!=0xf0)
    {
     temp=P1;
     switch(temp)
     {
      case 0xed: num=4;          //按键4,5控制秒
        second_add_pro();
      break;
      case 0xdd: num=5;
       second_sub_pro();
      break;
      case 0xbd: num=6;     //按键6控制开始/暂停处理函数
          begin_suspend_pro(); 
      break;
      case 0x7d: num=7;     //按键7控制定时保存函数
       time_save_pro();
      break;
      default:
      break;
     }
     while(temp!=0xf0)
     { temp=P1; temp&=0xf0; }
     delay(6);
               while(temp!=0xf0)
     { temp=P1; temp&=0xf0; }
    } 
   }
}[page]
void Displaypro(void)
{
        StrTab[0]=tab[hour/10];             //存储小时
        StrTab[1]=tab[hour%10];
        StrTab[2]=0x40;                    //存储"-"
        StrTab[3]=tab[minute/10];                 //存储分钟
        StrTab[4]=tab[minute%10];
        StrTab[5]=0x40;                           //存储"-"
        StrTab[6]=tab[second/10];                 //存储秒
        StrTab[7]=tab[second%10];
}
 
void Print_play_pro(void)                 //动态扫描数码管
{
  D0=1; D1=1; D2=1;               //显示秒
  P0=StrTab[7];
  delay(3);
  
  D0=0;D1=1; D2=1;
  P0=StrTab[6];
  delay(3);
  D0=1;D1=0; D2=1;               //显示"-"
  P0=StrTab[5];
  delay(3);
  D0=0;D1=0;D2=1;                    //显示分
  P0=StrTab[4];
  delay(3); 
  
  D0=1;D1=1;D2=0;
  P0=StrTab[3];
  delay(3);        
  D0=0;D1=1;D2=0;                    //显示"-"
  P0=StrTab[2];      
  delay(3); 
  D0=1;D1=0;D2=0;                    //显示小时
  P0=StrTab[1];
  delay(3); 
  D0=0;D1=0;D2=0;
  P0=StrTab[0];
  delay(3); 
}
/*****************************定时器1中断*********************************/
void time1_isr(void) interrupt 3           //定时器1用来处理蜂鸣器
{
     static uint count = 1;          //位置待定
  TH1=0xd8;               //重入初值定时20ms
     TL1=0xf0;
  //Print_play_pro();       //抖动效果    
  count++;
  D3=0;          //产生闹钟方波
  if(200==count)
  {
   TR0=1;
   TR1=0;
   count=1;
   D3=1;
  }
}
/***************************定时器0中断**********************************/                                
void tim(void) interrupt 1       //定时器0用来处理倒计时
{
        static uchar count;            //定义内部局部变量
        TH0=0xd8;               //重新赋值
        TL0=0xf0;
        count++;
        switch (count)
        {
                case 80:Displaypro();break;     //隔一定时间调用显示处理
                default:break;
        }
        if (count==100)
        {   
    clock_judge_pro();    //定时时间判断
    count=0;
    
    if((0==minute)&&(second==0)) //倒计时值处理
    {
     if(0==hour)    { hour=0;    }
     else           { hour--;    }
     minute=60;
    }
    if(0==second)
    {
     if(0==minute)  { minute=59; }
     else           { minute-=1; }
    } 
    if(0==second)      { second=60; }
    else               { second-=1; }
       if((0==hour)&&(0==minute)&&(0==second)) //倒计时到00:00:00,结束倒计时
      { hour=0; minute=0; second=0; Displaypro(); TR0=0; }       
        }   
}
关键字:51单片机  倒计时器 引用地址:基于51单片机的倒计时器设计

上一篇:DS1302芯片+1602液晶显示
下一篇:16键计算器 c51实现

推荐阅读最新更新时间:2024-03-16 14:25

关于如何利用Keil C实现51单片机中断功能
直接访问寄存器和端口 定义 sfr P0 0x80 sfr P1 0x81 sfr ADCON; 0xDE sbit EA 0x9F 操作 ADCON = 0x08; P1 = 0xFF; io_status = P0 ; EA = 1; 在使用了interrupt 1 关键字之后,会自动生成中断向量 在 ISR中不能 与其他 后台循环代码 (the background loop code) 共享局部变量,因为连接器会复用 在RAM中这些变量的位置 ,所以它们会有不同的意义,这取决于当前使用的不同的函数复用变量对RAM有限的51来讲很重要。所以,这些函数希望按照一定的顺序执行 而不被中断。 void
[单片机]
51单片机实现数码管动态显示60~0
硬件电路原理图 元件清单 C语言程序 #include reg51.h unsigned char table ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管字符码 void show(unsigned char n); void delay(unsigned int k); void main() { unsigned char i; int j; while(1) { for(i=60;j=60,i 0;i--) while(j--) show(i); } } void show(unsigned char n) { P0=table ; P1
[单片机]
<font color='red'>51单片机</font>实现数码管动态显示60~0
51单片机定时器/计数器的四种工作方式简介
1 工作方式0 定时器 / 计数器 T0工作在方式0时,16位 计数器 只用了13位,即TH0的高8位和TL0的低5位,组成一个13位 定时器 /计数器。 1)、工作在定时方式 2)、工作在计数方式 2 工作方式1 定时器T0工作方式1与工作方式0类同,差别在于其中的计数器的位数。工作方式0以13位计数器参与计数,工作方式1则以16位计数器参与计数。 1)、工作在定时方式 2)、工作在计数方式 工作方式1是16位计数器。这是工作方式1与工作方式0在计数方式时唯一差别。 3 工作方式2 定时器T0在工作方式2时,16位的计数器分成了两个独立的8位计数器TH0和TL0。 1)、工作在定时方式 2)、工作在计数方式 工作方式2与
[单片机]
51单片机定时器设置入门 (STC89C52RC)
51单片机定时器设置入门 (STC89C52RC) STC单片机定时器设置 STC单片机定时器的使用可以说非常简单,只要掌握原理,有一点的C语言基础就行了。要点有以下几个: 1. 一定要知道英文缩写的原形,这样寄存器的名字就不用记了。 理解是最好的记忆方法。好的教材一定会给出所有英文缩写的原形。 2.尽量用形像的方法记忆 比如TCON和TMOD两个寄存器各位上的功能,教程一般有个图表,你就在学习中不断回忆那个图表的形像 TMOD:定时器/计数器模式控制寄存器(TIMER/COUNTER MODE CONTROL REGISTER)    定时器/计数器模式控制寄存器TMOD是一个逐位定义的8位寄存
[单片机]
基于51单片机的锅炉水位温度压力检测系统仿真设计
仿真图proteus7.8及以上 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:S0056 1.主要功能: 基于51单片机AT89C51/52(与AT89S51/52、AT89C51/52、STC89C51/52等51内核单片机通用) 1.系统实时通过LCD1602显示水位检测值,锅炉炉膛温度值,锅炉内部压力值。 2、可对锅炉的水位上下限、炉膛温度上下限、压力上下限进行设置,第一行显示上限值,第二行显示下限值。 3、如果水位、温度、压力过限则蜂鸣器报警,通过LED指示报警类型。 4、默认水位下限值10cm,上限值40cm,压力下限值30kPa,压力上限值50kPa,温度下限值5℃,温度上限值105℃。 5、温
[单片机]
基于<font color='red'>51单片机</font>的锅炉水位温度压力检测系统仿真设计
51单片机内部EEPROM的应用
STC89C51、52内部都自带有2K字节的EEPROM,54、55和58都自带有16K字节的EEPROM,STC单片机是利用IAP技术实现的EEPROM,内部Flash擦写次数可达100,000 次以上,先来介绍下ISP与IAP的区别和特点。 ISP:In System Programable 是指在系统编程,通俗的讲,就是片子已经焊板子上,不用取下,就可以简单而方便地对其进行编程。比如我们通过电脑给STC单片机下载程序,或给AT89S51单片机下载程序,这就是利用了ISP技术。 IAP:In Application Programable 是指在应用编程,就是片子提供一系列的机制(硬件/软件上的)当片子在运行程序的时候可以
[单片机]
浅谈C8051单片机在变风量空调控制系统中的应用
1、前言:   变风量(Variable Air Volume, 简称VAV)空调系统是通过变风量箱去调节送入房间的风量和新回风混合比,并相应调节空调机组的风量或新回风混合比来控制某一空调区域温度的一种空调系统。变风量空调系统可以根据空调载荷的变化及室内要求参数的改变,自动调节空调送风量(达到最小送风量时调节送风温度),以满足室内人员的舒适要求或者其它的工艺要求。同时根据实际送风量自动调节送风机的转速,最大限度的减少风机动力、节约能量。与定风量空调系统相比,变风量空调系统具有节能性、舒适性、环保性、灵活性等优点。 2、硬件电路设计   2.1、风阀与水阀执行电路的设计   本控制器将温度、湿度、CO 2 传感器检测到的模拟
[单片机]
51单片机C语言学习笔记4:keil C51绝对地址访问
在利用keil进行8051单片机编程的时,常常需要进行绝对地址进行访问.特别是对硬件操作,如DA AD 采样 ,LCD 液晶操作,打印操作.等等. C51提供了三种访问绝对地址的方法: 1. 绝对宏: 在程序中,用 #include absacc.h 即可使用其中定义的宏来访问绝对地址,包括: CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD 具体使用可看一看absacc.h便知 例如: #include absacc.h #define ADstart XBYTE //总线方式访问AD #define ADL XBYTE #define ADH
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved