C 8051微控制器在过去一年中的设置
我有一个关于日期、周一和一年的问题。我们知道,每4年的2月等于29天,其余的是28天。所以我尝试编写一些代码,让程序知道二月的哪一年等于28天或29天 下面是我的代码,我想问的是,有没有更简单、更简短的方法C 8051微控制器在过去一年中的设置,c,microcontroller,8051,keil,C,Microcontroller,8051,Keil,我有一个关于日期、周一和一年的问题。我们知道,每4年的2月等于29天,其余的是28天。所以我尝试编写一些代码,让程序知道二月的哪一年等于28天或29天 下面是我的代码,我想问的是,有没有更简单、更简短的方法 void Timer(void) interrupt 1 { if(start_timer == 1) { TF0 = 0; TH0 = 0xB1; TL0 = 0XE0; msec++; if(msec==100) { sec++; msec=0; } if(sec==6
void Timer(void) interrupt 1
{
if(start_timer == 1)
{
TF0 = 0;
TH0 = 0xB1;
TL0 = 0XE0;
msec++;
if(msec==100)
{
sec++;
msec=0;
}
if(sec==60)
{
min++;
sec=0;
}
if(min==60)
{
hour++;
min=0;
}
if(hour==24)
{
date++;
hour=0;
}
if(date== 30 && mon == 2 ( && year == 2016 || year == 2020 || year == 2024 ))
{
mon++;
date=1;
}
if(date== 29 && mon == 2 ( && year == 2015 || year == 2017 || year == 2018 || year == 2019|| year == 2021 || year == 2022 || year == 2023))
{
mon++;
date=1;
}
if(date==32 ( && mon == 1 || mon == 3 || mon == 5 || mon == 7 || mon == 9 || mon == 11))
{
mon++;
date=1;
}
if(date==31 ( && mon == 4 || mon == 6 || mon == 8 || mon == 10 || mon == 12))
{
mon++;
date=1;
}
if(mon==13)
{
sec = 0;
min = 0;
hour = 0;
date = 1;
mon = 1;
year = year++;
}
}
}
更新:
void Timer(void) interrupt 1 {
static const int daymon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int daysinmon, leapyear;
if (start_timer == 1) {
TF0 = 0;
TH0 = 0xB1;
TL0 = 0XE0;
msec++;
if (msec >= 100) {
msec -= 100;
if (++sec >= 60) {
sec -= 60;
if (++min >= 60) {
min -= 60;
if (++hour >= 24) {
hour -= 24;
daysinmon = daymon[mon-1];
if (mon == 2) { // months 1-based
if (year % 4 == 0)
leapyear = 1;
else if (year % 100 != 0)
leapyear = 0;
else if (year % 400 == 0)
leapyear = 1;
else leapyear = 0;
if (leapyear == 1)
daysinmon++;
}
if (++date > daysinmon) {
date = 1; // days 1-based
if (++mon > 12) {
mon = 1;
year++;
}
}
}
}
}
}
}
}
也许如果((2000年)%4==0)
更能证明未来
编辑:是的,因为它将在2100年失败,但这将是其他人的问题。对于闰年
if ((year & 3) == 0) ...
if ((year & 3) != 0) ...
非闰年
if ((year & 3) == 0) ...
if ((year & 3) != 0) ...
编辑:
&是一个按位和。二进制
0000 & 0011 = 0000
0001 & 0011 = 0001
0010 & 0011 = 0010
0011 & 0011 = 0011
0100 & 0011 = 0000
当一个数字可被4整除时,带3的按位and将得到0。你不必担心2100年、2200年或2300年,除非你希望你的硬件在未来几个世纪都能很好地使用。也许你想要确定闰年的一般规则 要确定一年是否为闰年,请执行以下步骤:
1.如果年份可以被4整除,请转至步骤2。否则,请转至步骤5
2.如果年份可以被100整除,请转至步骤3。否则,请转至步骤4。
3.如果年份可以被400整除,请转至步骤4。否则,请转至步骤5。
4.这一年是闰年(有366天)。
5.年份不是闰年(有365天)。
确定闰年的代码通用方法可以是
uint8 leapYearTest(uint16 year) {
if ( year % 4 == 0)
{if ( year % 100 == 0)
if (year % 400 == 0)
return true;
}
else
return false;
return false;
}
上述代码可以缩短为一行,如下所示:
if ( (year%400==0)|| ((year%4==0) && (year%100!=0)))
return true;
else
return false;
然后可以根据函数返回的结果增加日期
if (mon==2)
{
date = (date+1)%(leapYearTest(year)+28);
}
我怀疑该算法可以通过预处理完成 您给了中断处理程序太多的工作要做,每次中断都要检查所有内容。我也做了一些其他的改变,也许不是必要的,但更强大,以检查调整时,每个元素包装。未来对代码的修改可能会看到中断功能本身中断,或者被更高优先级的中断延迟 编辑日期和月份现在以1为基础,以避免混淆
void Timer(void) interrupt 1 {
static const int daymon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int daysinmon, leapyear;
if (start_timer == 1) {
TF0 = 0;
TH0 = 0xB1;
TL0 = 0XE0;
msec++;
// and now you could re-enable interrupts to make it re-entrant
if (msec >= 1000) { // altered to 1000, and the conditional test
msec -= 1000;
if (++sec >= 60) {
sec -= 60;
if (++min >= 60) {
min -= 60;
if (++hour >= 24) { // the last time we adjust rather than zero
hour -= 24;
daysinmon = daymon [mon];
if (mon == 2) {
if (year % 400 == 0)
leapyear = 1;
else if (year % 100 == 0)
leapyear = 0;
else if (year % 4 == 0)
leapyear = 1;
else leapyear = 0;
if (leapyear)
daysinmon++;
}
if (++date > daysinmon) {
date = 1;
if (++mon > 12) {
mon = 1;
year++;
}
}
}
}
}
}
样本测试输出:
27 2 2000
28 2 2000
29 2 2000
1 3 2000
您是否正在使用MCU时钟计算日期和时间?我希望你的钟不是标准的。标准的MCU时钟非常不准确,在不到一个月的时间里,你经常会漂移超过一天。不要使用MCU时钟。基本上,我使用定时器中断,这就是我要说的。计时器使用MCU时钟,除非您的计时器是外部RTC。您真的在一秒钟内有100<代码>毫秒代码>吗?但我仍然必须输入我的月份,对吗?对于我这一年,我设置unsigned int=2015谢谢你的解释我尝试了上面的代码,只是2月份没有改变。我所做的是,我设置日期=28,周一=2,年份=2015。23:59:59. 当计时器达到00:00:00时,我设置28-2-2000时,它将日期增加到29,只是为了与您核对。下一个增量应该是29-2-2000,但它更改为01-03-2000,这是因为我将月份和日期都设置为零。如果(++date>=daysinmon){date=0;..可以更改为
如果(++date>daysinmon){date=1;..
您是否也将=
更改为
?我将其编译为一个从main()
调用一次的测试函数,我发现它可以测试闰年27-1-2000。它滚动到了28-1-2000(从零开始)然后到0-2-2000Oh!我将=
更改为
是的,正在工作。谢谢。我感谢您的帮助