⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.c

📁 用89C51做的一个简单的电子钟
💻 C
字号:
/*
 timer.c file
 Created by Computer-lov. Date: 2005.5.31
 Last edited date:2005.5.31
 Copyright (c) 2005 Computer-lov
 version 1.0
 All rigths reserved
 欢迎访问我的blog:  http://computer00.21ic.org
*/

#include "timer.h"
#include "main.h"
#include "keyboard.h"
#include "led.h"

unsigned char display_buffer[6];        //显示缓冲区

unsigned char second,minute,hour,day,month,year;  //分别保存秒、分、时、天、月、年的变量
unsigned char n_50m_second;             //保存多少个50毫秒的变量
unsigned char days_of_month;            //保存该月多少天的变量

void timer0_isr(void) interrupt 1 using 1      //定时器0中断处理函数
{
 TL0=0xB9;
 TH0=0x3C;                              //定时器重装。定时50mS中断一次
 n_50m_second++;
 if(n_50m_second>=20)                  //1秒到
  {
   n_50m_second=0;                     //清50毫秒计数
   second++;                           //秒加1
   if(second==60)                      //如果秒到60
    {
     second=0;                         //秒清0
     minute++;                         //分加1
     if(minute==60)                    //如果分到60
      {
       minute=0;                       //分清0
       hour++;                         //小时加1
       if(hour==24)                    //如果小时到24
        {
         hour=0;                       //小时清零
         day++;                        //天加1
         if(day>days_of_month)         //如果天大于本月最后一天
          {
           day=1;                      //天置1
           month++;                    //月加1
           if(month>12)                //如果月大于12
            {
             month=1;                  //月置1
             year++;                   //年加1
             if(year>=100)             //如果年大于100
              {
               year=0;                 //年清零
              }
            }
          }
        }
      }
    }
  } 
}

#define NORMAL       0
#define SECOND_ADJ   1
#define MINUTE_ADJ   2
#define HOUR_ADJ     3
#define DAY_ADJ      4
#define MONTH_ADJ    5
#define YEAR_ADJ     6

#define STATUS_MIN   0
#define STATUS_MAX   6

unsigned char calculate_days(void)       //计算本月有多少天
{
 unsigned int temp;
 switch (month)
  {
   case 1:
   case 3:
   case 5:
   case 7:
   case 8:
   case 10:
   case 12:
           return 31;  //1、3、5、7、8、10、12月为31天
           break;
   case 4:
   case 6:
   case 9:
   case 11:            //4、6、9、11月为30天
           return 30;
           break;
   case 2:
           temp=2000+year; //因为year中保存的是年的最后两位,所以要加上2000
           if((((temp%4)==0)&&((temp%100)!=0))||((temp%400)==0))
            {
             return 29;    //闰年2月为29天
            }
           else
            {
             return 28;    //平年2月为28天
            }
  }
}

unsigned char flicker_time;     //闪烁频率
unsigned char display_on;       //显示开关标志。用来产生闪烁效果
unsigned char status;           //状态值
unsigned char display_date;     //是否是显示日期

void timer(void)
{
 if(key==KEY_FUNCTION)          //如果功能键按下
  {
   if(status<STATUS_MAX)status++;   //如果状态值小于对大状态,则状态值加1
   else status=STATUS_MIN;          //否则,状态值置最小状态值
   key=0;                           //清键值
  }
 days_of_month=calculate_days();    //计算本月天数
 switch (status)
  {
   case NORMAL:                     //平常状态
    {
     if(key==KEY_UP)                //如果上翻键按下,则显示日期
      {
       display_date=100;            //设置显示日期的时间
       key=0;
      }
     if(key==KEY_DOWN)             //如果下翻键按下,则显示时间
      {
       display_date=0;
       key=0;
      }
     if(display_date)              //如果是显示日期,则计算日期每位
      {
       display_buffer[5]=16+day%10;
       display_buffer[4]=day/10;
       display_buffer[3]=16+month%10;
       display_buffer[2]=month/10;
       display_buffer[1]=16+year%10;
       display_buffer[0]=year/10;
       display_date--;               //经过一定时间后,自动显示时间
      }
     else                            //如果是显示时间,则计算时间每位                     
      {
       display_buffer[5]=second%10;
       display_buffer[4]=second/10;
       display_buffer[3]=16+minute%10;
       display_buffer[2]=minute/10;
       display_buffer[1]=16+hour%10;
       display_buffer[0]=hour/10;
      }
       display(display_buffer);        //显示结果
       break;
    }
   case SECOND_ADJ:                  //秒调整状态
    {
     if(key==KEY_UP)               //上翻键按下,秒增加1
      {
       display_on=1;               //开显示,调整时能看清楚
       second++;
       if(second>=60)second=0;     //如果秒到60,则清0
       key=0;
      }
     if(key==KEY_DOWN)             //下翻键按下,秒减1
      {
       display_on=1;
       second--;
       if(second>=60)second=59;
       key=0;
      }
     display_buffer[5]=second%10;   //计算每位值
     display_buffer[4]=second/10;
     display_buffer[3]=16+minute%10;
     display_buffer[2]=minute/10;
     display_buffer[1]=16+hour%10;
     display_buffer[0]=hour/10;
     if(!display_on)             //如果关显示
      {
       flicker_time++;           //闪烁计时加1
       if(flicker_time>20){flicker_time=0;display_on=1;}   //如果闪烁计时到20,开显示
       display_buffer[5]=DISPLAY_OFF;
       display_buffer[4]=DISPLAY_OFF;
      }
     else                       //如果开显示
      {
       flicker_time++;           //闪烁计时加1
       if(flicker_time>30){flicker_time=0;display_on=0;}   //如果闪烁计时到20,关显示
      }
     display(display_buffer);
     break;
    }
   case MINUTE_ADJ:       //分调整状态
    {
     if(key==KEY_UP)
      {
       display_on=1;
       minute++;
       if(minute>=60)minute=0;
       key=0;
      }
     if(key==KEY_DOWN)
      {
       display_on=1;
       minute--;
       if(minute>=60)minute=59;
       key=0;
      }
     display_buffer[5]=second%10;
     display_buffer[4]=second/10;
     display_buffer[3]=16+minute%10;
     display_buffer[2]=minute/10;
     display_buffer[1]=16+hour%10;
     display_buffer[0]=hour/10;
     if(!display_on)
      {
       flicker_time++;
       if(flicker_time>20){flicker_time=0;display_on=1;}
       display_buffer[3]=DISPLAY_OFF;
       display_buffer[2]=DISPLAY_OFF;
      }
     else
      {
       flicker_time++;
       if(flicker_time>30){flicker_time=0;display_on=0;}
      }
     display(display_buffer);
     break;
    }
   case HOUR_ADJ:           //小时调整状态
    {
     if(key==KEY_UP)
      {
       display_on=1;
       hour++;
       if(hour>=24)hour=0;
       key=0;
      }
     if(key==KEY_DOWN)
      {
       display_on=1;
       hour--;
       if(hour>=24)hour=23;
       key=0;
      }
     display_buffer[5]=second%10;
     display_buffer[4]=second/10;
     display_buffer[3]=16+minute%10;
     display_buffer[2]=minute/10;
     display_buffer[1]=16+hour%10;
     display_buffer[0]=hour/10;
     if(!display_on)
      {
       flicker_time++;
       if(flicker_time>20){flicker_time=0;display_on=1;}
       display_buffer[1]=DISPLAY_OFF;
       display_buffer[0]=DISPLAY_OFF;
      }
     else
      {
       flicker_time++;
       if(flicker_time>30){flicker_time=0;display_on=0;}
      }
     display(display_buffer);
     break;
    }
   case DAY_ADJ:       //天调整状态
    {
     if(key==KEY_UP)
      {
       display_on=1;
       day++;
       if(day>days_of_month)day=1;
       key=0;
      }
     if(key==KEY_DOWN)
      {
       display_on=1;
       day--;
       if(day==0)day=days_of_month;
       key=0;
      }
     display_buffer[5]=16+day%10;
     display_buffer[4]=day/10;
     display_buffer[3]=16+month%10;
     display_buffer[2]=month/10;
     display_buffer[1]=16+year%10;
     display_buffer[0]=year/10;
     if(!display_on)
      {
       flicker_time++;
       if(flicker_time>20){flicker_time=0;display_on=1;}
       display_buffer[5]=DISPLAY_OFF;
       display_buffer[4]=DISPLAY_OFF;
      }
     else
      {
       flicker_time++;
       if(flicker_time>30){flicker_time=0;display_on=0;}
      }
     display(display_buffer);
     break;
    }
   case MONTH_ADJ:
    {
     if(key==KEY_UP)
      {
       display_on=1;
       month++;
       if(month>=13)month=1;
       days_of_month=calculate_days();
       if(day>days_of_month)day=days_of_month;
       key=0;
      }
     if(key==KEY_DOWN)
      {
       display_on=1;
       month--;
       if(month==0)month=12;
       days_of_month=calculate_days();
       if(day>days_of_month)day=days_of_month;
       key=0;
      }
     display_buffer[5]=16+day%10;
     display_buffer[4]=day/10;
     display_buffer[3]=16+month%10;
     display_buffer[2]=month/10;
     display_buffer[1]=16+year%10;
     display_buffer[0]=year/10;
     if(!display_on)
      {
       flicker_time++;
       if(flicker_time>20){flicker_time=0;display_on=1;}
       display_buffer[3]=DISPLAY_OFF;
       display_buffer[2]=DISPLAY_OFF;
      }
     else
      {
       flicker_time++;
       if(flicker_time>30){flicker_time=0;display_on=0;}
      }
     display(display_buffer);
     break;
    }
   case YEAR_ADJ:          //年天调整状态
    {
     if(key==KEY_UP)
      {
       display_on=1;
       year++;
       if(year>=100)year=0;
       days_of_month=calculate_days();
       if(day>days_of_month)day=days_of_month;
       key=0;
      }
     if(key==KEY_DOWN)
      {
       display_on=1;
       year--;
       if(year>=100)year=99;
       days_of_month=calculate_days();
       if(day>days_of_month)day=days_of_month;
       key=0;
      }
     display_buffer[5]=16+day%10;
     display_buffer[4]=day/10;
     display_buffer[3]=16+month%10;
     display_buffer[2]=month/10;
     display_buffer[1]=16+year%10;
     display_buffer[0]=year/10;
     if(!display_on)
      {
       flicker_time++;
       if(flicker_time>20){flicker_time=0;display_on=1;}
       display_buffer[1]=DISPLAY_OFF;
       display_buffer[0]=DISPLAY_OFF;
      }
     else
      {
       flicker_time++;
       if(flicker_time>30){flicker_time=0;display_on=0;}
      }
     display(display_buffer);
     break;
    }
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -