This repository has been archived by the owner on Sep 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEXP5.1.ASM
656 lines (624 loc) · 11.4 KB
/
EXP5.1.ASM
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
ORG 0000H
NUM1 EQU 30H
NUM2 EQU 40H
NUMPOI EQU 2
MOV IE,#00000000B
MOV SP,#0E0H
MOV R0,#28H
LCALL CLEAR
MOV R0,#NUM1
LCALL CLEAR
MOV R0,#37H
LCALL CLEAR
MOV R0,#NUM2
LCALL CLEAR
MOV R0,#57H
LCALL CLEAR
MOV B,#00H
BEGIN:
SETB F0
CLR RS1
CLR RS0
KEY_SCAN: ;键盘扫描使用P1口,P1.4-P1.7为列扫描,P1.0-P1.3为行扫描
MOV P1,#0F0H
JNB P1.4, LIE4
JNB P1.5, LIE3
JNB P1.6, LIE2
JNB P1.7, LIE1
LCALL DISP_LED
SJMP KEY_SCAN
LIE1:
MOV R4,#01H
LJMP JUDGELIE
LIE2:
MOV R4,#02H
LJMP JUDGELIE
LIE3:
MOV R4,#03H
LJMP JUDGELIE
LIE4:
MOV R4,#04H
LJMP JUDGELIE
JUDGELIE:
MOV P1,#0FH
JNB P1.0, HANG4
JNB P1.1, HANG3
JNB P1.2, HANG2
JNB P1.3, HANG1
LJMP KEY_SCAN
HANG1:
LCALL DEL20MS
JB P1.3, KEY_SCAN
HANG1REL:
LCALL DEL20MS
JNB P1.3, HANG1REL
MOV R5,#01H
LJMP KEY_END
HANG2:
LCALL DEL20MS
JB P1.2, KEY_SCAN
HANG2REL:
LCALL DEL20MS
JNB P1.2, HANG2REL
MOV R5,#02H
LJMP KEY_END
HANG3:
LCALL DEL20MS
JB P1.1, KEY_SCAN
HANG3REL:
LCALL DEL20MS
JNB P1.1, HANG3REL
MOV R5,#03H
LJMP KEY_END
HANG4:
LCALL DEL20MS
JB P1.0, KEY_SCAN
HANG4REL:
LCALL DEL20MS
JNB P1.0, HANG4REL
MOV R5,#04H
LJMP KEY_END
KEY_END:
JNB F0,KEYOLD
;MOV R0,#NUM1
;LCALL CLEAR
CLR F0
KEYOLD:
MOV A,R5
DEC A
PUSH B
MOV B,#04H
MUL AB
ADD A,R4
DEC A ;计算键值在表中的偏移量
POP B
MOV DPTR,#KEY_TABLE ;查表获得实际按键
MOVC A,@A+DPTR
CJNE A,#0EH,KEY_OPER
MOV A,B
JNZ ALLCLRHELP
JZ SINCLRHELP
ALLCLRHELP:
LCALL ALLCLR
LJMP KEYEND
SINCLRHELP:
LCALL SINCLR
LJMP KEYEND
KEY_OPER:
CJNE A,#0FH,KEY_NEXT
MOV B,#01H
LJMP CAL
KEY_NEXT:
CLR C
CJNE A,#09H,ISOPER
ISNUM:
PUSH A
MOV A,B
JNZ ALLCLRNUM
LJMP NOCLRNUM
ALLCLRNUM:
LCALL ALLCLR
NOCLRNUM:
CLR RS1
SETB RS0
MOV R0,#38H
MOV R1,#37H
MOV R2,#08H
LCALL RLCBIT
CLR RS1
CLR RS0
POP A
MOV NUM1,A
INC R0
CJNE R0,#19H,KEYEND
MOV R0,#NUM1
LJMP KEYEND
ISOPER:
JC ISNUM
CLR C
SUBB A,#10
PUSH A
CLR RS1
SETB RS0
MOV R0,#30H
MOV R1,#40H
LCALL MEMMOVE
CLR RS1
CLR RS0
MOV R0,#NUM1
LCALL CLEAR
LJMP KEYEND
KEYEND:
LJMP KEY_SCAN
ALLCLR:
CLR RS1
CLR RS0
MOV R0,#NUM1
LCALL CLEAR
MOV B,#00H
RET
SINCLR:
CLR RS1
SETB RS0
MOV R0,#31H
MOV R1,#30H
MOV R2,#08H
LCALL RRCBIT
CLR RS1
CLR RS0
;LCALL CLEAR
RET
KEY_TABLE: ;0AH:+ 0BH:- 0CH:x 0DH:/ 0EH:* 0FH:#
DB 01H,02H,03H,0AH,04H,05H,06H,0BH,07H,08H,09H,0CH,0EH,00H,0FH,0DH
;R0为清空的开始位,CLEAR子程序将从R0开始的8位数码清空
CLEAR:
MOV A,R0
MOV R1,A
MOV R2,#09H
CLOOP:MOV @R1,#00H
INC R1
DJNZ R2,CLOOP
RET
DISP_LED:
MOV R1,#37H ;数码管显示内存初始地址
MOV R3,#00H
MOV R2,#09H ;数码管需要显示的位数+1
CLR F1
CLR C
MOV A,37H
CJNE A,#0FH,JUDERR
LJMP NOERR ;数码管显示逸出错误处理,设置最大位数为7位
JUDERR:
JZ NOERR
JNC NOERR
LCALL SHOWERR
SETB F0
CLR RS1
CLR RS0
RET
LEDLOOP: ;数码管显示主程序
NOERR:
MOV DPTR,#TND ;获取将要点亮的数码管段
MOV A,@R1
JZ JUGZERO ;数码管灭零、单零显示程序
CJNE A,#0EFH,SHOWPOINT ;数码管小数点显示判跳
SHOWON:
CJNE A,#17,NOTSHOWZ ;数码管负号判断显示
MOVC A,@A+DPTR
MOV P3,A
LJMP SHOWWEI
SHOWPOINT: ;数码管小数点显示主程序
JC SHOWON
SETB F1
CLR C
SUBB A,#0F0H
MOV DPTR,#TD
MOVC A,@A+DPTR
MOV P3,A
LJMP SHOWWEI
NOTSHOWZ: ;数码管灭零、单零判断显示主程序
MOVC A,@A+DPTR
MOV P3,A
SETB F1
LJMP SHOWWEI
JUGZERO:
JB F1,SHOWZERO
MOV P3,#0FFH
LJMP SHOWWEI
SHOWZERO:
MOV A,#00H
MOVC A,@A+DPTR
MOV P3,A
SHOWWEI:
MOV DPTR,#TWEI ;获取将要点亮的数码管位信息
MOV A,R3
MOVC A,@A+DPTR
MOV P2,A
DEC R1 ;数码管段和位偏移量自增
INC R3
DJNZ R2,GOON ;判断是否完成对8位数码的完整扫描,如果未完成则继续GOON
JNB F1,ONEZERO
RET
ONEZERO: ;数码管单零显示
MOV DPTR,#TND
MOV A,#00H
MOVC A,@A+DPTR
MOV P3,A
LCALL DELAY
RET ;如果已经完成了完整扫描,则重新开始扫描
GOON:
LCALL DELAY ;调用DELAY函数配合视觉暂留,实现多位数码管同时显示
AJMP LEDLOOP
DELAY:
mov r5,#20
d1:mov r6,#10
d2:mov r7,#5
djnz r7,$
djnz r6,d2
djnz r5,d1
ret
DEL20MS:
mov r6,#100
d4:mov r7,#100
djnz r7,$
djnz r6,d4
ret
RLCBIT:
RLCLOOP:
MOV A,@R1
MOV @R0,A
DEC R0
DEC R1
DJNZ R2,RLCLOOP
MOV @R0,#00H
RET
RRCBIT:
RRCLOOP:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R2,RRCLOOP
MOV @R0,#00H
RET
CAL:
POP A
CJNE A,#04H,CALJUDG
CALJUDG:
MOV R7,A
JNC CALCERR
RL A
ADD A,R7
MOV DPTR,#CALC
JMP @A+DPTR
CALCERR:
PUSH A
LJMP BEGIN
CALC:
LJMP PLUS
LJMP MINUS
LJMP MULTI
LJMP DIVIDE
SJMP $
;使用寄存器R0,R1,R3,将40H,30H开始的数码相加,结果存入30H
PLUS:
SETB RS1
CLR RS0
MOV R0,#40H ;十进制数存放地址初始化
MOV R1,#30H
MOV R3,#08H ;字节长度初始化
LCALL PLUSFUN
CLR RS1
SETB RS0
MOV R0,#40H
MOV R1,#30H
LCALL MEMMOVE
LJMP BEGIN
;加法计算子程序,注意,使用前需要初始化寄存器R0,R1,R3, R0存被加数,R1存加数, 结果存R0开始的单元
PLUSFUN:
CLR C
PLUSLOOP: ;从50H开始循环遍历十进制数的各个数位
MOV A,@R0
ADDC A,@R1
DA A ;十进制数数位相加,进行二-十进制调整
MOV @R0,A ;暂存十进制数数位相加结果
CLR C ;清空CY,为接下来的判断做准备
SUBB A, #10H
JNC PLUSFIX ;判断数位相加是否大于等于10,若条件满足则进位,否则清空CY标志位
CLR C
LJMP PLUSFIN
PLUSFIX:
MOV @R0,A ;CY置位,为进位做准备
SETB C
PLUSFIN:
INC R0 ;循环遍历
INC R1
DJNZ R3,PLUSLOOP
RET
;使用寄存器R0,R1,R3,将40H,30H开始的数码相减,结果存入30H
MINUS:
SETB RS1
CLR RS0
MOV R0,#40H ;十进制数存放地址初始化
MOV R1,#30H
MOV R3,#08H ;字节长度初始化
SETB RS1
SETB RS0
MOV R0,#47H
MOV R1,#37H
MOV R2,#08H
LCALL GETMAX
MOV A,R4
JNZ DOSWAP
JZ NOSWAP
DOSWAP:
SETB RS1
CLR RS0
MOV R0,#30H
MOV R1,#40H
LJMP MINUSCAL
NOSWAP:
SETB RS1
CLR RS0
MOV R0,#40H
MOV R1,#30H
LJMP MINUSCAL
MINUSCAL:
LCALL MINUSFUN
SETB RS1
SETB RS0
MOV A,R4
JZ MEM1
JNZ MEM2
MEM1:
CLR RS1
SETB RS0
MOV R0,#40H
MOV R1,#30H
LCALL MEMMOVE
LJMP BEGIN
MEM2:
MOV 37H,#17
LJMP BEGIN ;程序结束
;减法计算子程序,注意,使用前需要初始化寄存器R0,R1,R3, R0存被减数, R1存减数, R3存数码个数
MINUSFUN:
CLR C
MINUSLOOP: ;从50H开始循环遍历十进制数的各个数位
MOV A,@R0
MINUSCON:
SUBB A,@R1
JC MINUSFIX
MOV @R0,A ;暂存十进制数数位相加结果
LJMP MINUSFIN
MINUSFIX:
ADD A,#10
MOV @R0,A
LJMP MINUSFIN
MINUSFIN:
INC R0 ;循环遍历
INC R1
DJNZ R3,MINUSLOOP
RET
;使用寄存器R0,R1,R3,将40H,30H开始的数码相乘,结果存入30H
MULTI:
SETB RS1
CLR RS0
MOV R0,#40H
MOV R1,#30H
MOV R3,#08H
SETB RS1
SETB RS0
MOV R0,#47H
MOV R1,#37H
MOV R2,#08H
LCALL GETMAX
MOV A,R4
JNZ MULSWAP
JZ MULGOON
MULSWAP:
CLR RS1
SETB RS0
MOV R0,#30H
MOV R1,#50H
LCALL MEMMOVE
MOV R0,#40H
MOV R1,#30H
LCALL MEMMOVE
MOV R0,#50H
MOV R1,#40H
LCALL MEMMOVE
MULGOON:
CLR RS1
SETB RS0
MOV R0,#30H
MOV R1,#50H
LCALL MEMMOVE
MOV R0,#40H
MOV R1,#30H
LCALL MEMMOVE
MOV R0,#60H
LCALL CLEAR
MOV 60H,#1
MOV R0,#40H
LCALL CLEAR
MULTILOOP:
CLR RS1
SETB RS0
MOV R0,#50H
LCALL ISZERO
MOV A,R4
JNZ MINFIN
SETB RS1
CLR RS0
MOV R0,#40H
MOV R1,#30H
MOV R3,#08H
LCALL PLUSFUN
MOV R0,#50H
MOV R1,#60H
MOV R3,#08H ;字节长度初始化
LCALL MINUSFUN
LJMP MULTILOOP
MINFIN:
CLR RS1
SETB RS0
MOV R0,#40H
MOV R1,#30H
LCALL MEMMOVE
LJMP BEGIN
;使用寄存器R0,R1,R3,将40H,30H开始的数码相除,结果存入30H
DIVIDE:
CLR RS1
SETB RS0
MOV R0,#30H
LCALL ISZERO
MOV A,R4
JNZ DIVERR
JZ DIVNOERR
DIVERR:
LCALL SHOWERR
LJMP BEGIN
DIVNOERR:
CLR RS1 ;商和余数寄存器初始化
SETB RS0
MOV R0,#48H
LCALL CLEAR
MOV R0,#60H
LCALL CLEAR
MOV R0,#70H
LCALL CLEAR
MOV 70H,#1
CLR RS1
SETB RS0
MOV R7,#NUMPOI
RBITLOOP:
MOV R0,#48H
MOV R1,#47H
MOV R2,#08H ;移动次数
LCALL RLCBIT
DJNZ R7,RBITLOOP
;除法主程序
SETB RS1
CLR RS0
MOV R5,#00H
DIVIDELOOP:
DIVLESS:
SETB RS1
SETB RS0
MOV R0,#4FH
MOV R1,#37H
MOV R2,#08H
LCALL GETMAX
MOV A,R4 ;交换过顺序,A变为1
JZ DIVCALCLOOP
SETB RS1
CLR RS0
CJNE R5,#08H,DIVON
LJMP DIVEND
DIVON:
CLR RS1
SETB RS0
MOV R0,#50H
MOV R1,#4FH
MOV R2,#16
LCALL RLCBIT
MOV R0,#68H
MOV R1,#67H
MOV R2,#8
LCALL RLCBIT
SETB RS1
CLR RS0
INC R5
CJNE R5,#09H,DIVLESS
LJMP DIVEND
;JNZ DIVIDELOOP
DIVCALCLOOP:
SETB RS1
CLR RS0
MOV R0,#48H
MOV R1,#30H
MOV R3,#08H ;字节长度初始化
LCALL MINUSFUN
MOV R0,#60H
MOV R1,#70H
MOV R3,#08H
LCALL PLUSFUN
LJMP DIVLESS
DIVEND:
MOV A,#60H
ADD A,#NUMPOI
MOV R0,A
MOV A,@R0
ADD A,#0F0H
MOV @R0,A
CLR RS1
SETB RS0
MOV R0,#60H
MOV R1,#30H
LCALL MEMMOVE
MOV B,#01H
LJMP BEGIN
GETMAX:
GETLOOP:
MOV A,@R0
CLR C
SUBB A,@R1
JC GETFINAL
JNZ GET2
DEC R0
DEC R1
DJNZ R2,GETLOOP
LJMP GET2
GETFINAL: ;如果是负数,则交换相减顺序
MOV R4,#01H
RET
GET2:
MOV R4,#00H
RET
ISZERO:
MOV A,R0
MOV R1,A
MOV R2,#08H
ZEROLOOP:MOV A,@R1
DEC R2
INC R1
CJNE R2,#00H,ZERO2
MOV R4,#01H
RET
ZERO2:
JZ ZEROLOOP
MOV R4,#00H
RET
SHOWERR:
MOV R1,#70H
MOV R2,#08H
ERRLOOP:
MOV @R1,#0FH
INC R1
DJNZ R2,ERRLOOP
CLR RS1
SETB RS0
MOV R0,#70H
MOV R1,#30H
LCALL MEMMOVE
CLR RS1
CLR RS0
MOV B,#01H
RET
;MEMMOVE 将R0开头的数据移动到R1开始的存储单元,数据共8位
MEMMOVE:
MOV R2,#09H
MEMLOOP:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R2,MEMLOOP
RET
;AT89C51数码管0-9,A-F编码表,不含小数点,P3口输出
TND: DB 28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60H,30H,25H,0A9H,26H,0A1H,0B1H,0FFH,0F7H
;AT89C51数码管位选编码表
TWEI: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH
TWEID: DB 07FH,0BFH,0DFH,0EFH,0F7H,0FBH,0FDH,0FEH
;AT89C51数码管0-9,A-F编码表,含小数点,P3口输出
TD: DB 08H,5EH,82H,42H,54H,41H,01H,5AH,00H,40H,10H,05H,89H,06H,81H,91H