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

📄 5.3-2.c

📁 单片机应用开发实例.rar
💻 C
字号:
#define   SYS_CLOCK_EN  1
#if       SYS_CLOCK_EN

#include  "typedef.h"
#include  "reg52.h"
#include  "string.h"
#include  "stdlib.h"
#include  "Stdio.h"

#define   FOSC                    22118400L
#define   MACHINE_NUM           12          
#define   TICKS_PER_SEC           10       
#define   CLK_DATE_EN             1           // 1为数据标志 
#define   ENTER_CRITICAL()       EA=1
#define   EXIT_CRITICAL()         EA=0                         

#if CLK_DATE_EN
typedef struct clk_month 
{         
UCHAR  MonthDays;                        //每月天                               
char  *MonthName;                          //月名 
UCHAR  MonthVal;                         //每星期的天数名称                       
} CLK_MONTH;
#endif

static UCHAR   ClkTickCtr;                       //保持系统时钟轨迹
static UCHAR   ClkHr;
static UCHAR   ClkMin;
static UCHAR   ClkSec;                          //计算地区时间
#if    CLK_DATE_EN
static UCHAR   ClkDay;                         //计算地区日期
                                      
static UCHAR   ClkDOW;                       //每星期的天数(0 为星期天)
                                    
static UCHAR   ClkMonth;
static UINT    ClkYear;
#endif
      
static  BOOL       ClkUpdateTime(void);

#if     CLK_DATE_EN
static  BOOL     ClkIsLeapYear(UINT year);
static  void       ClkUpdateDate(void);
static  void       ClkUpdateDOW(void);
#endif

void   Init_sys_timer(void);
void   Sys_clk_init(void); 
void   Sys_clk_task(void);

void   Clk_format_time(UCHAR mode, char *s);
void   Clk_set_time(UCHAR hr, UCHAR min, UCHAR sec);
int    Cmp_now_time(UCHAR hr, UCHAR min, UCHAR sec);

#if    CLK_DATE_EN
void   Clk_format_date(UCHAR mode, char *s);
void   Clk_set_date(UCHAR month, UCHAR day, UINT year);
void   Clk_set_date_time(UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec);
int    Cmp_now_date_time(UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec);
#endif

#if CLK_DATE_EN
static  char code *ClkDOWTbl[] = {                                       
    "Sunday ",
    "Monday ",
    "Tuesday ",
    "Wednesday ",
    "Thursday ",
    "Friday ",
    "Saturday "
};


static CLK_MONTH code ClkMonthTbl[] = {             // 月表                                               
{0,  "",         0},                        // 无效                                                
    {31, "January ",   6},                        // 1月                                                   
    {28, "February ",  2},                        // 2月               
    {31, "March ",    2},                        // 3月                                                       
    {30, "April ",     5},                        // 4月                                                        
    {31, "May ",      0},                        // 5月
{30, "June ",      3},                        // 6月
    {31, "July ",      5},                        // 7月 
{31, "August ",     1},                          // 8月 
{30, "September ",  4},                          // 9月
{31, "October ",    6},                          // 10月
{30, "November ",  2},                          // 11月
{31, "December ",  4},                         // 12月
};
#endif  

void  Sys_clk_task (void)
{
     if(++ClkTickCtr==TICKS_PER_SEC)   
      {
         ClkTickCtr=0;
                               
         if (ClkUpdateTime() == TRUE)
         {     
          #if CLK_DATE_EN
              ClkUpdateDate();                       // MM-DD-YY)    
          #endif
         }
      }   
}  

void Sys_tick_isr(void)  interrupt 5  using  3
{
    TF2=0;
    Sys_clk_task();  
    
}
//系统定时器初始化
void Init_sys_timer(void)
{
  BYTE_WORD Init_value; 

  Sys_clk_init();  
    
  T2CON=0x00;
  Init_value.word=FOSC/(TICKS_PER_SEC*MACHINE_NUM); 
  TH2=RCAP2H=-Init_value.bytes.high;
  TL2=RCAP2L=-Init_value.bytes.low;

  ET2=1;
  TR2=1;  	
  
  //TMOD&=0xF0;	           //使用定时器0,但在中断中需要重新赋初值
  //TMOD|=0x01;
  
 // Init_value.word=FOSC/(TICKS_PER_SEC*MACHINE_NUM); 
  //TH0=-Init_value.bytes.high;
  //TL0=-Init_value.bytes.low;

  //ET0=1;
  //TR0=1;
}

void  Sys_clk_init (void)
{
    ClkTickCtr = 0;
    Clk_set_time(11,32,0);
#if CLK_DATE_EN
    Clk_set_date(5,28,2002);
#endif    
}

#if  CLK_DATE_EN
void  Clk_format_date (UCHAR mode, char *s)
{
    UINT  year;
    char    str[5];
    
    switch (mode) 
       {
        case  1:
              strcpy(s, "MM-DD-YY");         
              s[0] = ClkMonth / 10 + '0';               //转换数据为ASCII                
              s[1] = ClkMonth % 10 + '0';
              s[3] = ClkDay   / 10 + '0';
              s[4] = ClkDay   % 10 + '0';
              year = ClkYear % 100;
              s[6] = year / 10 + '0';
              s[7] = year % 10 + '0';
              break;

        case  2:
        strcpy(s, ClkDOWTbl[ClkDOW]);               //得到每星期的天
  strcat(s, ClkMonthTbl[ClkMonth].MonthName);   //得到月名

              if (ClkDay < 10)
               {
                 str[0] = ClkDay + '0';
                 str[1] = 0;
               } 
              else
               {
                 str[0] = ClkDay / 10 + '0';
                 str[1] = ClkDay % 10 + '0';
                 str[2] = 0;
               }
              strcat(s, str);
              strcat(s, ", ");
              sprintf(str,"%d",ClkYear); 
              strcat(s, str);
              break;

        case  3:
              strcpy(s, "YYYY-MM-DD");            

              s[0] = year / 1000 + '0';
              year = year % 1000;
              s[1] = year /  100 + '0';
              year = year %  100;
              s[2] = year /   10 + '0';
              s[3] = year %   10 + '0';
              s[5] = ClkMonth / 10 + '0';        
              s[6] = ClkMonth % 10 + '0';
              s[8] = ClkDay   / 10 + '0';
              s[9] = ClkDay   % 10 + '0';
              break;

        default:
              strcpy(s, "?");
              break;
    }
}
#endif

void  Clk_format_time (UCHAR mode, char *s)
{
    UCHAR hr;
    switch (mode)
     {
        case  1:
              strcpy(s, "HH:MM:SS");    
              s[0] = ClkHr  / 10 + '0';  
              s[1] = ClkHr  % 10 + '0';
              s[3] = ClkMin / 10 + '0';
              s[4] = ClkMin % 10 + '0';
              s[6] = ClkSec / 10 + '0';
              s[7] = ClkSec % 10 + '0';
              break;

        case  2:
              strcpy(s, "HH:MM:SS AM");     
              s[9] = (ClkHr >= 12) ? 'P' : 'A';               
              if (ClkHr > 12) 
                {                                 // 调整显示时间  
                 */
                  hr   = ClkHr - 12;
                } 
              else
                {
                  hr = ClkHr;
                }
              s[0] = hr     / 10 + '0';                            
              s[1] = hr     % 10 + '0';
              s[3] = ClkMin / 10 + '0';
              s[4] = ClkMin % 10 + '0';
              s[6] = ClkSec / 10 + '0';
              s[7] = ClkSec % 10 + '0';
              break;

        default:
              strcpy(s, "?");
              break;
    }
}

static  BOOL  ClkUpdateTime (void)
{
    BOOL newday;
    
newday = FALSE;                     
whole day yet      */
    if (ClkSec >= 59)
     {                                             //假如1整分钟      
          ClkSec = 0;                                //Yes, clear seconds  
          if (ClkMin >= 59)
            {                                      //假如1整小时   

              ClkMin = 0;                           //清分钟                                   
              if (ClkHr >= 23) 
               {                                   //假如1整天
                 ClkHr = 0;                         //清小时
                 newday    = TRUE;                 //新1天的标志 
               } 
              else
               {
                ClkHr++;             
               }
            }
          else
           {
            ClkMin++;                
           }
     } 
    else
     {
        ClkSec++;                    
     }
    return (newday);
}

void  Clk_set_time (UCHAR hr, UCHAR min, UCHAR sec)
{
ENTER_CRITICAL();    
    ClkHr  = hr;
    ClkMin = min;
    ClkSec = sec;
EXIT_CRITICAL();    
}

#if CLK_DATE_EN
static  BOOL  ClkIsLeapYear(UINT year)
{
    if (!(year % 4) && (year % 100) || !(year % 400)) 
     {
        return TRUE;
     } 
    else 
     {
        return (FALSE);
     }
}
#endif

#if  CLK_DATE_EN
void  Clk_set_date (UCHAR month, UCHAR day, UINT year)
{
    ENTER_CRITICAL();                         
    ClkMonth = month;
    ClkDay   = day;
    ClkYear  = year;
    ClkUpdateDOW();                             
    EXIT_CRITICAL();                         
}
#endif

#if  CLK_DATE_EN
void  Clk_set_date_time (UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec)
{
ENTER_CRITICAL();    
    ClkMonth = month;
    ClkDay   = day;
    ClkYear  = year;
    ClkHr    = hr;
    ClkMin   = min;
    ClkSec   = sec;
ClkUpdateDOW();         
EXIT_CRITICAL();       

}
#endif

#if CLK_DATE_EN
static  void  ClkUpdateDate (void)
{
    BOOL newmonth;
    
    newmonth = TRUE;
if (ClkDay >= ClkMonthTbl[ClkMonth].MonthDays)
 {                                            //是月的最后1天?
        if (ClkMonth == 2) 
{                                                 // 2月?
            if (ClkIsLeapYear(ClkYear) == TRUE)
 {                                              // 闰月? 
                if (ClkDay >= 29) 
{                                              //是,昨天是2月 
                    ClkDay = 1;                 //3月1日
                } else
 {
                    ClkDay++;
                    newmonth = FALSE;
                }
            } else {
                ClkDay = 1;
            }
        } else {
            ClkDay = 1;
        }
    } else {
        ClkDay++;
        newmonth = FALSE;
    }
if (newmonth == TRUE) {              
        if (ClkMonth >= 12) {              
            ClkMonth = 1;           
            ClkYear++;              

        } else {
            ClkMonth++;           
        }
    }
ClkUpdateDOW();            

}
#endif

#if CLK_DATE_EN
static  void  ClkUpdateDOW (void)
{
    UINT dow;
    
    dow = ClkDay + ClkMonthTbl[ClkMonth].MonthVal;
    if (ClkMonth < 3)
    {
        if (ClkIsLeapYear(ClkYear)) 
        {
            dow--;
        }
    }
    dow    += ClkYear + (ClkYear / 4);
    dow    += (ClkYear / 400) - (ClkYear / 100);
    dow    %= 7;
    ClkDOW  = dow;
}
#endif

int Cmp_now_time(UCHAR hr, UCHAR min, UCHAR sec)
{
   if(ClkHr!=hr)
     return(hr-ClkHr);
   else if(ClkMin!= min) 
     return(min-ClkMin);   
   else
     return(sec-ClkSec);    
}

// 功能:  给定的时间与当前时间比较
// 函数:  int Cmp_now_date_time(UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec)

#if CLK_DATE_EN
int Cmp_now_date_time(UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec)
{
   if(ClkYear!=year)
       return(year-ClkYear);
   else if(ClkMonth!=month)
	   return(month-ClkMonth);
   else if(ClkDay!=day)
	   return(day-ClkDay);
   else if(ClkHr!=hr)
       return(hr-ClkHr);
   else if(ClkMin!= min) 
       return(min-ClkMin);   
   else
       return(sec-ClkSec);    
}
#endif
#endif


//CALENDER.H 

#ifndef _CALENDER_H_
#define _CALENDER_H_ 

#define CLK_DATE_EN          1                 
      
void   Sys_clk_init(void); 
void   Sys_clk_task(void);

void   Clk_format_time(UCHAR mode, char *s);
void   Clk_set_time(UCHAR hr, UCHAR min, UCHAR sec);
int    Cmp_now_time(UCHAR hr, UCHAR min, UCHAR sec);

#if    CLK_DATE_EN
void   Clk_format_date(UCHAR mode, char *s);
void   Clk_set_date(UCHAR month, UCHAR day, UINT year);
void   Clk_set_date_time(UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec);
int    Cmp_now_date_time(UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec);
#endif

#endif

//Typedef.h
#define   Max(x,y)                    ( (x)>(y) ? (x) : (y) ) 
#define   Min(x,y)                    ( (x)<(y) ? (x) : (y) )  

#define LongToBin(n) \
(\
((n >> 21) & 0x80) | \
((n >> 18) & 0x40) | \
((n >> 15) & 0x20) | \
((n >> 12) & 0x10) | \
((n >> 9) & 0x08) | \
((n >> 6) & 0x04) | \
((n >> 3) & 0x02) | \
((n ) & 0x01) \
)

#define Bin(n) LongToBin(0x##n##L)
#endif

⌨️ 快捷键说明

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