📄 5.3-2.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 + -