电子闹钟程序:在微机及接口实验箱上完成电子闹钟设计。试验箱上的七段数码管显示时间,蜂鸣器整点报时。设置初始时间与定时时间,并在设置的时间报时,增加了闹铃音乐。
本系统设计的电子时钟以8086微处理器作为CPU,用8254做定时计数器产生时钟频率,8255做可编程并行接口显示时钟电路,8259做中断控制器产生中断。8254设定计数初值进行计数,工作于计数器0,方式3。计数器0设置初值为10000用来产生10ms的脉冲,通过设置8259循环100次从而产生1s的脉冲。通过移位指令来实现时、秒、分的个位和十位的独自存储,将分、秒的个位十位分别存入指定的寄存器中,比较转移指令来完成秒和分的累加。当秒的个位累加到10时十位加一并将个位清零,当秒累计到60时,分的个位就开始计一位,同时秒清零,当分和秒都记到60时,时的个位开始计一位,同时分和秒都清零。小时计到24时就调用子程序使秒、分、时清零从新开始计时。通过可编程并行接口芯片8255将要显示的位内容送到端口A保存起来并将累加好的记数值经过変址寻址方式将记数值转换成数码管所要显示值。与此同时,还对显示的时间进行比较,看是否和设定的时间一致。当与设定的时间一致的时候,通过8254的控制,使扬声器发声,从而达到数字闹钟的功能。
程序由以下五个模块组成:初始化模块,定时模块,中断模块,显示模块以及发声模块。
初始化模块:主控模块是系的核心模块,对8254、8255、8259进行初始化,设置中断向量。调用中断子程序和显示子程序由软件实现。该时钟程序由00:00:00开始计时,通过8254的分频产生1ms的方波。
定时模块:定时模块是为8259提供中断请求信号的。由一片8254实现,选用定时器0,工作在方式3,由于时钟应该1秒走动一次,所以输出值应为1S,其输出信号可作为8259的中断请求信号。
中断处理模块:中断模块实现动态显示的。中断程序为时间按秒增加,并显示,只要开中断,便可实现每秒显示时间增加一秒,从而达到动态显示的效果。
显示模块:显示模块是将显示缓冲区的数值送到LED显示的功能模块,显示缓冲区是由六个字节构成,分别保存小时的高位和低位,分钟的高位和低位,秒钟的高位和低位。硬件上由六个LED构成,软件上由扫描显示的方法实现。
发声模块:通过比较,当显示时间与设定时间一致时,使扬声器发声。
程序实现代码:
A8254 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 882,330,330,294,262,990,262,882,882
DW 990,262,294,262,294,262,330,882,441
DW 441,393,350,330,393,262,882,990,262,330
DW 294,262,990,262,882,330,330,294,262,990
DW 262,882,882,990,262,294,294,262,294,262
DW 330,330,882,441,441,393,350,330,393,262
DW 882,262,330,294,294,262,990,262,0
TIME_LIST DB 4,12,4,4,4,8,4,12,4 ;时间表
DB 4,4,8,4,8,4,8,4,12
DB 4,4,4,8,4,12,4,4,4,4
DB 4,4,8,4,12,12,4,4,4,8
DB 4,12,4,4,4,4,4,4,4,4
DB 4,8,4,12,4,4,4,8,4,8
DB 4,4,4,4,4,8,8,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的段地址矢量
;SIR1
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 ;ICW3
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
PUSH BX
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 MID ;若不相等,则跳转
MOV AL,0 ;相等则向下执行
MOV [SI],AL
MOV AL,[SI+6]
ADD AL,1
DAA ;十进制调整,用于加法
MOV [SI+6],AL
CMP AL,10H
JNE TRNED
MOV AL,0
MOV [SI+6],AL
MOV AL,[SI+5]
ADD AL,1
DAA
MOV [SI+5],AL
CMP AL,6H
JNE TRNED
MOV AL,0
MOV [SI+5],AL
MOV AL,[SI+4]
ADD AL,1
DAA
MOV [SI+4],AL
CMP AL,10H
MID: JNE TRNED
MOV AL,0
MOV [SI+4],AL
MOV AL,[SI+3]
ADD AL,1
DAA
MOV [SI+3],AL
CMP AL,6H
JNE TRNED
MOV AL,0
MOV [SI+3],AL
MOV AL,[SI+2]
ADD AL,1
DAA
MOV [SI+2],AL
MOV AL,[SI+1]
CMP AL,2H
JNZ HOUR1
MOV AL,[SI+2]
CMP AL,4H
JNZ TRNED
MOV AL,0
MOV [SI+2],AL
MOV [SI+1],AL
JMP TRNED
HOUR1:
MOV AL,[SI+2]
CMP AL,10H
JNZ TRNED
MOV AL,0
MOV [SI+2],AL
MOV AL,[SI+1]
ADD AL,1
DAA
MOV [SI+1],AL
TRNED:
MOV AL,[SI+6]
MOV BL,[SI+5]
ROR BL,04
OR AL,BL
MOV SEC,AL
MOV AL,[SI+4]
MOV BL,[SI+3]
ROR BL,04
OR AL,BL
MOV MIN,AL
MOV AL,[SI+2]
MOV BL,[SI+1]
ROR BL,04
OR AL,BL
MOV HOUR,AL
POP BX
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 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
MOV AL,HOUR
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
END START
注:硬件连接图如图所示。硬件连接中MIR6接KK1;SIR1接KK2.