基于51单片机数码管万年历按键可调(Proteus仿真设计)

基于51单片机数码管万年历按键可调(Proteus仿真设计)


在这里插入图片描述

  • AT89C5274S37374L138
  • Proteus仿真

实例代码

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
#include<reg51.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
//#define ture 1
//#define fault 0

sbit SET=P1^7;

void delay(uchar k);
uchar monthday(uchar a,uchar b);
void display();

uchar code dayofmonth[]={31,28,31,30,31,30,31,31,30,31,30,31};
uchar code scan[]={0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,
0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
0xf8,0xf9,0xfa,0xfb,0xfc,0xfd}; //扫描的译码信号
uchar i;
uchar code table[]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0xC0}; //段码表
uchar buffer[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uchar shuju=0;
uchar state=0;
uchar qxiang;

typedef struct
{
uchar year[2];
uchar month;
uchar day;
uchar week;
}date;
typedef struct
{
uchar hour;
uchar minute;
uchar second;
}time;
uchar count=0;
date today={{18,20},11,14,3}; //设置日期初值
time now={14,30,00}; //设置时间初值
void main()
{
TMOD=0x01;
TL0=(65536-1000)%256;
TH0=(65536-1000)/256;
IE=0x82; //EA=1;ET0=1总中断允许和定时器中断允许
TR0=1; //定时器启动计数
display();
while(1)
{
P1=0xff;
shuju=P1&0xff;
qxiang=shuju&0x80;
switch(qxiang)
{
case(0x80):switch(shuju)
{
case(0xfe) : //秒调整
{
EA=1;
EX0=1; //总中断允许,外中断0允许
IT0=1; //中断0为负跳变触发
}break;
case(0xfd) : //分调整
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0xfb) : //时调整
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0xf7) : //星期调整
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0xef) : //日调整
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0xdf): //月调整
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0xbf): //年调整
{
EA=1;
EX0=1;
IT0=1;
}break;
default: //时钟正常计时
{
EA=1;
TR0=1;
EX0=0;
}break;
}break;
case(0x00) :switch(shuju)
{
case(0x7e):
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0x7d):
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0x7b):
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0x77):
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0x6f):
{
EA=1;
EX0=1;
IT0=1;

}break;
case(0x5f):
{
EA=1;
EX0=1;
IT0=1;
}break;
case(0x3f):
{
EA=1;
EX0=1;
IT0=1;
}break;
default:
{
EA=1;
TR0=1;
EX0=0;
}break;
}break;
}
}
}

void int0() interrupt 0 using 0 //中断服务程序,调节时间
{
uchar result,z;
result=shuju;
switch(qxiang)
{
case(0x80): switch(result)
{
case(0xfe) : //秒调整 +
{
now.second++;
if(now.second>=60)
{
now.second=0;
}
display();
}break;
case(0xfd) : //分调整 +
{
now.minute++;
if(now.minute>=60)
{
now.minute=0;
}
display();
}break;
case(0xfb) : //时调整 +
{
now.hour++;
if(now.hour>=24)
{
now.hour=0;
}
display();
}break;
case(0xf7) : //星期调整 +
{
today.week++;
if(today.week>=8)
{
today.week=1;
}
display();
}break;
case(0xef) : //日调整 +
{
today.day++;
z = monthday(today.year[1],today.year[0]);
if((z==1)&&(today.month==2))
{
if(today.day>=30)
today.day=1;
}
else if (today.day>dayofmonth[today.month-1])
today.day=1;
display();
}break;
case(0xdf) : //月调整 +

{
today.month++;
if(today.month>=13)
{
today.month=1;
}
display();
} break;
case(0xbf) : //年调整 +
{
today.year[0]=today.year[0]+1;
if(today.year[0]>=100)
{
today.year[0]=0;
today.year[1]=today.year[1]+1;
if(today.year[1]>=100)
{
today.year[1]=0;
}
}
display();
}break;
default: //时钟正常计时
{
EA=1;
TR0=1;
EX0=0;
}break;
}break;
case(0x00): switch(result)
{
case(0x7e): //秒调整-
{
if(now.second>0)
now.second=now.second-1;
else now.second=59;
display();
}break;
case(0x7d): //分调整-
{
if(now.minute>0)
now.minute=now.minute-1;
else now.minute=59;
display();
}break;
case(0x7b) : // 时调整-
{
if(now.hour>0)
now.hour=now.hour-1;
else now.hour=23;
display();
}break;
case(0x77) : // 周调整-
{
if(today.week>1)
today.week=today.week-1;
else today.week=7;
display();
}break;
case(0x6f): // 日调整-
{
z = monthday(today.year[1],today.year[0]);
if((z==1)&&(today.month==2))
{
if(today.day>1)
today.day=today.day-1;
else today.day=29;
}
else {
if(today.day>1)
today.day=today.day-1;
else today.day=dayofmonth[today.month-1];
}
display();
}break;
case(0x5f): // 月调整-
{
if(today.month>1)
today.month=today.month-1;
else today.month=12;
display();
}break;
case(0x3f) : // 年调整-
{
if(today.year[0]>0)
today.year[0]=today.year[0]-1;
else
{
today.year[0]=99;
today.year[1]=today.year[1]-1;
}
display();
}break;
default: //时钟正常计时
{
EA=1;
TR0=1;
EX0=0;
}break;
}break;
}
}
//定时器中断程序
void timer0\_int() interrupt 1 using 1
{
uchar c;
TL0=(65536-1000)%256;
TH0=(65536-1000)/256;
TR0=1;
count++;
if(count==35)
{
count=0;
now.second=now.second+1;
if(now.second>=60)
{
now.second=0;
now.minute++;
if(now.minute>=60)
{
now.minute=0;
now.hour++;
if(now.hour>=24)
{
now.hour=0;
today.week++;
today.day++;
if(today.week>=8)
{
today.week=1;
}
c=monthday( today.year[1], today.year[0]);
if((c==1)&&(today.month==2))
{
if(today.day>=30)
{
today.day=1;
today.month++;
}
}
else if(today.day>=(dayofmonth[today.month-1]+1))
{
today.day=1;
today.month++;
if(today.month>=13)
{
today.month=1;
today.year[0]=today.year[0]+1;
if(today.year[0]>=100)
{
today.year[0]=0;
today.year[1]=today.year[1]+1;
if(today.year[1]>=100)
{
today.year[1]=0;
}
}
}
}
}
}
}
}
display();
}
//延时程序
void delay(uchar k)
{
uchar m,n;
for(m=0;m<=k;m++)
for(n=0;n<=40;n++);
}
//闰年判断程序
uchar monthday(uchar a,uchar b)
{
uchar x,y;
x=a\*100+b;
if(x%4!=0)
y=0;
else if(x%100!=0)
y=1;
else if(x%400!=0)
y=0;
else y=1;
return(y);
}
//扫描显示程序
void display()
{
buffer[0]=now.second%10;
buffer[1]=now.second/10;
buffer[2]=10;
buffer[3]=now.minute%10;
buffer[4]=now.minute/10;
buffer[5]=10;
buffer[6]=now.hour%10;
buffer[7]=now.hour/10;
buffer[8]=today.week%10;
buffer[9]=today.week/10;
buffer[10]=10;
buffer[11]=today.day%10;
buffer[12]=today.day/10;
buffer[13]=10;
buffer[14]=today.month%10;
buffer[15]=today.month/10;
buffer[16]=10;
buffer[17]=today.year[0]%10;
buffer[18]=today.year[0]/10;
buffer[19]=today.year[1]%10;
buffer[20]=today.year[1]/10;
buffer[21]=10;
for(i=0;i<=21;i++)
{
P0=table[buffer[i]];
P2=scan[i];
delay(3);//如果数码出现闪烁,可调整该延时来修正。
P0=0x00;
}
}

  • absacc.h头文件代码
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
/\*--------------------------------------------------------------------------
ABSACC.H

Direct access to 8051, extended 8051 and NXP 8051MX memory areas.
Copyright (c) 1988-2010 Keil Elektronik GmbH and ARM Germany GmbH
All rights reserved.
--------------------------------------------------------------------------\*/

#ifndef \_\_ABSACC\_H\_\_
#define \_\_ABSACC\_H\_\_

#define CBYTE ((unsigned char volatile code \*) 0)
#define DBYTE ((unsigned char volatile data \*) 0)
#if !defined (\_\_CX2\_\_)
#define PBYTE ((unsigned char volatile pdata \*) 0)
#endif
#define XBYTE ((unsigned char volatile xdata \*) 0)

#define CWORD ((unsigned int volatile code \*) 0)
#define DWORD ((unsigned int volatile data \*) 0)
#if !defined (\_\_CX2\_\_)
#define PWORD ((unsigned int volatile pdata \*) 0)
#endif
#define XWORD ((unsigned int volatile xdata \*) 0)


#if defined (\_\_CX51\_\_) || defined (\_\_CX2\_\_)
#define FVAR(object, addr) (\*((object volatile far \*) (addr)))
#define FARRAY(object, base) ((object volatile far \*) (base))
#define FCVAR(object, addr) (\*((object const far \*) (addr)))
#define FCARRAY(object, base) ((object const far \*) (base))
#else
#define FVAR(object, addr) (\*((object volatile far \*) ((addr)+0x10000L)))
#define FCVAR(object, addr) (\*((object const far \*) ((addr)+0x810000L)))
#define FARRAY(object, base) ((object volatile far \*) ((base)+0x10000L))
#define FCARRAY(object, base) ((object const far \*) ((base)+0x810000L))
#endif

#if defined (\_\_CX2\_\_)
#define HBYTE ((unsigned char volatile huge \*) 0)
#define HWORD ((unsigned int volatile huge \*) 0)
#define HVAR(object, addr) (\*((object volatile huge \*) (addr)))
#define HARRAY(object, base) ((object volatile huge \*) (base))
#endif

#define CVAR(object, addr) (\*((object volatile code \*) (addr)))
#define CARRAY(object, base) ((object volatile code \*) (base))
#define DVAR(object, addr) (\*((object volatile data \*) (addr)))
#define DARRAY(object, base) ((object volatile data \*) (base))
#define XVAR(object, addr) (\*((object volatile xdata \*) (addr)))
#define XARRAY(object, base) ((object volatile xdata \*) (base))

#endif


资源链接

1
2
3
baidu链接:https://pan.baidu.com/s/1kKh4-tC3v6Xs-r6960FKZw 
提取码:1uja