2.1 设计思路
首先使用8255、8254、8259 三个芯片实现电子时钟的功能,让闹钟可以正常走时;其次,在时钟的基础上添加闹铃功能、整点报时功能、设置当前时间功能;完成设计。
2.2 设计方案
1. 电子时钟部分:此次设计是通过对计数器8254设定计数值对脉冲进行计数,在程序里,8254工作于计数器0,方式3。接入的CLK为1MHz,设计数初值为10000,每100次中断计数一次,产生的记数时间正好是时钟每秒走过的时间。通过对中断控制器8259设置初始化命令字初值来控制中断。程序中通过移位指令来实现时、秒、分的个位和十位的独自存储,将分、秒的个位十位分别存入指定的寄存器中。比较转移指令来完成秒和分的累加。七段数码管由8255并行接口的A口进行位的选择,通过B口输出要显示的段码。这样就在6个七段数码管上分别显示时、分和秒。当1S时间到时,修改当前数码管数值,10秒时将秒的低位清零,高位加1,分和时亦是如此;到达60秒时,将秒清零,分加1,到达60分时,将分清零,小时加1,到达24小时则全部清零。
2. 闹钟响铃部分:对于闹钟部分,我们首先要完成数码管显示单元按键的连接和设计,让16个按键分别为0-F;再利用实验平台的单次脉冲输入KK1产生一次中断,这样就可以设置时间了。将设置好的时间储存起来,时刻与当前的时间进行比较,当时间一样时,计数器1工作,蜂鸣器蜂鸣,播放音乐,这就完成了闹钟响铃功能。
3. 整点报时部分:整点报时,就是在整时的时候响一次铃,当时钟整点时,无论是几点,时钟的分和秒部分都为零,所以,只要让时钟的分和秒部分与零进行比较,当他们都相等时,就代表到达整点了,可以响铃了。整点报时就完成了,本闹钟设置的整点报时时长为5秒。
4. 设置当前时间:本部分也用到了数码管显示单元的按键部分,只要利用之前的设计就好了,这次使用单次脉冲输入的KK2产生中断设置时间,再将设置的时间存储在时间变量中,时间就设置好了。
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
678A8254 EQU 06C0H ;宏定义 B8254 EQU 06C2H C8254 EQU 06C4H CON8254 EQU 06C6H MY8255_A EQU 0600H MY8255_B EQU 0602H MY8255_C EQU 0604H MY8255_CON EQU 0606H PUBLIC SEC,MIN,HOUR DATA SEGMENT ;定义数据段 TAB DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H ;数码表 DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H FREQ_LIST DW 371,495,495,495,624,556,495,556,624 ;频率表 DW 495,495,624,742,833,833,833,742,624 DW 624,495,556,495,556,624,495,416,416,371 DW 495,833,742,624,624,495,556,495,556,833 DW 742,624,624,742,833,990,742,624,624,495 DW 556,495,556,624,495,416,416,371,495,0 TIME_LIST DB 4, 6, 2, 4, 4, 6, 2, 4, 4 ;时间表 DB 6, 2, 4, 4, 12, 1, 3, 6, 2 DB 4, 4, 6, 2, 4, 4, 6, 2, 4, 4 DB 12, 4, 6, 2, 4, 4, 6, 2, 4, 4 DB 6, 2, 4, 4, 12, 4, 6, 2, 4, 4 DB 6, 2, 4, 4, 6, 2, 4, 4, 12 SEC DB 0 ;初始化 HOUR DB 0 MIN DB 0 N_TIME DB 20 DUP(0) Z_TIME DB 20 DUP(0) N_S DB 30 N_M DB 0 N_H DB 0 TIMER DB 10 DUP(0) DUAN DB 0 BUF DB 3 DUP(0) DATA ENDS SSTACK SEGMENT STACK ;堆栈段 DW 256 DUP(?) SSTACK ENDS CODE SEGMENT ;代码段 ASSUME CS:CODE, SS:SSTACK,DS:DATA START: ;8254初始化 MOV DX, CON8254 ;8254 MOV AL, 36H ;计数器0,方式3 OUT DX, AL ;分频 MOV DX, A8254 MOV AL, 010H OUT DX, AL MOV AL, 27H OUT DX, AL ;8255初始化 MOV AL,81H MOV DX,MY8255_CON OUT DX,AL ;MIR7中断 MOV AX, 0000H MOV DS, AX MOV AX, OFFSET MIR7 ;取中断入口地址 MOV SI, 003CH ;中断矢量地址 MOV [SI], AX ;填IRQ7的偏移矢量 MOV AX, SEG MIR7 ;段地址 MOV SI, 003EH MOV [SI], AX ;填IRQ7的段地址矢量 ;MIR6中断 MOV AX, OFFSET MIR6 ;取中断入口地址 MOV SI, 0038H ;中断矢量地址 MOV [SI], AX ;填IRQ6的偏移矢量 MOV AX, SEG MIR6 ;段地址 MOV SI, 003AH MOV [SI], AX ;填IRQ6的段地址矢量 ;MIR2中断 MOV AX, OFFSET SIR1 ;取中断入口地址 MOV SI, 00C4H ;中断矢量地址 MOV [SI], AX ;填SIR1的偏移矢量 MOV AX, SEG SIR1 ;段地址 MOV SI, 00C6H MOV [SI], AX ;填SIR1的段地址矢量 ;8259初始化 MOV AL, 11H OUT 20H, AL ;ICW1 MOV AL, 08H OUT 21H, AL MOV AL,04H OUT 21H,AL ;ICW2 MOV AL, 03H OUT 21H, AL ;ICW4 ;初始化从片8259 MOV AL, 11H OUT 0A0H, AL ;ICW1 MOV AL, 30H OUT 0A1H, AL ;ICW2 MOV AL, 02H OUT 0A1H, AL ;ICW3 MOV AL, 01H OUT 0A1H, AL ;ICW4 MOV AL, 0FDH OUT 0A1H,AL ;OCW1 = 1111 1101 MOV AX,SEG N_TIME ;取N_TIME的段地址 MOV DS,AX MOV SI,OFFSET N_TIME ;取N_TIME的地址偏移量 MOV [SI+1],1 STI AA1: CALL DISP ;调用显示子程序(disp) CALL BJ ;调用闹钟(bj) CALL ZDBS ;调用整点报时(bj) JMP AA1 MIR6 PROC CLI PUSH AX PUSH SI MOV AX,DATA MOV DS,AX MOV SI,3000H MOV AL,00H MOV [SI],AL ;清显示缓冲 MOV [SI+1],AL MOV [SI+2],AL MOV [SI+3],AL MOV [SI+4],AL MOV [SI+5],AL MOV DI,3005H MOV DX,MY8255_CON ;写8255控制字 MOV AL,81H OUT DX,AL BEGIN: CALL DIS ;调用显示子程序 CALL CLEAR ;清屏 CALL CCSCAN ;扫描 JNZ INK1 JMP BEGIN INK1: CALL DIS CALL KEYDALLY CALL KEYDALLY CALL CLEAR CALL CCSCAN MOV AX,SEG DUAN ;取DUAN的段地址 MOV DS,AX MOV SI,OFFSET DUAN ;取DUAN的地址偏移量,用于技计数 MOV AL,[SI] INC AL MOV [SI],AL CMP AL,7 ;AL与6相比较 JE B2 JNZ INK2 ;有键按下,转到INK2 JMP BEGIN ;======================================== ;确定按下键的位置 ;======================================== B2: MOV AL,0 MOV [SI],AL POP AX POP SI IRET INK2: MOV CH,0FEH MOV CL,00H COLUM: MOV AL,CH MOV DX,MY8255_A OUT DX,AL MOV DX,MY8255_C IN AL,DX L1: TEST AL,01H ;is L1? JNZ L2 MOV AL,00H ;L1 JMP KCODE L2: TEST AL,02H ;is L2? JNZ L3 MOV AL,04H ;L2 JMP KCODE L3: TEST AL,04H ;is L3? JNZ L4 MOV AL,08H ;L3 JMP KCODE L4: TEST AL,08H ;is L4? JNZ NEXT MOV AL,0CH ;L4 KCODE: ADD AL,CL CALL PUTBUF PUSH AX KON: CALL DIS CALL CLEAR CALL CCSCAN JNZ KON POP AX NEXT: INC CL MOV AL,CH TEST AL,08H JZ KERR ROL AL,1 MOV CH,AL JMP COLUM KERR: JMP BEGIN ;======================================== ;键盘扫描子程序 ;======================================== CCSCAN: MOV AL,00H MOV DX,MY8255_A OUT DX,AL MOV DX,MY8255_C IN AL,DX NOT AL AND AL,0FH RET ;======================================== ;清屏子程序 ;======================================== CLEAR: MOV DX,MY8255_B MOV AL,00H OUT DX,AL RET ;======================================== ;显示子程序 ;======================================== DIS: PUSH AX MOV SI,3000H MOV DL,0DFH MOV AL,DL AGAIN: PUSH DX MOV DX,MY8255_A OUT DX,AL MOV AL,[SI] MOV BX,OFFSET TAB AND AX,00FFH ADD BX,AX MOV AL,[BX] MOV DX,MY8255_B OUT DX,AL CALL KEYDALLY INC SI POP DX MOV AL,DL TEST AL,01H JZ OUT1 ROR AL,1 MOV DL,AL JMP AGAIN OUT1: POP AX RET ;====== 延时子程序 ====== KEYDALLY: PUSH CX MOV CX,0006H D1: MOV AX,009FH D2: DEC AX JNZ D2 LOOP D1 POP CX RET ;======================================== ;存键盘值到相应位的缓冲中 ;======================================== PUTBUF: MOV SI,DI MOV [SI],AL MOV CX,SEG DUAN ;取DUAN的段地址 MOV DS,CX MOV SI,OFFSET DUAN ;取DUAN的地址偏移量 MOV BX,[SI] MOV CX,SEG N_TIME ;取DUAN的段地址 MOV DS,CX MOV SI,OFFSET N_TIME ;取DUAN的地址偏移量 MOV [SI+BX],AL MOV DX,[SI+BX] DEC DI CMP DI,2FFFH JNZ GOBACK MOV DI,3005H GOBACK: RET MIR6 ENDP SIR1 PROC CLI PUSH AX PUSH SI MOV AX,DATA MOV DS,AX MOV SI,3000H MOV AL,00H MOV [SI],AL ;清显示缓冲 MOV [SI+1],AL MOV [SI+2],AL MOV [SI+3],AL MOV [SI+4],AL MOV [SI+5],AL MOV DI,3005H MOV DX,MY8255_CON ;写8255控制字 MOV AL,81H OUT DX,AL BEGIN_U: CALL DIS1 ;调用显示子程序 CALL CLEAR1 ;清屏 CALL CCSCAN1 ;扫描 JNZ INK3 JMP BEGIN_U INK3: CALL DIS1 CALL U_DALLY CALL U_DALLY CALL CLEAR1 CALL CCSCAN1 MOV AX,SEG DUAN ;取DUAN的段地址 MOV DS,AX MOV SI,OFFSET DUAN ;取DUAN的地址偏移量 MOV AL,[SI] INC AL MOV [SI],AL CMP AL,7 ;AL与7相比较 JE B3 JNZ INK4 ;有键按下,转到INK2 JMP BEGIN_U ;======================================== ;确定按下键的位置 ;======================================== B3: MOV AL,0 MOV [SI],AL POP AX POP SI IRET INK4: MOV CH,0FEH MOV CL,00H COLUM2: MOV AL,CH MOV DX,MY8255_A OUT DX,AL MOV DX,MY8255_C IN AL,DX U1: TEST AL,01H ;is L1? JNZ U2 MOV AL,00H ;L1 JMP KCODE1 U2: TEST AL,02H ;is L2? JNZ U3 MOV AL,04H ;L2 JMP KCODE1 U3: TEST AL,04H ;is L3? JNZ U4 MOV AL,08H ;L3 JMP KCODE1 U4: TEST AL,08H ;is L4? JNZ NEXT1 MOV AL,0CH ;L4 KCODE1: ADD AL,CL CALL PUTBUF1 PUSH AX KON1: CALL DIS1 CALL CLEAR1 CALL CCSCAN1 JNZ KON1 POP AX NEXT1: INC CL MOV AL,CH TEST AL,08H JZ KERR1 ROL AL,1 MOV CH,AL JMP COLUM2 KERR1: JMP BEGIN_U ;======================================== ;键盘扫描子程序 ;======================================== CCSCAN1: MOV AL,00H MOV DX,MY8255_A OUT DX,AL MOV DX,MY8255_C IN AL,DX NOT AL AND AL,0FH RET ;======================================== ;清屏子程序 ;======================================== CLEAR1: MOV DX,MY8255_B MOV AL,00H OUT DX,AL RET ;======================================== ;显示子程序 ;======================================== DIS1: PUSH AX MOV SI,3000H MOV DL,0DFH MOV AL,DL AGAIN1: PUSH DX MOV DX,MY8255_A OUT DX,AL MOV AL,[SI] MOV BX,OFFSET TAB AND AX,00FFH ADD BX,AX MOV AL,[BX] MOV DX,MY8255_B OUT DX,AL CALL U_DALLY INC SI POP DX MOV AL,DL TEST AL,01H JZ OUT2 ROR AL,1 MOV DL,AL JMP AGAIN1 OUT2: POP AX RET ;====== 延时子程序 ====== U_DALLY: PUSH CX MOV CX,0006H W1: MOV AX,009FH W2: DEC AX JNZ W2 LOOP W1 POP CX RET ;======================================== ;存键盘值到相应位的缓冲中 ;======================================== PUTBUF1: MOV SI,DI MOV [SI],AL MOV CX,SEG DUAN ;取DUAN的段地址 MOV DS,CX MOV SI,OFFSET DUAN ;取DUAN的地址偏移量 MOV BX,[SI] MOV CX,SEG TIMER ;取DUAN的段地址 MOV DS,CX MOV SI,OFFSET TIMER ;取DUAN的地址偏移量 MOV [SI+BX],AL MOV DX,[SI+BX] DEC DI CMP DI,2FFFH JNZ GOBACK1 MOV DI,3005H GOBACK1: RET SIR1 ENDP MIR7 PROC STI ;置中断标志位IF PUSH AX ;压栈 PUSH SI MOV AX,SEG TIMER ;取TIMER的段地址 MOV DS,AX MOV SI,OFFSET TIMER ;取TIMER的地址偏移量 MOV AL,[SI] INC AL MOV [SI],AL CMP AL,100 ;AL与100相比较 JNE TRNED ;若相等,则跳转 MOV AL,0 ;不等则向下执行 MOV [SI],AL MOV AL,[SI+1] ADD AL,1 DAA ;十进制调整,用于加法 MOV [SI+1],AL CMP AL,60H JNE TRNED MOV AL,0 MOV [SI+1],AL MOV AL,[SI+2] ADD AL,1 DAA MOV [SI+2],AL CMP AL,60H JNE TRNED MOV AL,0 MOV [SI+2],AL MOV AL,[SI+3] ADD AL,1 DAA MOV [SI+3],AL CMP AL,24H JNE TRNED MOV AL,0 MOV [SI+3],AL TRNED: MOV AL,[SI+1] MOV SEC,AL MOV AL,[SI+2] MOV MIN,AL MOV AL,[SI+3] MOV HOUR,AL POP SI ;出栈 POP AX STI ;置中断标志位IF IRET ;中断返回 ENDP DISP: PUSH BX PUSH DI PUSH AX PUSH SI MOV DX,MY8255_B MOV AX,SEG TAB MOV DS,AX MOV BX,OFFSET TAB MOV AL,SEC AND AL,0FH ;与低四位相与 MOV AH,00H MOV SI,AX MOV AL,[BX+SI] OUT DX,AL MOV DX,MY8255_A MOV AL,0DFH OUT DX,AL CALL DALLY MOV AL,SEC AND AL,0F0H ror al,04 MOV AH,00H MOV SI,AX MOV AL,[BX+SI] MOV DX,MY8255_B OUT DX,AL MOV DX,MY8255_A MOV AL,0EFH OUT DX,AL CALL DALLY MOV AL,MIN AND AL,0FH MOV AH,00H MOV SI,AX MOV AL,[BX+SI] MOV DX,MY8255_B OUT DX,AL MOV DX,MY8255_A MOV AL,0F7H OUT DX,AL CALL DALLY MOV AL,MIN AND AL,0F0H ror al,04 MOV AH,00H MOV SI,AX MOV AL,[BX+SI] MOV DX,MY8255_B OUT DX,AL MOV DX,MY8255_A MOV AL,0FBH OUT DX,AL CALL DALLY MOV AL,HOUR AND AL,0FH MOV AH,00H MOV SI,AX MOV AL,[BX+SI] MOV DX,MY8255_B OUT DX,AL MOV DX,MY8255_A MOV AL,0FDH OUT DX,AL CALL DALLY MOV AL,HOUR AND AL,0F0H ror al,04 MOV AH,00H MOV SI,AX MOV AL,[BX+SI] MOV DX,MY8255_B OUT DX,AL MOV DX,MY8255_A MOV AL,0FEH OUT DX,AL CALL DALLY POP SI POP AX POP DI POP BX RET ZDBS PROC ;整点报时 MOV AL,MIN CMP AL,00H JNZ LP2 MOV AL,SEC CMP AL,00H JNZ LP2 MOV DX, CON8254 ;8254 MOV AL, 76H ;计数器1,方式3 OUT DX, AL ZD1: MOV DX, B8254 MOV AL, 00H OUT DX, AL MOV AL, 09H OUT DX, AL MOV AL,SEC CMP AL,05H JE OUTZD CALL DISP JMP ZD1 OUTZD: MOV AX,00H OUT DX,AL MOV AL,AH OUT DX,AL RET LP2: RET ZDBS ENDP BJ PROC ;闹铃程序 MOV AL,HOUR MOV CX,SEG N_TIME ;取DUAN的段地址 MOV DS,CX MOV SI,OFFSET N_TIME ;取DUAN的地址偏移量 MOV BL,[SI+1] ROL BL,04 MOV AL,0 MOV AL,[SI+2] OR BL,AL CMP AL,BL JNZ LP MOV CX,SEG N_TIME ;取DUAN的段地址 MOV DS,CX MOV SI,OFFSET N_TIME ;取DUAN的地址偏移量 MOV BL,[SI+3] ROL BL,04 MOV AL,0 MOV AL,[SI+4] OR BL,AL MOV AL,MIN CMP AL,BL JNZ LP MOV CX,SEG N_TIME ;取DUAN的段地址 MOV DS,CX MOV SI,OFFSET N_TIME ;取DUAN的地址偏移量 MOV BL,[SI+5] ROL BL,04 MOV AL,0 MOV AL,[SI+6] OR BL,AL MOV AL,SEC CMP AL,BL JNZ LP MOV DX, CON8254 ;8254 MOV AL, 76H ;计数器1,方式3 OUT DX, AL BEGIN_M: MOV BX,OFFSET FREQ_LIST MOV DI,OFFSET TIME_LIST ;装入时间表起始地址 PLAY: MOV DX,0FH ;输入时钟为1MHz,1M = 0F4240H MOV AX,4240H DIV WORD PTR [BX] ;取出频率值计算计数初值,0F4240H / 输出频率 MOV DX,B8254 OUT DX,AL ;装入计数初值 MOV AL,AH OUT DX,AL MOV DL,[DI] ;取出演奏相对时间,调用延时子程序 CALL DALLY2 ADD BX,2 INC DI CMP WORD PTR [BX],0 ;判断是否到曲末? JE OUTPLAY CALL DISP JMP PLAY OUTPLAY:MOV DX,B8254 MOV AX,00H OUT DX,AL MOV AL,AH OUT DX,AL RET LP: RET DALLY2 PROC ;延时子程序 H0: MOV CX,0010H H1: MOV AX,0FF0H H2: DEC AX JNZ H2 LOOP H1 DEC DL JNZ H0 RET DALLY2 ENDP BJ ENDP DALLY: PUSH CX MOV CX,0006H T1: MOV AX,009FH T2: DEC AX JNZ T2 LOOP T1 POP CX RET CODE ENDS
总结
以上所述是小编给大家介绍的汇编语言实现电子闹钟思路详解,希望对大家有所帮助!
最后
以上就是虚拟钻石最近收集整理的关于汇编语言实现电子闹钟思路详解的全部内容,更多相关汇编语言实现电子闹钟思路详解内容请搜索靠谱客的其他文章。
发表评论 取消回复