中断服务入口程序入口地址:
存储空间两个字节
0003H:外部中断0
000BH:定时/计数器0
0013H:外部中断1
001BH:定时/计数器1
0023H:串口1
TCON与SCON寄存器
寄存器 | 地址 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 复位值 |
TCON | 88H | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 | 00000000B |
SCON | 98H | SM0/FE | SM1 | SM2 | REN | TB8 | RB8 | TI | RI | 00000000B |
TCON,SCON在SFR区中
外部中断0
IT0:外部中断INT0的触发控制位,0为双边沿触发(上升沿和下降沿都触发),1为下降沿触发
IE0: 外部中断INT0请求标志,当触发了外部中断的条件,都会硬件置为IE0。当CPU响应中断服务程序时,由硬件自动清0中断标志
外部中断1
IT1:外部中断INT1的触发控制位,0为双边沿触发(上升沿和下降沿都触发),1为下降沿触发
IE1: 外部中断INT1请求标志,当触发了外部中断的条件,都会硬件置为IE1。当CPU响应中断服务程序时,由硬件自动清0中断标志
定时/计数器0
TR0:定时/计数器T0启动/停止控制位
TF0:定时/计数器T0的溢出中断标志。若CPU响应中断,在进入中断后,CPU自动将TF0清0.TF0也可用软件清0(查询方式)
定时/计数器1
TR1:定时/计数器T1启动/停止控制位
TF1:定时/计数器T1的溢出中断标志。若CPU响应中断,在进入中断后,CPU自动将TF1清0.TF1也可用软件清0(查询方式)
串口中断请求标志
串口中断的请求标志位都不能自动清0,需要用户自己在中断服务程序中使用软件清0
RI:串口1接收中断标志位,接收时,先接收再中断
TI:串口1发送中断标志位,发送时,先发送再中断
IE(中断允许控制寄存器)
寄存器 | 地址 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 复位值 |
IE | A8H | EA | ELVD | EADC | ES | ET1 | EXI | ET0 | EX0 | 00000000B |
0:关中断,1:开中断
EA:中断允许总控制位
ES:串口1中断允许控制位
ET1:定时器1中断允许控制位
ET0:定时器0中断允许控制位
EX1:外部中断INT1的中断允许控制位
EX0:外部中断INT0的中断允许控制位
IP(中断优先级控制寄存器)
寄存器 | 地址 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 复位值 |
IP | B8H | PPCA | PLVD | PADC | PS | PT1 | PXI | PT0 | PX0 | 00000000B |
0:低优先级,1:高优先级
PS:串口1中断优先级控制位
PT1:定时器1中断优先级控制位
PT0:定时器0中断优先级控制位
PX1:外部中断INT1的中断优先级控制位
PX0:外部中断INT0的中断优先级控制位
利用中断实现花式流水灯
;1)主程序控制 P2 口 LED 花式闪烁,显示顺序:
; 依次左移点亮;
;依次右移点亮;
; LED0、LED2、LED4、LED6 亮 1s 熄灭,LED1、LED3、LED5、LED7 亮 1s 熄灭,
;循环 3 次;
;2)INT0 与按键 K1 连接,中断时 8 个 LED 闪烁 5 次。
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP INT0_ISR
ORG 0100H
LED_L EQU R1
LED_R EQU R2
LOOP_F EQU R3
LED0_6 EQU R4
LED1_7 EQU R5
LOOP_IT0 EQU R6
MAIN: MOV LED_L,#0FEH ;1111 1110B
MOV LED_R,#07FH ;0111 1111B
MOV LOOP_F,#03H
MOV LED0_6,#0AAH
MOV LED1_7,#055H
MOV LOOP_IT0,#5
START:
SETB IT0
SETB EX0
SETB EA
MOV P2,LED_L
LOOP: MOV P2,LED_L
MOV A,P2
SETB C
RLC A
LCALL DELAY100MS
MOV LED_L,A
JNB P2.7,LOOP2
LJMP LOOP
LOOP2:MOV P2,LED_R
MOV A,P2
SETB C
RRC A
LCALL DELAY100MS
MOV LED_R,A
JNB P2.0,LOOP3
LJMP LOOP2
LOOP3:MOV P2,LED0_6
MOV A,P2
LCALL DELAY100MS
MOV P2,LED1_7
MOV A,P2
LCALL DELAY100MS
DJNZ LOOP_F,LOOP3
LJMP MAIN
INT0_ISR:
PUSH ACC ;入栈
LED:MOV A,#00H
MOV P2,A
LCALL DELAY100MS
MOV A,#0FFH
MOV P2,A
DJNZ LOOP_IT0,LED
;CRL IE0 标志位清0
POP ACC ;出栈
RETI
DELAY100MS: ;@12.000MHz
NOP
NOP
NOP
PUSH 30H
PUSH 31H
PUSH 32H
MOV 30H,#4
MOV 31H,#166
MOV 32H,#207
NEXT:
DJNZ 32H,NEXT
DJNZ 31H,NEXT
DJNZ 30H,NEXT
POP 32H
POP 31H
POP 30H
RET
END
上述代码问题 :
- 延时时间问题:需求中要求 LED0、LED2、LED4、LED6 亮 1s 熄灭,LED1、LED3、LED5、LED7 亮 1s 熄灭,但代码中使用的是
DELAY100MS
延时,需要修改为 1s 延时。 - 中断标志位清除问题:代码中注释提到清除
IE0
标志位,但没有实际执行清除操作。在 8051 单片机中,下降沿触发的外部中断(IT0 = 1
),硬件会自动清除IE0
标志位,无需软件手动清除。 - 循环次数重置问题:在
INT0_ISR
中断服务程序中,DJNZ LOOP_IT0,LED
会使LOOP_IT0
的值不断减少,中断结束后没有重置,再次进入中断时闪烁次数会受影响,需要在每次中断开始时重置。 - 主程序循环问题:
LJMP MAIN
会导致每次循环都重新初始化变量,应该使用一个循环结构来实现多次循环。
修改后的代码:
;1)主程序控制 P2 口 LED 花式闪烁,显示顺序:
; 依次左移点亮;
;依次右移点亮;
; LED0、LED2、LED4、LED6 亮 1s 熄灭,LED1、LED3、LED5、LED7 亮 1s 熄灭,
;循环 3 次;
;2)INT0 与按键 K1 连接,中断时 8 个 LED 闪烁 5 次。
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP INT0_ISR
ORG 0100H
LED_L EQU R1
LED_R EQU R2
LOOP_F EQU R3
LED0_6 EQU R4
LED1_7 EQU R5
LOOP_IT0 EQU R6
MAIN: MOV LED_L,#0FEH ;1111 1110B
MOV LED_R,#07FH ;0111 1111B
MOV LOOP_F,#03H
MOV LED0_6,#0AAH
MOV LED1_7,#055H
MOV LOOP_IT0,#5 ;对循环次数重新赋值
START:
SETB IT0
SETB EX0
SETB EA
MOV P2,LED_L
LOOP: MOV P2,LED_L
MOV A,P2
SETB C
RLC A
LCALL DELAY100MS
MOV LED_L,A
JNB P2.7,LOOP2
LJMP LOOP
LOOP2:MOV P2,LED_R
MOV A,P2
SETB C
RRC A
LCALL DELAY100MS
MOV LED_R,A
JNB P2.0,LOOP3
LJMP LOOP2
LOOP3:MOV P2,LED0_6
MOV A,P2
LCALL DELAY100MS
MOV P2,LED1_7
MOV A,P2
LCALL DELAY100MS
DJNZ LOOP_F,LOOP3
LJMP MAIN
INT0_ISR:
PUSH ACC ;入栈
LED:MOV A,#00H
MOV P2,A
LCALL DELAY100MS
MOV A,#0FFH
MOV P2,A
DJNZ LOOP_IT0,LED
;CRL IE0 标志位清0
MOV LOOP_IT0,#5
POP ACC ;出栈
DON:RETI
DELAY100MS: ;@12.000MHz
NOP
NOP
NOP
PUSH 30H
PUSH 31H
PUSH 32H
MOV 30H,#4
MOV 31H,#166
MOV 32H,#207
NEXT:
DJNZ 32H,NEXT
DJNZ 31H,NEXT
DJNZ 30H,NEXT
POP 32H
POP 31H
POP 30H
RET
END
利用中断实现花式流水灯