📄 wnl.c
字号:
#include <REGX51.H>
#include "delay.h"
#include "type.h"
#include "1602.h"
#include "wnl.h"
#include "display.h"
#include "interupt.h"
extern uchar mode;
uchar ClkTickCtr; // 系统时钟计数器
uchar ClkHr; //小时计数器
uchar ClkMin; //分钟计数器
uchar ClkSec; //秒计数器
uchar ClkDay; //日期计数器
uchar ClkMonth; //月份计数器
uchar ClkYear; //年份计数器
uchar ClkDOW; //星期计数器
uchar Naozhong_Hr; //闹钟的小时
uchar Naozhong_Min; //闹钟的分钟
#define TICKS_PER_SEC 100 //每秒钟的节拍数,因为定计0溢出时间为10Ms,所以节拍为100
typedef struct clk_month
{
char MonthDays; // 每个月有多少天
UCHAR MonthVal; // 用来计算每月开始星期的参数
} CLK_MONTH;
static CLK_MONTH code ClkMonthTbl[] = // 天数、月份名、
{
{0 , 0},
{31, 6}, // 一月
{28, 2}, // 二月
{31, 2}, // 三月
{30, 5}, // 四月
{31, 0}, // 五月
{30, 3}, // 六月
{31, 5}, // 七月
{31, 1}, // 八月
{30, 4}, // 九月
{31, 6}, // 十月
{30, 2}, // 十一月
{31, 4} // 十二月
};
static char code *ClkDOWTbl[] = { //星期
"Sun ",
"Mon ",
"Tue ",
"Wed ",
"Thu ",
"Fri ",
"Sat "
};
void Sys_clk_task (void) //时钟任务
{
if(++ClkTickCtr==TICKS_PER_SEC) //每秒检查
{
ClkTickCtr=0;
//(P3_4) = !(P3_4);
if (ClkUpdateTime() == TRUE) //检查时间变化
{
ClkUpdateDate(); //检查日期变化
}
}
}
//@@***********************************************************
//
// 功能: 系统时钟中断服务函数
// 函数: void Sys_tick_isr(void)
// 语言: C
//
//@@***********************************************************
//-------------------------------------------------------------
void Sys_tick_isr(void) interrupt 1 using 3 //定计0中断服务程序,使用第三组寄存器
{
TH0 = 0xD8 ; //TH0 TL0 要实现10ms的计时
TL0 = 0xF0 ;
Sys_clk_task();
}
//@@***********************************************************
//
// 功能: 系统定时器初始化
// 函数: void Vtimer_init(void)
// 语言: C
//@@***********************************************************
//-------------------------------------------------------------
void Init_sys_timer(void)
{
Sys_clk_init();
TCON=0x05; //外部中断下降沿触发,响应外部和定计溢出中断后硬件置1,CPU响应后硬件清0
//TCON定时器/计数器控制寄存器
//D7 D6 D5 D4 D3 D2 D1 D0
//TF1 TF0 IE1 IT1 IE0 IT0
TMOD&=0xF0; //清定时器0的工作方式
//TMOD定时器/计数器的方式控制寄存器
//D7 D6 D5 D4 D3 D2 D1 D0
//GATE C/T M1 M0 | GATE C/T M1 M0
//----T/C 1---------|-------T/C 0------//
TMOD|=0x01; //工作方式为十六位定计器,需要重装载
TH0 = 0xD8 ; //TH0 TL0 要实现100ms的计时
TL0 = 0xF0 ;
EA=1; //全局中断开
EX0=1; //外部中断0开
EX1=1; //外部中断1开
ET0=1; //定计0允许中断
TR0=1; //启动定计0开始定时
}
void Sys_clk_init (void) //系统时钟、日期初始化
{
ClkTickCtr = 0;
Clk_set_time(14,50,0);
Clk_set_date(7,5,18);
Clk_set_naozhong(7,30);
}
void Clk_format_date (void) //日期格式检查子程序
{
uchar year = ClkYear;
real_date[0] = year / 10 + '0';
real_date[1] = year % 10 + '0';
real_date[2] = '-';
real_date[3] = ClkMonth / 10 + '0'; // Convert DATE to ASCII
real_date[4] = ClkMonth % 10 + '0';
real_date[5] = '-';
real_date[6] = ClkDay / 10 + '0';
real_date[7] = ClkDay % 10 + '0';
}
void Clk_format_time (uchar mode) //时间格式检查子程序
{
UCHAR hr;
switch (mode)
{
case 0: // 24小时制显示
real_time[0] = ClkHr / 10 + '0';
real_time[1] = ClkHr % 10 + '0';
real_time[2] = ':';
real_time[3] = ClkMin / 10 + '0';
real_time[4] = ClkMin % 10 + '0';
real_time[5] = ':';
real_time[6] = ClkSec / 10 + '0';
real_time[7] = ClkSec % 10 + '0';
real_time[8] = '-';
real_time[9] = '-';
break;
case 1: // 12小时制显示
real_time[8] = (ClkHr >= 12) ? 'P' : 'A'; //24转12小时
if (ClkHr > 12)
{
hr = ClkHr - 12;
}
else
{
hr = ClkHr;
}
real_time[0] = hr / 10 + '0';
real_time[1] = hr % 10 + '0';
real_time[2] = ':';
real_time[3] = ClkMin / 10 + '0';
real_time[4] = ClkMin % 10 + '0';
real_time[5] = ':';
real_time[6] = ClkSec / 10 + '0';
real_time[7] = ClkSec % 10 + '0';
real_time[9] = 'M';
break;
}
}
uchar ClkUpdateTime (void) //时钟子程序
{
uchar newday;
newday = FALSE; // 保证不会增加日期
if (ClkSec >= 59)
{
ClkSec = 0; //每分钟60秒
if (ClkMin >= 59)
{
ClkMin = 0; //每小时60分钟
if (ClkHr >= 23)
{
ClkHr = 0; //每天24小时
newday = TRUE; //日期可以增加了
}
else
{
ClkHr++; //小时自加
}
}
else
{
ClkMin++; //分钟自加
}
}
else
{
ClkSec++; //秒自加
}
return (newday);
}
uchar ClkIsLeapYear(UINT year) //闰年检查子程序
{
if (!(year % 4) && (year % 100) || !(year % 400))
{
return (TRUE); //可以被4整除为闰年
}
else
{
return (FALSE);
}
}
void Clk_set_time (UCHAR hr, UCHAR min, UCHAR sec) //设置时间子程序
{
EA=0;
ClkHr = hr;
ClkMin = min;
ClkSec = sec;
EA=1;
}
void Clk_set_date ( uchar year,UCHAR month, UCHAR day) //设置日期子程序
{
EA=0;
ClkYear = year;
ClkMonth = month;
ClkDay = day;
ClkUpdateDOW();
EA=1;
}
void Clk_set_naozhong (uchar hr,uchar min)
{
EA = 0;
Naozhong_Hr = hr; //闹钟的小时
Naozhong_Min = min; //闹钟的分钟
EA = 1;
}
void ClkUpdateDate (void)
{
uchar newmonth;
if (ClkDay >= ClkMonthTbl[ClkMonth].MonthDays) //检查是否每月的最后一日
{
if (ClkMonth == 2) //检查是否是二月
{
if (ClkIsLeapYear(ClkYear) == TRUE) //检查是否闰年
{
if (ClkDay >= 29) //检查是否二月最后一日
{
ClkDay = 1;
newmonth = TRUE; //日期变为三月的第一日
}
else
{
ClkDay++;
newmonth = FALSE;
}
}
else
{
ClkDay = 1;
newmonth = TRUE;
}
}
else
{
ClkDay = 1;
newmonth = TRUE;
}
}
else
{
ClkDay++;
newmonth = FALSE;
}
if (newmonth == TRUE) //是否新的一个月
{
if (ClkMonth >= 12) //是否十二月
{
ClkMonth = 1; //十二月
ClkYear++; //年份加1
}
else
{
ClkMonth++; //非十二月,月份加1
}
}
ClkUpdateDOW(); //计算星期
}
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -