-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsource_code.c
1351 lines (1223 loc) · 44.5 KB
/
source_code.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//电脑时钟c语言代码
//2018.11.15 final version
#include "C8051F020.h"
//////////////////////////////////////////////////////////////////////////////
//// 初始化程序 ////
//////////////////////////////////////////////////////////////////////////////
void Oscillator_Init() //外部晶振设置
{
int i = 0;
OSCXCN = 0x67;
for (i = 0; i < 3000; i++); // Wait 1ms for initialization
while ((OSCXCN & 0x80) == 0);
OSCICN = 0x08;
}
void Timer_Init() //定时器设置
{
TMR3CN = 0x04; //定时器3工作
TMR3RLH = 0x90; //定时器3初值
TMR3H = 0x90; //定时器3装填值
EIE2 = 0x0a1; //允许定时器3开中断
IE = 0x82; //允许定时器0开中断
IP = 0x02; //定时器0高中断优先级
}
void Init_Device(void)
{
Oscillator_Init();
Timer_Init();
}
#define uchar unsigned char //宏定义
#define uint unsigned int
sbit P3_0 = P3 ^ 0; //位变量定义
sbit P3_1 = P3 ^ 1;
sbit P3_2 = P3 ^ 2;
sbit P3_5 = P3 ^ 5;
sbit P3_6 = P3 ^ 6;
sbit P3_7 = P3 ^ 7;
//////////////////////////////////////////////////////////////////////////////
//// 全局变量声明 ////
//////////////////////////////////////////////////////////////////////////////
uchar flag = 1; //键盘标志位
uchar state[11]; //标志位合集
uchar keyst = 1; //按键显示标志位
uchar suichi[2] = {1, 1}; //整点报时、闹钟标志位
uchar num[17] = {0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0,
0xfe, 0xf6, 0xee, 0x3e, 0x9c, 0x7a, 0x9e, 0x8e };
//显示管字模
uchar alarm[3][2]; //闹钟设置变量
uchar sec = 58; //秒变量
uchar min = 59; //分变量
uchar hour = 23; //时变量
uint toki = 0; //定时器计数变量
uchar wkday; //周变量
uchar day = 4; //日变量
uchar month = 1; //月变量
uint year = 2100; //年变量
uchar m; //键值标志位
//////////////////////////////////////////////////////////////////////////////
//// 函数声明 ////
//////////////////////////////////////////////////////////////////////////////
void delay(uint k); //delay函数
void time(); //计时函数
void week(); //星期的函数
void ymd(); //年月日控制函数
void display1(); //时间显示函数
void display2(); //星期显示函数
void display3(); //年月日显示函数
void display4(uchar k); //闹钟设置显示函数
void alarm1(); //闹钟控制函数
void oclock(); //整点报时函数
void _74HC164(uchar dat); //移位寄存器控制函数
uchar keyscan(); //键盘扫描函数
void setmod(); //功能设置函数
void setsequence(); //设置选择函数
void sethms(); //时分秒设置函数
void setymd(); //年月日设置函数
void correctymd(); //设置年月日进位校正函数
void selectalarm(); //闹钟选择函数
void stalm1(); //闹钟1--闹钟3函数
void stalm2();
void stalm3();
///////////////////////////////////////////////////////////////////////////////
//// 显示/设置选择程序 ////
///////////////////////////////////////////////////////////////////////////////
void select()
{
switch(state[0])
{
case(0): //显示模式
{
if(m == 17) //若F6键按下,切换至设置模式
{
m = 20;
state[0] = 1;
WDTCN=0xa5; //喂狗
}
setmod(); //显示模式
switch(state[5]) //选择是否开整点报时
{
case(0): //开整点报时
if(m == 11) //按"="键关闭整点报时
{
m = 20; //键值标志变量回初态
state[5] = 1; //跳转至下一态
}
suichi[0] = 1; //整点报时开
break;
case(1): //关整点报时
if(m == 11) //按"="键开启整点报时
{
m = 20;
state[5] = 0;
WDTCN=0xa5; //喂狗
}
suichi[0] = 0; //整点报时关
break;
}
break;
}
case(1): //时间设置模式
{
WDTCN=0xa5; //喂狗
setsequence(); //设置选择函数
break;
}
case(2): //闹钟设置模式
TR0 = 1; //定时器开
WDTCN=0xa5; //喂狗
selectalarm(); //选择闹钟
break;
}
}
//////////////////////////////////////////////////////////////////////////////
//// 显示功能控制程序 ////
//////////////////////////////////////////////////////////////////////////////
void setmod()
{
switch(state[1]) //模式选择
{
case(0): //时分秒显示模式
{
if(m == 16) //若按F5,切换至星期显示模式
{
WDTCN=0xa5; //喂狗
m = 20; //键盘回初态
state[1] = 1; //标志位切至星期显示
}
TR0 = 1; //定时器开
keyst = 1; //按键显示时分秒模式
display1(); //显示时分秒
break;
}
case(1): //星期显示模式
{
if(m == 16) //若按F5,切换至年月日显示模式
{
WDTCN=0xa5; //喂狗
m = 20; //键盘回初态
state[1] = 2; //标志位切至年月日显示
}
keyst = 2; //按键显示星期模式
display2(); //显示星期
break;
}
case(2): //年月日显示模式
{
if(m == 16) //若按F5,切换至时分秒显示模式
{
WDTCN=0xa5; //喂狗
m = 20; //键盘回初态
state[1] = 0; //标志位切至时分秒显示
}
keyst = 3; //按键显示年月日模式
display3(); //显示年月日
break;
}
}
return;
}
//////////////////////////////////////////////////////////////////////////////
//// 设置选择程序 ////
//////////////////////////////////////////////////////////////////////////////
void setsequence()
{
TR0 = 0; //关定时器0
switch(state[2])
{
case(1): //设置时分秒
WDTCN=0xa5; //喂狗
sethms();
break;
case(0): //设置年月日
WDTCN=0xa5; //喂狗
setymd();
break;
}
}
//////////////////////////////////////////////////////////////////////////////
//// 时间设置程序 ////
//////////////////////////////////////////////////////////////////////////////
void sethms()
{
uchar mark = 1; //循环标志位
uchar key; //键值局域变量
keyst = 1; //按键显示标志位
while(mark) //跳出程序前一直循环等待按键
{
WDTCN=0xa5; //喂狗
display1(); //显示时分秒
if(state[3] == 0) //设置秒
{
key = keyscan(); //键盘扫描
if(key == 0) //如果按"0",秒加一
{
sec++;
if(sec == 60) sec = 0; //秒为59时再加一则回0
}
if(key == 10) state[3] = 1; //若按".",则设置分
if(key == 17)
{
state[2] = 0; //若按"F6",跳转至闹钟设置
state[0] = 2;
}
mark = 0; //标志位回0跳出循环
}
if(state[3] == 1) //设置分
{
key = keyscan(); //键盘扫描
if(key == 0) //如果按"0",分加一
{
min++;
if(min == 60) min = 0; //分为59时再加一则回0
}
if(key == 10) state[3] = 2; //若按".",则设置时
if(key == 17)
{
state[2] = 0; //若按"F6",跳转至闹钟设置
state[0] = 2;
}
mark = 0; //标志位回0跳出循环
}
if(state[3] == 2) //设置时
{
key = keyscan(); //键盘扫描
if(key == 0) //如果按"0",时加一
{
hour++;
if(hour == 24) hour = 0; //时为23时再加一则回0
}
if(key == 10) state[3] = 0; //若按".",则设置秒
if(key == 17)
{
state[2] = 0; //若按"F6",跳转至闹钟设置
state[0] = 2;
}
mark = 0; //标志位回0跳出循环
}
}
}
//////////////////////////////////////////////////////////////////////////////
//// 年月日设置程序 ////
//////////////////////////////////////////////////////////////////////////////
void setymd()
{
uchar mark = 1; //循环标志位
uchar key; //键值局域变量
keyst = 3; //按键显示标志位
while(mark) //跳出程序前一直循环等待按键
{
WDTCN=0xa5;
display3(); //显示年月日
if(state[4] == 0) //设置年
{
key = keyscan(); //键盘扫描
if(key == 0) year++; //若按"0",则年加一
if(key == 1) year--; //若按"1",则年减一
if(key == 10) state[4] = 1; //若按".",则设置月
if(key == 17) state[2] = 1; //若按"F6",跳转至时分秒设置
mark = 0; //标志位回0跳出循环
}
if(state[4] == 1) //设置月
{
key = keyscan(); //键盘扫描
if(key == 0) month++; //若按"0",则月加一
if(month == 13) month = 1; //若月为12,再加一则回1月
if(key == 10) state[4] = 2; //若按".",则设置日
if(key == 17) state[2] = 1; //若按"F6",跳转至时分秒设置
mark = 0; //标志位回0跳出循环
}
if(state[4] == 2) //设置日
{
key = keyscan(); //键盘扫描
if(key == 0) correctymd(); //若按"0",则日按规则进位
if(key == 10) state[4] = 0; //若按".",则设置年
if(key == 17) state[2] = 1; //若按"F6",跳转至时分秒设置
mark = 0; //标志位回0跳出循环
}
}
}
//////////////////////////////////////////////////////////////////////////////
//// 设置年月日的校正程序 ////
//////////////////////////////////////////////////////////////////////////////
void correctymd()
{
day++; //日加一
WDTCN=0xa5; //喂狗
if((month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 8) || (month == 10) || (month == 12))
{ //一三五七八十腊
if(day == 32) //三十一天永不差
{
day = 1;
}
}
if((month == 4) || (month == 6) || (month == 9) || (month == 11))
{ //四、六、九、十一
if(day == 31) //三十天
{
day = 1;
}
}
if(month == 2) //判断平年还是闰年
{
if((year % 100) != 0) //判断年份是否为100的倍数
{
if((year % 4) == 0) //不是100的倍数且是4的倍数,是闰年
{
if(day == 30) //闰年二月二十九
{
day = 1;
}
}
if((year % 4) != 0) //不是4的倍数,是平年
{
if(day == 29) //平年二月二十八
{
day = 1;
}
}
}
if((year % 100) == 0) //年份是100的倍数
{
if((year % 400) == 0) //是100的倍数且是400的倍数,是闰年
{
if(day == 30) //闰年二月二十九
{
day = 1;
}
}
else //是100的倍数且不是400的倍数,是平年
{
if(day == 29) //平年二月二十八
{
day = 1;
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
//// 闹钟选择程序 ////
//////////////////////////////////////////////////////////////////////////////
void selectalarm()
{
state[10] = suichi[0]; //记忆整点报时状态
suichi[0] = 0; //设置闹钟时关闭整点报时
suichi[1] = 0; //关闭闹钟提示
switch(state[6])
{
case(0): //设置闹钟1
stalm1();
WDTCN=0xa5; //喂狗
break;
case(1): //设置闹钟2
stalm2();
WDTCN=0xa5; //喂狗
break;
case(2): //设置闹钟3
stalm3();
WDTCN=0xa5; //喂狗
break;
}
}
//////////////////////////////////////////////////////////////////////////////
//// 闹钟1设置程序 ////
//////////////////////////////////////////////////////////////////////////////
void stalm1()
{
uchar mark = 1; //循环标志位
uchar key; //键值局域变量
WDTCN=0xa5; //喂狗
keyst = 4; //按键显示闹钟设置
while(mark)
{
WDTCN=0xa5;
display4(state[6]); //显示闹钟设置界面
if(state[7] == 0) //闹钟分设置模式
{
key = keyscan(); //扫描键盘
if(key == 0) //若按0键
{
(alarm[0][0])++; //闹钟分++
if(alarm[0][0] == 60) alarm[0][0] = 0;
} //若分为59,再加一回0
if(key == 10) state[7] = 1; //若按. 键,设置闹钟时
if(key == 17) state[6] = 1; //若按F6键,设置下一个闹钟
mark = 0;
}
if(state[7] == 1) //闹钟时设置模式
{
key = keyscan(); //扫描键盘
if(key == 0) //若按0键
{
(alarm[0][1])++; //闹钟时++
if(alarm[0][1] == 25) alarm[0][1] = 0;
} //闹钟时数为"24"时,关闹钟,显示A1 OFF,再加一回0
if(key == 10) state[7] = 0; //若按. 键,设置闹钟分
if(key == 17) state[6] = 1; //若按F6键,设置下一个闹钟
mark = 0; //跳出循环
}
}
}
//////////////////////////////////////////////////////////////////////////////
//// 闹钟2设置程序 ////
//////////////////////////////////////////////////////////////////////////////
/*闹钟2,3的代码与闹钟1基本一致,此处不再重复注释*/
void stalm2()
{
uchar mark = 1;
uchar key;
WDTCN=0xa5;
keyst = 4;
while(mark)
{
WDTCN=0xa5;
display4(state[6]);
if(state[8] == 0)
{
key = keyscan();
if(key == 0)
{
(alarm[1][0])++;
if(alarm[1][0] == 60) alarm[1][0] = 0;
}
if(key == 10) state[8] = 1;
if(key == 17) state[6] = 2;
mark = 0;
}
if(state[8] == 1)
{
key = keyscan();
if(key == 0)
{
(alarm[1][1])++;
if(alarm[1][1] == 24) alarm[1][1] = 0;
}
if(key == 10) state[8] = 0;
if(key == 17) state[6] = 2;
mark = 0;
}
}
}
//////////////////////////////////////////////////////////////////////////////
//// 闹钟3设置程序 ////
//////////////////////////////////////////////////////////////////////////////
void stalm3()
{
uchar mark = 1;
uchar key;
WDTCN=0xa5;
keyst = 4;
while(mark)
{
WDTCN=0xa5;
display4(state[6]);
if(state[9] == 0)
{
key = keyscan();
if(key == 0)
{
(alarm[2][0])++;
if(alarm[2][0] == 60) alarm[2][0] = 0;
}
if(key == 10) state[9] = 1;
if(key == 17) //若按F6,回到显示模式,闹钟开,整点报时回到初态
{
state[6] = 0;
suichi[0] = state[10];
suichi[1] = 1;
state[0] = 0;
}
mark = 0;
}
if(state[9] == 1)
{
key = keyscan();
if(key == 0)
{
(alarm[2][1])++;
if(alarm[2][1] == 24) alarm[2][1] = 0;
}
if(key == 10) state[9] = 0;
if(key == 17) //若按F6,回到显示模式,闹钟开,整点报时回到初态
{
state[6] = 0;
suichi[0] = state[10];
suichi[1] = 1;
state[0] = 0;
}
mark = 0;
}
}
}
//////////////////////////////////////////////////////////////////////////////
//// delay程序 ////
//////////////////////////////////////////////////////////////////////////////
void delay(uint k)
{
uchar j; //循环变量
WDTCN=0xa5; //喂狗
while((k--) != 0) //k=0时跳出循环
{
for(j = 0; j < 100; j++) {} //空循环100次
} //一共循环100*k次
}
//////////////////////////////////////////////////////////////////////////////
//// 74HC164程序 ////
//////////////////////////////////////////////////////////////////////////////
void _74HC164(uchar dat) //向74HC164中一个8位data
{
uchar i;
WDTCN=0xa5; //喂狗
for(i = 0; i < 8; i++) //将8位data并行输出
{
P3_7 = 0; //时钟翻转
if(dat & 0x80) //取出数据的第一位
P3_6 = 1; //是1则置1
else
P3_6 = 0; //是0则置0
P3_7 = 1; //时钟翻转,产生上升沿信号
dat = dat << 1; //数据左移
}
}
//////////////////////////////////////////////////////////////////////////////
//// 键盘扫描程序 ////
//////////////////////////////////////////////////////////////////////////////
uchar keyscan()
{
uchar key_value; //键值变量
uchar i; //循环变量
WDTCN=0xa5; //喂狗
flag = 1; //按键标志位置1
_74HC164(0x00); //向74HC164送入0x00
if((P4 | 0xf0) != 0xff) //若有按键按下
{
delay(50); //防抖
if(!((P4 | 0xf0) == 0xff)) //判断是否确实有按键按下
{
for(i = 0; i < 5; i++) //行扫描
{
switch(i)
{
case(0): //第一行
{
_74HC164(0x1e); //0001 1110
if ((P4 | 0xf0) == 0xfe) //1111 1110
{
flag = 0; //有键按下的标志
key_value = 0; //0键按下
}
if ((P4 | 0xf0) == 0xfd) //1111 1101
{
flag = 0;
key_value = 1; //1键按下
}
if ((P4 | 0xf0) == 0xfb) //1111 1011
{
flag = 0;
key_value = 2; //2键按下
}
if ((P4 | 0xf0) == 0xf7) //1111 0111
{
flag = 0;
key_value = 3; //3键按下
}
break;
}
case(1): //第二行
{
_74HC164(0x1d); //0001 1101
if ((P4 | 0xf0) == 0xfe) //1111 1110
{
flag = 0;
key_value = 4; //4键按下
}
if ((P4 | 0xf0) == 0xfd) //1111 1101
{
flag = 0;
key_value = 5; //5键按下
}
if ((P4 | 0xf0) == 0xfb) //1111 1011
{
flag = 0;
key_value = 6; //6键按下
}
if ((P4 | 0xf0) == 0xf7) //1111 0111
{
flag = 0;
key_value = 7; //7键按下
}
break;
}
case(2): //扫描第三行
{
_74HC164(0x1b); //0001 1011
if ((P4 | 0xf0) == 0xfe) //1111 1110
{
flag = 0;
key_value = 8; //8键按下
}
if ((P4 | 0xf0) == 0xfd) //1111 1101
{
flag = 0;
key_value = 9; //9键按下
}
if ((P4 | 0xf0) == 0xfb) //1111 1011
{
flag = 0;
key_value = 10; //. 键按下
}
if ((P4 | 0xf0) == 0xf7) //1111 0111
{
flag = 0;
key_value = 11; //=键按下
}
break;
}
case(3): //扫描第四行
{
_74HC164(0x17); //0001 0111
if ((P4 | 0xf0) == 0xfe) //1111 1110
{
flag = 0;
key_value = 12; //F1键按下
}
if ((P4 | 0xf0) == 0xfd) //1111 1101
{
flag = 0;
key_value = 13; //F2键按下
}
if ((P4 | 0xf0) == 0xfb) //1111 1011
{
flag = 0;
key_value = 14; //F3键按下
}
if ((P4 | 0xf0) == 0xf7) //1111 0111
{
flag = 0;
key_value = 15; //F4键按下
}
break;
}
case(4):
{
_74HC164(0x0f); //0000 1111
if ((P4 | 0xf0) == 0xfe) //1111 1110
{
flag = 0;
key_value = 16; //F5键按下
}
if ((P4 | 0xf0) == 0xfd) //1111 1101
{
flag = 0;
key_value = 17; //F6键按下
}
if ((P4 | 0xf0) == 0xfb) //1111 1011
{
flag = 0;
key_value = 18; //F7键按下
}
if ((P4 | 0xf0) == 0xf7) //1111 0111
{
flag = 0;
key_value = 19; //F8键按下
}
break;
}
}
}
}
}
if(flag) return 20; //没按键,返回20
else
_74HC164(0x00);
while (((P4 | 0xf0)) != 0xff) //等待按键松开
{
switch(keyst)
{
case(1): //显示按键前的时分秒界面
display1();
break;
case(2): //显示按键前的星期界面
display2();
break;
case(3): //显示按键前的年月日界面
display3();
break;
case(4): //显示按键前的闹钟设置界面
display4(state[6]);
break;
}
}
return key_value; //返回键值
}
//////////////////////////////////////////////////////////////////////////////
//// 时分秒控制程序 ////
//////////////////////////////////////////////////////////////////////////////
void time()
{
WDTCN=0xa5; //喂狗
if(sec == 60) //若秒为60
{
sec = 0; //秒回0
min++; //分加一
if(min == 60) //若分为60
{
min = 0; //分回0
hour++; //时加一
if(hour == 24) //若时为24
{
hour = 0; //时回0
ymd(); //日期进位
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
//// 星期控制程序 ////
//////////////////////////////////////////////////////////////////////////////
void week()
{
uchar monz; //蔡勒公式下的"月"
uchar decade = year % 100; //取年的低二位
uchar century = year / 100; //取年的高二位
WDTCN=0xa5; //喂狗
if(month == 1) //若为1月
{
monz = 13; //1月修正为前一年的"13月"
if(decade == 0) //若是xx00年
{
decade = 99;
century--; //高二位减一
}
else decade--; //若不是00年,低二位减一
}
else if(month == 2) //若为2月
{
monz = 14; //2月修正为前一年的"14月"
if(decade == 0) //若是xx00年
{
decade = 99; //年的低二位变为99
century--; //高二位减一
}
else decade--; //若不是00年,低二位减一
}
else monz = month; //3-12月正常
wkday=(((decade+(decade/4)+(century/4)-2*century+13*(monz+1)/5)+day-1+70)%7); //蔡勒公式计算今天是礼拜几
if(wkday == 0) wkday = 7; //蔡勒公式运算结果0作为周日
}
//////////////////////////////////////////////////////////////////////////////
//// 年月日控制程序 ////
//////////////////////////////////////////////////////////////////////////////
void ymd()
{
day++; //日加一
WDTCN=0xa5; //喂狗
if((month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 8) || (month == 10) || (month == 12))
{ //一三五七八十腊
if(day == 32) //三十一天永不差
{
day = 1;
month++;
if(month == 13) //12月进位回1月
{
month = 1;
year++; //年加一
}
}
}
if((month == 4) || (month == 6) || (month == 9) || (month == 11))
{ //四、六、九、十一
if(day == 31) //三十天
{
day = 1;
month++;
}
}
if(month == 2) //判断平年还是闰年
{
if((year % 100) != 0) //判断年份是否为100的倍数
{
if((year % 4) == 0) //不是100的倍数且是4的倍数,是闰年
{
if(day == 30) //闰年二月二十九
{
day = 1;
month++;
}
}
if((year % 4) != 0) //不是4的倍数,是平年
{
if(day == 29) //平年二月二十八
{
day = 1;
month++;
}
}
}
if((year % 100) == 0) //年份是100的倍数
{
if((year % 400) == 0) //是100的倍数且是400的倍数,是闰年
{
if(day == 30) //闰年二月二十九
{
day = 1;
month++;
}
}
else //是100的倍数且不是400的倍数,是平年
{
if(day == 29) //平年二月二十八
{
day = 1;
month++;
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
//// 时分秒显示程序 ////
//////////////////////////////////////////////////////////////////////////////
void display1()
{
uchar c = 0; //循环变量
WDTCN=0xa5; //喂狗
P3_5 = 0; //蜂鸣器关
for(; c < 7; c++)
{
switch(c)
{
case(0): //选中第一个数码管
{
P3_0 = 0;
P3_1 = 0;
P3_2 = 1;
P2 = num[sec % 10]; //显示秒个位
break;
}
case(1): //选中第二个数码管
{
P3_0 = 1;
P3_1 = 0;
P3_2 = 1;
P2 = num[sec / 10]; //显示秒十位
break;
}
case(2): //选中第三个数码管
{
P3_0 = 0;
P3_1 = 1;
P3_2 = 1;
P2 = num[min % 10] + 0x01; //显示分个位加.
break;
}
case(3): //选中第四个数码管
{
P3_0 = 1;
P3_1 = 1;
P3_2 = 1;
P2 = num[min / 10]; //显示分十位
break;
}
case(4): //选中第五个数码管
{
P3_0 = 0;
P3_1 = 0;
P3_2 = 0;
P2 = num[hour % 10] + 0x01; //显示时个位加.
break;
}
case(5): //选中第六个数码管
{
P3_0 = 1;
P3_1 = 0;
P3_2 = 0;
P2 = num[hour / 10]; //显示时十位
break;
}
case(6): //选中第八个数码管
if(suichi[0] == 0) //若整点报时关
{
P3_0 = 1;
P3_1 = 1;
P3_2 = 0;
P2 = 0x01; //显示. 示意整点报时关
break;
}
}
delay(1); //延时
P2 = 0x00; //数码管消隐
}
}