基于51单片机的万年历,用到了单片机独立键盘、数码管、LED灯模块实现。
想要简单还是DS1302好用。
1 /************************************************** 2 3 作者:纟彖氵戋 博客:http://www.cnblogs.com/yllinux/ 4 5 时间:2017年6月7日 6 7 目标:利用单片机独立键盘、数码管、LED灯模块实现万年历(算法实现) 8 9 ***************************************************/ 10 #include <reg52.h> 11 #define uchar unsigned char 12 #define uint unsigned int 13 14 uchar a[] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80 }; //字形码表0~9和. 15 uchar b[] = { 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff }; //数码管位码表1~8和0 16 uchar c[] = { 0x3f,0xf3,0xcf }; 17 uint year = 2100; 18 uchar month = 2, day = 14; 19 uchar hour = 8, minute = 40, second = 0; 20 uchar count; //时钟计数 21 uchar n = 1; //年月日调位指示 22 uchar j = 1; //时分秒调位指示 23 24 sbit Key1 = P3 ^ 0; //计时停止 25 sbit Key2 = P3 ^ 1; //调位 26 sbit Key3 = P3 ^ 2; //加一 27 sbit Key4 = P3 ^ 3; //切换 28 sbit LED1 = P1 ^ 0; //可删此灯,有冲突 29 sbit we = P2 ^ 7; 30 sbit du = P2 ^ 6; 31 32 void Delayms(uint z) 33 { 34 uint x, y; 35 for (x = 0; x < z; x++) 36 for (y = 0; y < 114; y++); 37 } 38 39 //时分秒显示函数 40 void Dispaly1(uchar hour, uchar minute, uchar second) 41 { 42 //数码管1 43 P0 = b[8]; 44 we = 1; 45 we = 0; 46 P0 = a[hour / 10]; 47 du = 1; 48 du = 0; 49 P0 = b[0]; 50 we = 1; 51 we = 0; 52 Delayms(1); 53 //数码管2 54 P0 = b[8]; 55 we = 1; 56 we = 0; 57 P0 = a[hour % 10]; 58 du = 1; 59 du = 0; 60 P0 = b[1]; 61 we = 1; 62 we = 0; 63 Delayms(1); 64 //数码管2小数点 65 P0 = b[8]; 66 we = 1; 67 we = 0; 68 P0 = a[10]; 69 du = 1; 70 du = 0; 71 P0 = b[1]; 72 we = 1; 73 we = 0; 74 Delayms(1); 75 //数码管3 76 P0 = b[8]; 77 we = 1; 78 we = 0; 79 P0 = a[minute / 10]; 80 du = 1; 81 du = 0; 82 P0 = b[2]; 83 we = 1; 84 we = 0; 85 Delayms(1); 86 //数码管4 87 P0 = b[8]; 88 we = 1; 89 we = 0; 90 P0 = a[minute % 10]; 91 du = 1; 92 du = 0; 93 P0 = b[3]; 94 we = 1; 95 we = 0; 96 Delayms(1); 97 //数码管4小数点 98 P0 = b[8]; 99 we = 1; 100 we = 0; 101 P0 = a[10]; 102 du = 1; 103 du = 0; 104 P0 = b[3]; 105 we = 1; 106 we = 0; 107 Delayms(1); 108 //数码管5 109 P0 = b[8]; 110 we = 1; 111 we = 0; 112 P0 = a[second / 10]; 113 du = 1; 114 du = 0; 115 P0 = b[4]; 116 we = 1; 117 we = 0; 118 Delayms(1); 119 //数码管6 120 P0 = b[8]; 121 we = 1; 122 we = 0; 123 P0 = a[second % 10]; 124 du = 1; 125 du = 0; 126 P0 = b[5]; 127 we = 1; 128 we = 0; 129 Delayms(1); 130 } 131 132 133 //年月日显示函数 134 void Dispaly2(uint year, uchar month, uchar day) 135 { 136 //数码管1 137 P0 = b[8]; 138 we = 1; 139 we = 0; 140 P0 = a[year / 1000]; 141 du = 1; 142 du = 0; 143 P0 = b[0]; 144 we = 1; 145 we = 0; 146 Delayms(1); 147 148 //数码管2 149 P0 = b[8]; 150 we = 1; 151 we = 0; 152 P0 = a[(year % 1000) / 100]; 153 du = 1; 154 du = 0; 155 P0 = b[1]; 156 we = 1; 157 we = 0; 158 Delayms(1); 159 160 //数码管3 161 P0 = b[8]; 162 we = 1; 163 we = 0; 164 P0 = a[(year % 100) / 10]; 165 du = 1; 166 du = 0; 167 P0 = b[2]; 168 we = 1; 169 we = 0; 170 Delayms(1); 171 172 //数码管4 173 P0 = b[8]; 174 we = 1; 175 we = 0; 176 P0 = a[year % 10]; 177 du = 1; 178 du = 0; 179 P0 = b[3]; 180 we = 1; 181 we = 0; 182 Delayms(1); 183 184 //数码管4小数点 185 P0 = b[8]; 186 we = 1; 187 we = 0; 188 P0 = a[10]; 189 du = 1; 190 du = 0; 191 P0 = b[3]; 192 we = 1; 193 we = 0; 194 Delayms(1); 195 196 //数码管5 197 P0 = b[8]; 198 we = 1; 199 we = 0; 200 P0 = a[month / 10]; 201 du = 1; 202 du = 0; 203 P0 = b[4]; 204 we = 1; 205 we = 0; 206 Delayms(1); 207 208 //数码管6 209 P0 = b[8]; 210 we = 1; 211 we = 0; 212 P0 = a[month % 10]; 213 du = 1; 214 du = 0; 215 P0 = b[5]; 216 we = 1; 217 we = 0; 218 Delayms(1); 219 //数码管6小数点 220 P0 = b[8]; 221 we = 1; 222 we = 0; 223 P0 = a[10]; 224 du = 1; 225 du = 0; 226 P0 = b[5]; 227 we = 1; 228 we = 0; 229 Delayms(1); 230 //数码管7 231 P0 = b[8]; 232 we = 1; 233 we = 0; 234 P0 = a[day / 10]; 235 du = 1; 236 du = 0; 237 P0 = b[6]; 238 we = 1; 239 we = 0; 240 Delayms(1); 241 //数码管8 242 P0 = b[8]; 243 we = 1; 244 we = 0; 245 P0 = a[day % 10]; 246 du = 1; 247 du = 0; 248 P0 = b[7]; 249 we = 1; 250 we = 0; 251 Delayms(1); 252 } 253 254 void Keyscan1() 255 { 256 static uchar i = 0; 257 if (Key1 == 0) 258 { 259 Delayms(5); //消抖 260 if (Key1 == 0) 261 while (!Key1); //等待按键弹起 262 i++; 263 } 264 if (i % 2 == 1) 265 { 266 LED1 = 0; 267 TR0 = 0; 268 } 269 if (i % 2 == 0) 270 { 271 LED1 = 1; 272 TR0 = 1; 273 } 274 if (Key2 == 0) 275 { 276 Delayms(5); 277 if (Key2 == 0) 278 while (!Key2); 279 j++; 280 if (j == 3) 281 j = 0; 282 } 283 if (j % 3 == 1) 284 { 285 if (Key3 == 0) 286 { 287 Delayms(5); 288 if (Key3 == 0) 289 while (!Key3); 290 second++; 291 if (second == 60) 292 second = 0; 293 } 294 } 295 if (j % 3 == 2) 296 { 297 if (Key3 == 0) 298 { 299 Delayms(5); 300 if (Key3 == 0) 301 while (!Key3); 302 minute++; 303 if (minute == 60) 304 minute = 0; 305 } 306 } 307 if (j % 3 == 0) 308 { 309 if (Key3 == 0) 310 { 311 Delayms(5); 312 if (Key3 == 0) 313 while (!Key3); 314 hour++; 315 if (hour == 24) 316 hour = 0; 317 } 318 } 319 } 320 321 void Keyscan2() 322 { 323 static uchar m = 0; 324 if (Key1 == 0) 325 { 326 Delayms(5); 327 if (Key1 == 0) 328 while (!Key3); 329 m++; 330 if (m == 3) 331 m = 0; 332 } 333 if (m % 2 == 1) 334 { 335 LED1 = 0; 336 TR0 = 0; 337 } 338 if (m % 2 == 0) 339 { 340 LED1 = 1; 341 TR0 = 1; 342 } 343 if (Key2 == 0) 344 { 345 Delayms(5); 346 if (Key2 == 0) 347 while (!Key2); 348 n++; 349 } 350 if (n % 3 == 1) 351 { 352 if (Key3 == 0) 353 { 354 Delayms(5); 355 if (Key3 == 0) 356 while (!Key3); 357 day++; 358 if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) //是闰年 359 { 360 if (month == 12 || month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) 361 { 362 if (day == 32) 363 { 364 day = 0; 365 } 366 } 367 if ( month == 4 || month == 6 || month == 9 || month == 11 ) 368 { 369 if (day == 31) 370 { 371 day = 0; 372 } 373 } 374 if (month == 2) 375 { 376 if (day == 29) 377 { 378 day = 0; 379 } 380 } 381 } 382 else //不是闰年 383 { 384 if (month == 12 || month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) 385 { 386 if (day == 32) 387 { 388 day = 0; 389 } 390 } 391 if ( month == 4 || month == 6 || month == 9 || month == 11 ) 392 { 393 if (day == 31) 394 { 395 day = 0; 396 } 397 } 398 if (month == 2) 399 { 400 if (day == 30) 401 { 402 day = 0; 403 } 404 } 405 } 406 407 } 408 } 409 if (n % 3 == 2) 410 { 411 if (Key3 == 0) 412 { 413 Delayms(5); 414 if (Key3 == 0) 415 while (!Key3); 416 month++; 417 if (month == 12) 418 month = 0; 419 } 420 } 421 if (n % 3 == 0) 422 { 423 if (Key3 == 0) 424 { 425 Delayms(5); 426 if (Key3 == 0) 427 while (!Key3); 428 year++; 429 if (year == 99) 430 year = 0; 431 } 432 } 433 434 } 435 436 void main() 437 { 438 TMOD = 0x01; 439 TH0 = 0x4c; 440 //TH0 = (65536 - 10000) / 256; 441 TL0 = 0x00; 442 //TL0 = (65536 - 10000) % 256; 443 EA = 1; 444 ET0 = 1; 445 TR0 = 1; 446 while (1) 447 { 448 static uchar h = 0; 449 if (Key4 == 0) 450 { 451 Delayms(5); 452 if (Key4 == 0) 453 while (!Key4); 454 h++; 455 } 456 if (h % 2 == 1) //按Key4奇次数显示年月日 457 { 458 P1 = c[n % 3]; //年月日调位判断灯 459 Dispaly2(year, month, day); 460 Keyscan2(); 461 } 462 if (h % 2 == 0) //按Key4偶次数显示时分秒 463 { 464 P1 = c[j % 3]; //时分秒调位判断灯 465 Dispaly1(hour, minute, second); 466 Keyscan1(); 467 } 468 } 469 } 470 471 void time0_int(void) interrupt 1 472 { 473 //TH0 = (65536 - 10000) / 256; 474 //TL0 = (65536 - 10000) % 256; 475 TH0 = 0x4c; //公式:定时时间t = (2^16 - T0初值) * 振荡周期 * 12 (振荡周期 * 12 即机器周期) 476 TL0 = 0x00; //T0 = 2^16 - t * 11059200 / 12 (此定时时间为 50ms, T1 = 19456 = 0x4c00) 477 count++; 478 if (count == 20) 479 { 480 count = 0; 481 second++; 482 if (second == 60) 483 { 484 second = 0; 485 minute++; 486 if (minute == 60) 487 { 488 minute = 0; 489 hour++; 490 if (hour == 24) 491 { 492 hour = 0; 493 day++; 494 if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) //是闰年 495 { 496 if (month == 12 || month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) 497 { 498 if (day == 31) 499 { 500 day = 0; 501 month++; 502 if (month == 12) 503 { 504 month = 1; 505 year++; 506 if (year == 99) 507 { 508 year = 0; 509 } 510 } 511 } 512 } 513 if ( month == 4 || month == 6 || month == 9 || month == 11 ) 514 { 515 if (day == 30) 516 { 517 day = 0; 518 month++; 519 } 520 } 521 if (month == 2) 522 { 523 if (day == 28) 524 { 525 day = 0; 526 month++; 527 } 528 } 529 } 530 else //不是闰年 531 { 532 if (month == 12 || month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) 533 { 534 if (day == 31) 535 { 536 day = 0; 537 month++; 538 if (month == 12) 539 { 540 month = 1; 541 year++; 542 if (year == 99) 543 { 544 year = 0; 545 } 546 } 547 } 548 } 549 if ( month == 4 || month == 6 || month == 9 || month == 11 ) 550 { 551 if (day == 30) 552 { 553 day = 0; 554 month++; 555 } 556 } 557 if (month == 2) 558 { 559 if (day == 29) 560 { 561 day = 0; 562 month++; 563 } 564 } 565 566 } 567 } 568 } 569 } 570 } 571 }
判断闰年算法:百度百科_闰年
非整百年:能被4整除的为闰年。(如2004年就是闰年,2100年不是闰年);整百年:能被400整除的是闰年。(如2000年是闰年,1900年不是闰年)
((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0) 或 year % 4 == 0 && year % 100 != 0 || year % 400 == 0
******************************************************************************
第一次更新,上面的没写星期显示,在此加上,部分算法有问题,已改
1 /************************************************** 2 3 作者:纟彖氵戋 博客:http://www.cnblogs.com/yllinux/ 4 5 时间:2017年6月9日 6 7 目标:利用单片机独立键盘、数码管、LED灯模块实现万年历(算法实现) 8 9 结果:默认显示 “ 星期 - 小时. 分钟. 秒 ” ;按Key4切换年月日显示 “ 年份. 月份. 日期 ” 10 按Key1停止计时,再按继续计时;按Key2切换要调的位同时LED灯给出位提示;按Key3调整的位加一;按Key4切换年月日显示和时分秒显示 11 12 缺点:延时运用了运算和松手检测运用了死等;代码有些烂。(有待改进) 13 ***************************************************/ 14 #include <reg52.h> 15 #define uchar unsigned char 16 #define uint unsigned int 17 18 uchar code a[] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80,0x40 }; //字形码表0~9和.和- 19 uchar code b[] = { 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff }; //数码管位码表1~8和0 20 uchar code c[] = { 0x3f,0xf3,0xcf }; //调位指示灯位表 21 uchar const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5};//星期查找表 22 23 uint year = 2017; 24 uchar month = 6, day = 14; 25 uchar hour = 8, minute = 35, second = 0, ms_500 = 0; 26 uchar count; //时钟计数 27 uchar n = 1; //年月日调位指示 28 uchar j = 1; //时分秒调位指示 29 30 sbit Key1 = P3 ^ 0; //计时停止 31 sbit Key2 = P3 ^ 1; //调位 32 sbit Key3 = P3 ^ 2; //加一 33 sbit Key4 = P3 ^ 3; //切换 34 sbit LED1 = P1 ^ 0; 35 sbit we = P2 ^ 7; 36 sbit du = P2 ^ 6; 37 38 //延时函数 39 void Delayms(uint z) 40 { 41 uint x, y; 42 for (x = 0; x < z; x++) 43 for (y = 0; y < 114; y++); 44 } 45 46 //计算星期函数 47 uchar get_week(uint year,uchar month,uchar day) 48 { 49 uchar temp; 50 uchar yearH, yearL; 51 yearH = year/100; 52 yearL = year%100; 53 if (yearH > 19) yearL+=100; 54 temp = yearL + yearL / 4; 55 temp = temp % 7; 56 temp = temp + day + table_week[ month - 1 ]; 57 if (yearL % 4 == 0 && month < 3) temp--; 58 return(temp % 7); 59 } 60 61 62 //时分秒显示函数 63 void Dispaly1(uchar hour, uchar minute, uchar second) 64 { 65 P0 = b[8]; we = 1; we = 0; P0 = a[get_week(year, month, day)]; du = 1; du = 0; P0 = b[0]; we = 1; we = 0; Delayms(1); //数码管1 66 67 P0 = b[8]; we = 1; we = 0; P0 = a[11]; du = 1; du = 0; P0 = b[1]; we = 1; we = 0; Delayms(1); //数码管2 68 69 P0 = b[8]; we = 1; we = 0; P0 = a[hour / 10]; du = 1; du = 0; P0 = b[2]; we = 1; we = 0; Delayms(1); //数码管3 70 71 P0 = b[8]; we = 1; we = 0; P0 = a[hour % 10]; du = 1; du = 0; P0 = b[3]; we = 1; we = 0; Delayms(1); //数码管4 72 73 P0 = b[8]; we = 1; we = 0; P0 = a[10]; du = 1; du = 0; P0 = b[3]; we = 1; we = 0; Delayms(1); //数码管4小数点 74 75 P0 = b[8]; we = 1; we = 0; P0 = a[minute / 10]; du = 1; du = 0; P0 = b[4]; we = 1; we = 0; Delayms(1); //数码管5 76 77 P0 = b[8]; we = 1; we = 0; P0 = a[minute % 10]; du = 1; du = 0; P0 = b[5]; we = 1; we = 0; Delayms(1); //数码管6 78 79 P0 = b[8]; we = 1; we = 0; P0 = a[10]; du = 1; du = 0; P0 = b[5]; we = 1; we = 0; Delayms(1); //数码管6小数点 80 81 P0 = b[8]; we = 1; we = 0; P0 = a[second / 10]; du = 1; du = 0; P0 = b[6]; we = 1; we = 0; Delayms(1); //数码管7 82 83 P0 = b[8]; we = 1; we = 0; P0 = a[second % 10]; du = 1; du = 0; P0 = b[7]; we = 1; we = 0; Delayms(1); //数码管8 84 } 85 86 //年月日显示函数 87 void Dispaly2(uint year, uchar month, uchar day) 88 { 89 P0 = b[8]; we = 1; we = 0; P0 = a[year / 1000]; du = 1; du = 0; P0 = b[0]; we = 1; we = 0; Delayms(1);//数码管1 90 91 P0 = b[8]; we = 1; we = 0; P0 = a[(year % 1000) / 100]; du = 1; du = 0; P0 = b[1]; we = 1; we = 0; Delayms(1);//数码管2 92 93 P0 = b[8]; we = 1; we = 0; P0 = a[(year % 100) / 10]; du = 1; du = 0; P0 = b[2]; we = 1; we = 0; Delayms(1);//数码管3 94 95 P0 = b[8]; we = 1; we = 0; P0 = a[year % 10]; du = 1; du = 0; P0 = b[3]; we = 1; we = 0; Delayms(1);//数码管4 96 97 P0 = b[8]; we = 1; we = 0; P0 = a[10]; du = 1; du = 0; P0 = b[3]; we = 1; we = 0; Delayms(1);//数码管4小数点 98 99 P0 = b[8]; we = 1; we = 0; P0 = a[month / 10]; du = 1; du = 0; P0 = b[4]; we = 1; we = 0; Delayms(1);//数码管5 100 101 P0 = b[8]; we = 1; we = 0; P0 = a[month % 10]; du = 1; du = 0; P0 = b[5]; we = 1; we = 0; Delayms(1);//数码管6 102 103 P0 = b[8]; we = 1; we = 0; P0 = a[10]; du = 1; du = 0; P0 = b[5]; we = 1; we = 0; Delayms(1);//数码管6小数点 104 105 P0 = b[8]; we = 1; we = 0; P0 = a[day / 10]; du = 1; du = 0; P0 = b[6]; we = 1; we = 0; Delayms(1);//数码管7 106 107 P0 = b[8]; we = 1; we = 0; P0 = a[day % 10]; du = 1; du = 0; P0 = b[7]; we = 1; we = 0; Delayms(1);//数码管8 108 } 109 110 void Keyscan1() 111 { 112 static uchar i = 0; 113 if (Key1 == 0) 114 { 115 Delayms(5); //消抖 116 if (Key1 == 0) 117 while (!Key1); //等待按键弹起 118 i++; 119 } 120 if (i % 2 == 1) 121 { 122 //LED1 = 0; 123 TR0 = 0; 124 } 125 if (i % 2 == 0) 126 { 127 //LED1 = 1; 128 TR0 = 1; 129 } 130 if (Key2 == 0) 131 { 132 Delayms(5); 133 if (Key2 == 0) 134 while (!Key2); 135 j++; 136 if (j == 3) 137 j = 0; 138 } 139 if (j % 3 == 1) 140 { 141 if (Key3 == 0) 142 { 143 Delayms(5); 144 if (Key3 == 0) 145 while (!Key3); 146 second++; 147 if (second == 60) 148 second = 0; 149 } 150 } 151 if (j % 3 == 2) 152 { 153 if (Key3 == 0) 154 { 155 Delayms(5); 156 if (Key3 == 0) 157 while (!Key3); 158 minute++; 159 if (minute == 60) 160 minute = 0; 161 } 162 } 163 if (j % 3 == 0) 164 { 165 if (Key3 == 0) 166 { 167 Delayms(5); 168 if (Key3 == 0) 169 while (!Key3); 170 hour++; 171 if (hour == 24) 172 hour = 0; 173 } 174 } 175 } 176 177 void Keyscan2() 178 { 179 static uchar m = 0; 180 if (Key1 == 0) 181 { 182 Delayms(5); 183 if (Key1 == 0) 184 while (!Key3); 185 m++; 186 if (m == 3) 187 m = 0; 188 } 189 if (m % 2 == 1) 190 { 191 //LED1 = 0; 192 TR0 = 0; 193 } 194 if (m % 2 == 0) 195 { 196 //LED1 = 1; 197 TR0 = 1; 198 } 199 if (Key2 == 0) 200 { 201 Delayms(5); 202 if (Key2 == 0) 203 while (!Key2); 204 n++; 205 } 206 if (n % 3 == 1) 207 { 208 if (Key3 == 0) 209 { 210 Delayms(5); 211 if (Key3 == 0) 212 while (!Key3); 213 day++; 214 if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) //是闰年 215 { 216 if (month == 12 || month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) 217 { 218 if (day == 32) 219 { 220 day = 0; 221 } 222 } 223 if ( month == 4 || month == 6 || month == 9 || month == 11 ) 224 { 225 if (day == 31) 226 { 227 day = 0; 228 } 229 } 230 if (month == 2) 231 { 232 if (day == 30) 233 { 234 day = 0; 235 } 236 } 237 } 238 else //不是闰年 239 { 240 if (month == 12 || month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) 241 { 242 if (day == 32) 243 { 244 day = 0; 245 } 246 } 247 if ( month == 4 || month == 6 || month == 9 || month == 11 ) 248 { 249 if (day == 31) 250 { 251 day = 0; 252 } 253 } 254 if (month == 2) 255 { 256 if (day == 29) 257 { 258 day = 0; 259 } 260 } 261 } 262 263 } 264 } 265 if (n % 3 == 2) 266 { 267 if (Key3 == 0) 268 { 269 Delayms(5); 270 if (Key3 == 0) 271 while (!Key3); 272 month++; 273 if (month == 12) 274 month = 0; 275 } 276 } 277 if (n % 3 == 0) 278 { 279 if (Key3 == 0) 280 { 281 Delayms(5); 282 if (Key3 == 0) 283 while (!Key3); 284 year++; 285 if (year == 2101) 286 year = 2000; 287 } 288 } 289 290 } 291 292 void main() 293 { 294 TMOD = 0x01; 295 TH0 = 0x4c; 296 TL0 = 0x00; 297 EA = 1; 298 ET0 = 1; 299 TR0 = 1; 300 while (1) 301 { 302 static uchar h = 0; 303 if (Key4 == 0) 304 { 305 Delayms(5); 306 if (Key4 == 0) 307 while (!Key4); 308 h++; 309 } 310 if (h % 2 == 1) //按Key4奇次数显示年月日 311 { 312 P1 = c[n % 3]; //年月日调位判断灯 313 Dispaly2(year, month, day); 314 Keyscan2(); 315 } 316 if (h % 2 == 0) //按Key4偶次数显示时分秒 317 { 318 P1 = c[j % 3]; //时分秒调位判断灯 319 Dispaly1(hour, minute, second); 320 Keyscan1(); 321 get_week( year, month, day); 322 } 323 } 324 } 325 326 void time0_int(void) interrupt 1 327 { 328 TH0 = 0x4c; //公式:定时时间t = (2^16 - T0初值) * 振荡周期 * 12 (振荡周期 * 12 即机器周期) 329 TL0 = 0x00; //T0 = 2^16 - t * 11059200 / 12 (此定时时间为 50ms, T1 = 19456 = 0x4c00) 330 count++; 331 if (count == 10) 332 { 333 count = 0; 334 ms_500++; 335 if (ms_500 == 2) 336 { 337 ms_500 = 0; 338 second++; 339 if (second == 60) 340 { 341 second = 0; 342 minute++; 343 if (minute == 60) 344 { 345 minute = 0; 346 hour++; 347 if (hour == 24) 348 { 349 hour = 0; 350 day++; 351 if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) //是闰年 352 { 353 if (month == 12 || month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) 354 { 355 if (day == 31) 356 { 357 day = 0; 358 month++; 359 if (month == 12) 360 { 361 month = 1; 362 year++; 363 if (year == 2101) 364 { 365 year = 2000; 366 } 367 } 368 } 369 } 370 if ( month == 4 || month == 6 || month == 9 || month == 11 ) 371 { 372 if (day == 30) 373 { 374 day = 0; 375 month++; 376 } 377 } 378 if (month == 2) 379 { 380 if (day == 29) 381 { 382 day = 0; 383 month++; 384 } 385 } 386 } 387 else //不是闰年 388 { 389 if (month == 12 || month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) 390 { 391 if (day == 31) 392 { 393 day = 0; 394 month++; 395 if (month == 12) 396 { 397 month = 1; 398 year++; 399 if (year == 2101) 400 { 401 year = 2000; 402 } 403 } 404 } 405 } 406 if ( month == 4 || month == 6 || month == 9 || month == 11 ) 407 { 408 if (day == 30) 409 { 410 day = 0; 411 month++; 412 } 413 } 414 if (month == 2) 415 { 416 if (day == 28) 417 { 418 day = 0; 419 month++; 420 } 421 } 422 423 } 424 } 425 } 426 } 427 } 428 } 429 }
星期算法:
(1)
https://zhidao.baidu.com/question/159474320.html
1 uchar const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5};//平年月表 2 uchar get_week(uint year,uchar month,uchar day) 3 { 4 uchar temp; 5 uchar yearH, yearL; 6 yearH = year / 100; 7 yearL = year % 100; 8 if (yearH > 19) 9 yearL += 100; 10 temp = yearL + yearL / 4; 11 temp = temp % 7; 12 temp = temp + day + table_week[month - 1]; 13 if (yearL % 4 == 0 && month < 3) 14 temp--; 15 return(temp % 7); 16 }
(2)
蔡勒公式法:百度百科_蔡勒公式
http://blog.csdn.net/minyuanxiani/article/details/22890447#
1 /* 2 ********************************************************************************************************* 3 * 函 数 名: bsp_CalcWeek 4 * 功能说明: 根据日期计算星期几 5 * 形 参: _year _mon _day 年月日 (年是2字节整数,月和日是字节整数) 6 * 返 回 值: 周几 (1-7) 7表示周日 7 ********************************************************************************************************* 8 */ 9 uint8_t bsp_CalcWeek(uint16_t _year, uint8_t _mon, uint8_t _day) 10 { 11 /* 12 蔡勒(Zeller)公式 13 历史上的某一天是星期几?未来的某一天是星期几?关于这个问题,有很多计算公式(两个通用计算公式和 14 一些分段计算公式),其中最著名的是蔡勒(Zeller)公式。 15 即w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 16 17 公式中的符号含义如下, 18 w:星期; 19 c:年的高2位,即世纪-1 20 y:年(两位数); 21 m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算, 22 比如2003年1月1日要看作2002年的13月1日来计算); 23 d:日; 24 [ ]代表取整,即只要整数部分。 25 26 算出来的W除以7,余数是几就是星期几。如果余数是0,则为星期日。 27 如果结果是负数,负数求余数则需要特殊处理: 28 负数不能按习惯的余数的概念求余数,只能按数论中的余数的定义求余。为了方便 29 计算,我们可以给它加上一个7的整数倍,使它变为一个正数,然后再求余数 30 31 以2049年10月1日(100周年国庆)为例,用蔡勒(Zeller)公式进行计算,过程如下: 32 蔡勒(Zeller)公式:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1 33 =49+[49/4]+[20/4]-2×20+[26× (10+1)/10]+1-1 34 =49+[12.25]+5-40+[28.6] 35 =49+12+5-40+28 36 =54 (除以7余5) 37 即2049年10月1日(100周年国庆)是星期5。 38 */ 39 uint8_t y, c, m, d; 40 int16_t w; 41 42 if (_mon >= 3) 43 { 44 m = _mon; 45 y = _year % 100; 46 c = _year / 100; 47 d = _day; 48 } 49 else /* 某年的1、2月要看作上一年的13、14月来计算 */ 50 { 51 m = _mon + 12; 52 y = (_year - 1) % 100; 53 c = (_year - 1) / 100; 54 d = _day; 55 } 56 57 w = y + y / 4 + c / 4 - 2 * c + ((uint16_t)26*(m+1))/10 + d - 1; 58 if (w == 0) 59 { 60 w = 7; /* 表示周日 */ 61 } 62 else if (w < 0) /* 如果w是负数,则计算余数方式不同 */ 63 { 64 w = 7 - (-w) % 7; 65 } 66 else 67 { 68 w = w % 7; 69 } 70 return w; 71 }
--
***********************************************************************
参考:
http://www.cnblogs.com/LXSYD-C/p/6364888.html
如有错误还请指出,如有侵权还请告知,如需转载请注明出处!