设计方案
设计基于LCD1602的多功能秒表,要满足在不间断计时的同时进行其他操作,由此可以联想出定时器的中断系统是其最好的选择。通过定时器中断函数的设计,可以让程序每隔一段时间进行一次计数,让LCD1602在不间断显示时间的同时,进行按键检测与计时的需要。
在代码具体时间中,为了避免代码过长、累赘、麻烦,本小组使用了模块化编程的思想,将定时器延迟函数、LCD1602操作函数、按键检测函数、延迟函数分别进行了模块化处理,这样不仅可以让主函数代码简短不少,而且可以使逻辑思维更加清晰,不再受基础函数的改动而烦恼。
在设计日历功能时,考虑到实际的电子表在平常状态下,不论是计时还是闹钟模式,日历中的时间计数都是未曾中断的,因此设计日历模式函数时,一旦日历模式被首次进入,日历中的计时就不会停止,除非重新设定日历时间。而在设定日历模式中,由于能力的不足与串口的关联性太强,本小组采用了让其在旁显示操作第几位的做法,用另一种方法,让操作者可以清晰的知道自己正在更改日历中的哪个数值。借鉴于日历模式是电子表的中心,本小组将其他模式的接口统统通向日历模式,这样在日历模式下,可以随意进入任意一个其他模式中。
在设计计时模式时,考虑到真正的电子表都有开始/暂停按键,所以本小组也参照该设计,设计了一个按键控制计时的开始与暂停。并且根据题目要求设计出了一个清零并暂停的按键满足题目需要。再次由于题目的需求,本小组设计出了检查保存结果模式,来检查可被保存的五次时间。考虑到真正的电子表和实际的按键数量,本小组并未在日历函数中安装此功能,而是将该模式接口移动到计时模式上,并且由于单片机内存有限,故酌情考虑设计了5个保存时间。
在设计倒计时模式时,由于题目本身的需要,本小组决定让操作者自己先设定倒计时的时间,再进行倒计时操作,这样能增加倒计时模式的可用性。倒计时模式仍支持检查保存结果模式,因为倒计时模式的底层逻辑与计时模式基本相同,区别在于倒计时模式可以自己设定倒计时的初始时间,而计时模式将这一功能代替为开始/暂停。倒计时模式的设定模式与日历设定模式的底层原理相同。倒计时模式与计时模式的保存结果是公用的,一是为了防止代码过长导致的操作繁琐与累赘,二是考虑到单片机的内存大小实在有限。
在设计检查保存结果模式中,设计了5个可被保存的时间。由于独立按键的缺少与代码实现的复杂度,只设计了其能一键全部清零的功能。其功能相对单一,并且只提供了前往日历功能的接口,因为日历功能下,可以前往其他任意功能,可以增加便捷性。
在实际代码中,发现日历功能、计时功能、倒计时功能的计时可能可以并被允许同时进行,故在定时器中断函数中本小组设计了3个标志变量来检查其是否能被统计计数.因为实际使用中,并不能保证程序从整毫秒开始计时,并且计时与倒计时要求的精度都比较高,所以才采用了此种方法,来保证3个功能能同时在后台进行。
总结来说,在具体实现上,代码保证的基本原则就是统一性原则,这样利于编程者的编程方便,也利于后来人的代码阅读理解,代码风格的同一可以让逻辑更加清晰,使得代码更加可读,也让该程序更好实现。
ps.51单片机的运行不太理想啊,它它它它……有点慢啊,可能是我的中断函数里写的语句太多了,不论怎么样,这其实是一个学习性的代码,参考即可啦(* ̄3 ̄)╭
MatrixKey.h
#ifndef __MATRIXKEY_H__
#define __MATRIXKEY_H__
unsigned char MatrixKey();
#endif
MatrixKey.c
#include<reg51.h>
#include<Delayms.h>
/**
* @brief 3*4矩阵键盘读取按键键码
* @param 无
* @retval KeyNumber 按下按键的键码值
如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0
*/
unsigned char MatrixKey(){
unsigned char KeyNumber=0;
P3=0xFF;
T1=0;
if(RXD==0){ Delayms(20); while(RXD==0); Delayms(20); KeyNumber=1; }
if(TXD==0){ Delayms(20); while(TXD==0); Delayms(20); KeyNumber=4; }
if(INT0==0){ Delayms(20); while(INT0==0); Delayms(20); KeyNumber=7; }
if(INT1==0){ Delayms(20); while(INT1==0); Delayms(20); KeyNumber=10; }
P3=0xFF;
WR=0;
if(RXD==0){ Delayms(20); while(RXD==0); Delayms(20); KeyNumber=2; }
if(TXD==0){ Delayms(20); while(TXD==0); Delayms(20); KeyNumber=5; }
if(INT0==0){ Delayms(20); while(INT0==0); Delayms(20); KeyNumber=8; }
if(INT1==0){ Delayms(20); while(INT1==0); Delayms(20); KeyNumber=11; }
P3=0xFF;
RD=0;
if(RXD==0){ Delayms(20); while(RXD==0); Delayms(20); KeyNumber=3; }
if(TXD==0){ Delayms(20); while(TXD==0); Delayms(20); KeyNumber=6; }
if(INT0==0){ Delayms(20); while(INT0==0); Delayms(20); KeyNumber=9; }
if(INT1==0){ Delayms(20); while(INT1==0); Delayms(20); KeyNumber=12; }
return KeyNumber;
}
Delayms.h
#ifndef __DELAYMS_H__
#define __DELAYMS_H__
void Delayms(unsigned int x);
#endif
Delayms.c
void Delayms(unsigned int x) //@11.0592MHz
{
unsigned char i, j;
while(x--){
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
LCD1602.h
#ifndef __LCD1602_H__
#define __LCD1602_H__
//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
#endif
LCD1602.c
#include <REGX52.H>
//引脚配置:
sbit LCD_RS=P3^5;
sbit LCD_EN=P3^4;
//sbit LCD_RW;
#define LCD_DataPort P0
//函数定义:
/**
* @brief LCD1602延时函数,12MHz调用可延时1ms
* @param 无
* @retval 无
*/
void LCD_Delay()
{
unsigned char i, j;
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
/**
* @brief LCD1602写命令
* @param Command 要写入的命令
* @retval 无
*/
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
// LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602写数据
* @param Data 要写入的数据
* @retval 无
*/
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
// LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay();
LCD_EN=0;
LCD_Delay();
}
/**
* @brief LCD1602设置光标位置
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @retval 无
*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
/**
* @brief LCD1602初始化函数
* @param 无
* @retval 无
*/
void LCD_Init()
{
LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
LCD_WriteCommand(0x01);//光标复位,清屏
}
/**
* @brief 在LCD1602指定位置上显示一个字符
* @param Line 行位置,范围:1~2
* @param Column 列位置,范围:1~16
* @param Char 要显示的字符
* @retval 无
*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
LCD_SetCursor(Line,Column);
LCD_WriteData(Char);
}
/**
* @brief 在LCD1602指定位置开始显示所给字符串
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串
* @retval 无
*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!='\0';i++)
{
LCD_WriteData(String[i]);
}
}
/**
* @brief 返回值=X的Y次方
*/
int LCD_Pow(int X,int Y)
{
unsigned char i;
int Result=1;
for(i=0;i<Y;i++)
{
Result*=X;
}
return Result;
}
/**
* @brief 在LCD1602指定位置开始显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~65535
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:-32768~32767
* @param Length 要显示数字的长度,范围:1~5
* @retval 无
*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
unsigned char i;
unsigned int Number1;
LCD_SetCursor(Line,Column);
if(Number>=0)
{
LCD_WriteData('+');
Number1=Number;
}
else
{
LCD_WriteData('-');
Number1=-Number;
}
for(i=Length;i>0;i--)
{
LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
}
}
/**
* @brief 在LCD1602指定位置开始以十六进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~0xFFFF
* @param Length 要显示数字的长度,范围:1~4
* @retval 无
*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i,SingleNumber;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
SingleNumber=Number/LCD_Pow(16,i-1)%16;
if(SingleNumber<10)
{
LCD_WriteData(SingleNumber+'0');
}
else
{
LCD_WriteData(SingleNumber-10+'A');
}
}
}
/**
* @brief 在LCD1602指定位置开始以二进制显示所给数字
* @param Line 起始行位置,范围:1~2
* @param Column 起始列位置,范围:1~16
* @param Number 要显示的数字,范围:0~1111 1111 1111 1111
* @param Length 要显示数字的长度,范围:1~16
* @retval 无
*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=Length;i>0;i--)
{
LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
}
}
Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0_Init(void);
#endif
Timer0.c
#include<reg51.h>
/**
* @brief 定时器0初始化,1毫秒@11.0592MHz
* @param 无
* @retval 无
*/
void Timer0_Init(void){ //定时器初始化
//TMOD=0x01; //0000 0001 设置模式
TMOD&=0xF0; //把TMOD的低四位清零,高四位保持不变
TMOD|=0x01; //把TMOD的最低位置1,高四位保持不变
//不可位寻址寄存器 不能 将每一位单独赋值
// 可位寻址寄存器 能 将每一位单独赋值
TF0=0; //中断溢出标志位 TF0=1 表示 产生中断
TR0=1; //定时器是否开启
TL0=0x66;
TH0=0xFC;
ET0=1;
EA=1;
PT0=0;
}
/*
定时器中断函数模板
void Timer0_Routine() interrupt 1{
static unsigned int T0Count;
TL0=0x66;
TH0=0xFC;
++T0Count;
if(T0Count>=1000){
T0Count=0;
led1=~led1;
}
}
*/
mian.c
#include<reg51.h>
#include<Delayms.h>
#include<MatrixKey.h>
#include<LCD1602.h>
#include<Timer0.h>
sbit beep=P2^3;
unsigned char Min,Sec,Ms; //分,秒,毫秒
unsigned char CountFlag; //CountFlag --> 0 表示非计时状态,1 表示计时状态
unsigned char KeyNum; //矩阵键盘键码
unsigned char SaveMin[6],SaveSec[6],SaveMs[6],SaveCount,CheckCount;
unsigned int CYear=2020,CMonth=2,CDay=29,CHour=23,CMin=58,CSec=30,CFlag;
unsigned char CSettmp,CSettmp2,CSetFlag;
unsigned char DMin,DSec,DMs,DownFlag,Dtmp;
void StartMemu();
void TimeMode();
void CheckMode();
void CalendarMode();
void CountdownMode();
void CSettingMode();
void DownSetting();
void main(){
//初始化LCD1602和定时器----
LCD_Init();
Timer0_Init();
//-------------------------
while(1) StartMemu();
}
/**
* StartMemu 开始菜单
* s9(KeyNum=3) 日历功能
* s13(KeyNum=6) 计时功能
* s17(KeyNum=9) 倒计时功能
*/
void StartMemu(){
LCD_ShowString(1,1,"Work ");
LCD_ShowString(2,1,"For Contest ");
while(1){
KeyNum=MatrixKey();
if(KeyNum==3) CalendarMode();
if(KeyNum==6) TimeMode();
if(KeyNum==9) CountdownMode();
}
}
/**
* CalendarMode 日历模式
* s9(KeyNum=3) 更换模式(计时模式)
* s13(KeyNum=6) 更换模式(倒计时模式)
* s17(KeyNum=9) 更换模式(检查保存结果模式)
* s21(KeyNum=12) 更改日历
*/
void CalendarMode(){
CFlag=1;
CSetFlag=0;
LCD_ShowString(1,1," - - ");
LCD_ShowString(2,1," : : ");
while(1){
LCD_ShowNum(1,1,CYear,4);
LCD_ShowNum(1,6,CMonth,2);
LCD_ShowNum(1,9,CDay,2);
LCD_ShowNum(2,1,CHour,2);
LCD_ShowNum(2,4,CMin,2);
LCD_ShowNum(2,7,CSec,2);
KeyNum=MatrixKey();
if(KeyNum==3) TimeMode();
if(KeyNum==6) CountdownMode();
if(KeyNum==9) CheckMode();
if(KeyNum==12) CSettingMode();
}
}
/**
* CSettingMode 更改日历模式
* s9(KeyNum=3) 确认并返回日历模式
* s13(KeyNum=6) +1
* s17(KeyNum=9) -1
* s21(KeyNum=12) 换位
*/
void CSettingMode(){
CFlag=0;
CSetFlag=1;
CSettmp=1;
LCD_ShowString(2,10,"Setting");
while(1){
LCD_ShowNum(1,16,CSettmp,1);
LCD_ShowNum(1,1,CYear,4);
LCD_ShowNum(1,6,CMonth,2);
LCD_ShowNum(1,9,CDay,2);
LCD_ShowNum(2,1,CHour,2);
LCD_ShowNum(2,4,CMin,2);
LCD_ShowNum(2,7,CSec,2);
KeyNum=MatrixKey();
if(KeyNum==3) CalendarMode();
if(KeyNum==6){
if(CSettmp==1) ++CYear;
if(CSettmp==2){ ++CMonth; if(CMonth==13) CMonth=1; }
if(CSettmp==3){
++CDay;
if((CMonth==1|CMonth==3|CMonth==5|CMonth==7|CMonth==8|CMonth==10|CMonth==12)&&CDay==32) CDay=1;
if((CMonth==4|CMonth==6|CMonth==9|CMonth==11)&&CDay==31) CDay=1;
if(((CYear%4==0&&CYear%100!=0)||CYear%400==0)&&CMonth==2&&CDay==30) CDay=1;
if(!((CYear%4==0&&CYear%100!=0)||CYear%400==0)&&CMonth==2&&CDay==29) CDay=1;
}
if(CSettmp==4) CHour=(CHour+1)%24;
if(CSettmp==5) CMin=(CMin+1)%60;
if(CSettmp==6) CSec=(CSec+1)%60;
}
if(KeyNum==9){
if(CSettmp==1&&CYear) --CYear;
if(CSettmp==2){ --CMonth; if(CMonth==0) CMonth=12; }
if(CSettmp==3){
--CDay;
if((CMonth==1|CMonth==3|CMonth==5|CMonth==7|CMonth==8|CMonth==10|CMonth==12)&&CDay==0) CDay=31;
if((CMonth==4|CMonth==6|CMonth==9|CMonth==11)&&CDay==0) CDay=30;
if(((CYear%4==0&&CYear%100!=0)||CYear%400==0)&&CMonth==2&&CDay==0) CDay=29;
if(!((CYear%4==0&&CYear%100!=0)||CYear%400==0)&&CMonth==2&&CDay==0) CDay=28;
}
if(CSettmp==4){ --CHour; if(CHour==-1) CHour=23; }
if(CSettmp==5){ --CMin; if(CMin==-1) CMin=59; }
if(CSettmp==6){ --CSec; if(CSec==-1) CSec=59; }
}
if(KeyNum==12){ ++CSettmp; CSettmp2=0; if(CSettmp==7) CSettmp=1; }
}
}
/**
* RunMode 计时模式
* s9(KeyNum=3) 更换模式(检查保存结果模式)
* s13(KeyNum=6) 清零并暂停操作
* s17(KeyNum=9) 继续/暂停操作
* s21(KeyNum=12) 保存当前计时功能,可保存5个
*/
void TimeMode(){
//CountFlag=1;
LCD_ShowString(1,1," : : S: /5");
LCD_ShowString(2,1,"Now Timing ");
while(1){
LCD_ShowNum(1,1,Min,2);
LCD_ShowNum(1,4,Sec,2);
LCD_ShowNum(1,7,Ms,2);
LCD_ShowNum(1,14,SaveCount,1);
KeyNum=MatrixKey();
if(KeyNum==3) CheckMode();
if(KeyNum==6){ Min=Sec=Ms=0; CountFlag=0; }
if(KeyNum==9) CountFlag^=1;
if(KeyNum==12&&SaveCount<5){
++SaveCount;
SaveMin[SaveCount]=Min;
SaveSec[SaveCount]=Sec;
SaveMs[SaveCount]=Ms;
}
}
}
/**
* CountdownMode 倒计时模式
* s9(KeyNum=3) 更换模式(检查保存结果模式)
* s13(KeyNum=6) 清零并停掉蜂鸣器操作
* s17(KeyNum=9) 设定操作
* s21(KeyNum=12) 保存当前计时功能,可保存5个(与计时模式共用)
*/
void CountdownMode(){
LCD_ShowString(1,1," : : S: /5");
LCD_ShowString(2,1,"Now Downing ");
while(1){
LCD_ShowNum(1,1,DMin,2);
LCD_ShowNum(1,4,DSec,2);
LCD_ShowNum(1,7,DMs,2);
LCD_ShowNum(1,14,SaveCount,1);
if(DownFlag==1&&DMin==0&&DSec==0&&DMs==0){ DownFlag=0; beep=0; }
KeyNum=MatrixKey();
if(KeyNum==3) CheckMode();
if(KeyNum==6){
DMin=DSec=DMs=0; DownFlag=0; beep=1;
}
if(KeyNum==9) DownSetting();
if(KeyNum==12&&SaveCount<5){
++SaveCount;
SaveMin[SaveCount]=DMin;
SaveSec[SaveCount]=DSec;
SaveMs[SaveCount]=DMs;
}
}
}
/**
* DownSetting 倒计时设定
* s9(KeyNum=3) 确认并返回倒计时模式
* s13(KeyNum=6) +1
* s17(KeyNum=9) -1
* s21(KeyNum=12) 换位
*/
void DownSetting(){
beep=1;
DownFlag=0;
Dtmp=1;
LCD_ShowString(1,1," : : ");
LCD_ShowString(2,1,"Now DownSetting ");
while(1){
LCD_ShowNum(1,1,DMin,2);
LCD_ShowNum(1,4,DSec,2);
LCD_ShowNum(1,7,DMs,2);
LCD_ShowNum(1,16,Dtmp,1);
KeyNum=MatrixKey();
if(KeyNum==3){ DownFlag=1; CountdownMode(); }
if(KeyNum==6){
if(Dtmp==1){ ++DMin; if(DMin>99) DMin=0; }
if(Dtmp==2){ ++DSec; if(DSec>59) DSec=0; }
if(Dtmp==3){ ++DMs; if(DMs>99) DMs=0; }
}
if(KeyNum==9){
if(Dtmp==1){ --DMin; if(DMin==-1) DMin=99; }
if(Dtmp==2){ --DSec; if(DSec==-1) DSec=59; }
if(Dtmp==3){ --DMs; if(DMs==-1) DMs=99; }
}
if(KeyNum==12){ ++Dtmp; if(Dtmp>3) Dtmp=1; }
}
}
/**
* CheckMode 检查保存结果模式
* s9(KeyNum=3) 为更换模式(日历模式)
* s13(KeyNum=6) 上一个
* s17(KeyNum=9) 下一个
* s21(KeyNum=12) 全部清空
*/
void CheckMode(){
LCD_ShowString(1,1," : : C: / ");
LCD_ShowString(2,1,"Now Checking ");
if(SaveCount) CheckCount=1; else CheckCount=0;
while(1){
LCD_ShowNum(1,1,SaveMin[CheckCount],2);
LCD_ShowNum(1,4,SaveSec[CheckCount],2);
LCD_ShowNum(1,7,SaveMs[CheckCount],2);
LCD_ShowNum(1,14,CheckCount,1);
LCD_ShowNum(1,16,SaveCount,1);
KeyNum=MatrixKey();
if(KeyNum==3) CalendarMode();
if(KeyNum==6&&CheckCount>1&&SaveCount!=0) --CheckCount;
if(KeyNum==9&&CheckCount<SaveCount) ++CheckCount;
if(KeyNum==12){
SaveCount=0;
CheckCount=0;
}
}
}
void Timer0_Routine() interrupt 1{
static unsigned int T0Count;
static unsigned int CCount;
static unsigned int DownCount;
TL0=0x66;
TH0=0xFC;
if(DownFlag==1){
++DownCount;
if(DownCount>=10){
DownCount=0;
if(DMs) --DMs;
if(DMs==0&&(DSec||DMin)){
DMs=99;
if(DSec>0) --DSec;
else if(DSec==0&&DMin){
DSec=59;
--DMin;
}
}
}
}
//如果处于即使状态每隔10毫秒进行计时---
if(CountFlag==1){
++T0Count;
if(T0Count>=10){
T0Count=0;
++Ms;
if(Ms>99){
Ms=0;
++Sec;
if(Sec>59){
Sec=0;
++Min;
if(Min>99)
Min=0;
}
}
}
}
//-------------------------------------
//如果处于即使状态每隔1秒进行计时---
if(CFlag==1){
++CCount;
if(CCount>=1000){
CCount=0;
++CSec;
if(CSec>59){
CSec=0;
++CMin;
if(CMin>59){
CMin=0;
++CHour;
if(CHour>23){
CHour=0;
++CDay;
if(CMonth==12&&CDay==32){
CMonth=1; CDay=1;
++CYear;
}
if((CMonth==1|CMonth==3|CMonth==5|CMonth==7|CMonth==8|CMonth==10)&&CDay==32){
CDay=1;
++CMonth;
}
if((CMonth==4|CMonth==6|CMonth==9|CMonth==11)&&CDay==31){
CDay=1;
++CMonth;
}
if(((CYear%4==0&&CYear%100!=0)||CYear%400==0)&&CMonth==2&&CDay==30){
CDay=1;
++CMonth;
}
if(!((CYear%4==0&&CYear%100!=0)||CYear%400==0)&&CMonth==2&&CDay==29){
CDay=1;
++CMonth;
}
}
}
}
}
}
//-------------------------------------
}