概念
中断源:指引起CPU中断的事件,即中断请求信号的来源。51单片机有5个中断源,分别是外部中断0,定时/计数器T0中断,外部中断1,定时/计数器T1中断,串行口中断,对应地址如下表:
中断源 | 中断矢量地址 |
---|---|
外部中断0 | 0003H |
定时/计数器T0中断 | 000BH |
外部中断1 | 0013H |
定时/计数器T1中断 | 001BH |
串行口中断 | 0023H |
定时/计数器控制寄存器TCON
位编号 | TCON.7 | TCON.6 | TCON.5 | TCON.4 | TCON.3 | TCON.2 | TCON.1 | TCON.0 |
---|---|---|---|---|---|---|---|---|
位地址 | 8FH | 8EH | 8DH | 8CH | 8BH | 8AH | 89H | 88H |
位定义 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
功能 | 定时器T1的溢出中断申请位,产生中断溢出时自动置为1,当CPU响应该中断后自动置0 | 定时器/计数器T1的控制位,由软件设置,置1时启动定时器,置0时停止定时器 | 定时器T0溢出中断申请位,产生溢出时硬件自动置1,CPU响应中断后自动清0 | 定时器/计数器T0的控制位,由软件设置,置1时启动定时器,置0时停止定时器 | 外部中断INT1请求标志位,当CPU检测到外部中断信号后被置1,当CPU响应中断并进入中断函数后硬件自动清0 | 外部中断INT1触发方式控制位,由软件设置,置1时为边沿触发方式,置0时为低电平触发中断方式 | 外部中断INT0请求标志位,当CPU检测到外部中断信号后被置1,当CPU响应中断并进入中断函数后硬件自动清0 | 外部中断INT0触发方式控制位,由软件设置,置1时为边沿触发方式,置0时为低电平触发中断方式 |
中断允许寄存器IE
位编号 | IE.7 | IE.6 | IE.5 | IE.4 | IE.3 | IE.2 | IE.1 | IE.0 |
---|---|---|---|---|---|---|---|---|
位地址 | AFH | – | – | ACH | ABH | AAH | A9H | A8H |
位定义 | EA | – | – | ES | ET1 | EX1 | ET0 | EX0 |
功能 | CPU总中断开放标志位,置1时开总中断,置0时关闭所有中断 | – | – | 串行中断允许标志位,置1时允许串行口中断,置0时关闭串行口中断 | 定时器/计数器T1溢出中断允许标志位,置1时允许T1中断,置0时关闭T1中断 | 外部中断1中断允许标志位,置1时允许外部中断1中断,置0时关闭外部中断1中断 | 定时器/计数器T0溢出中断允许标志位,置1时允许T1中断,置0时关闭T1中断 | 外部中断0中断允许标志位,置1时允许外部中断1中断,置0时关闭外部中断1中断 |
中断优先级寄存器IP
位编号 | IP.7 | IP.6 | IP.5 | IP.4 | IP.3 | IP.2 | IP.1 | IP.0 |
---|---|---|---|---|---|---|---|---|
位地址 | – | – | – | BCH | BBH | BAH | B9H | B8H |
位定义 | – | – | – | PS | PT1 | PX1 | PT0 | PX0 |
功能 | – | – | – | 串行口中断优先级控制位,置1时设定串行口中断为高优先级中断,置0时设定串行口为低优先级中断 | 定时/计数器T1中断优先级控制位,置1时设定定时/计数器T1中断为高优先级中断,置0时设定定时/计数器T1为低优先级中断 | 外部中断1优先级控制位,置1时设定外部中断1为高优先级中断,置0时设定外部中断1为低优先级中断 | 定时/计数器T0中断优先级控制位,置1时设定定时/计数器T0中断为高优先级中断,置0时设定定时/计数器T0为低优先级中断 | 外部中断0优先级控制位,置1时设定外部中断0为高优先级中断,置0时设定外部中断0为低优先级中断 |
定时/计数器方式寄存器TMOD
位编号 | TMOD.7 | TMOD.6 | TMOD.5 | TMOD.4 | TMOD.3 | TMOD.2 | TMOD.1 | TMOD.0 |
---|---|---|---|---|---|---|---|---|
位定义 | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
功能 | 门控位,用于控制定时/计数器的启动是否受外部中断请求信号的控制,置1时T0的启动受外部中断0控制,T1受外部中断1控制,置0时定时/计数器的启动与外部中断无关 | 定时或计数选择位,置1时为计数方式,置0时为定时方式 | 定时/计数工作方式选择位 | 定时/计数方式选择位 | 同上 | 同上 | 同上 | 同上 |
定时/计数器工作方式选择M1 M0
M1 | M0 | 工作方式 | 功能 | 初值计算 |
---|---|---|---|---|
0 | 0 | 方式0 | 13位定时/计数器 | T=[ ( 8192 - x ) * f ] / 12 |
0 | 1 | 方式1 | 16位定时/计数器 | T=[ ( 65536 - x ) * f ] / 12 |
1 | 0 | 方式2 | 具有自动重装初值的8位定时/计数器 | T=[ ( 256 - x ) * f ] / 12 |
1 | 1 | 方式3 | 分为两个独立的8位计数器(仅适用于T0) | – |
注:T表示计时时间,f表示晶振频率,x表示初值,再给TH0(TH1)和TL0(TL1)赋值时,将x转换为16进制,在分高低8位赋值即可
例程
外部中断0
ORG 0000H
AJMP START
ORG 0003H //外部中断INT0地址
AJMP INT_0 //转中断程序
ORG 0030H
START: MOV SP, #30H
MOV R0, #08H
MOV B, #255
MOV R1, #255
CLR P1.1 //P1.1清0
//INT1初始化
MOV IP, #01H //设置外部中断INT0为最高级
SETB IT0 //设置INT0为边沿触发
SETB EA //开总中断
SETB EX0 //开外部中断
ACALL LED
//流水灯程序
LED: MOV A, #01
MOV P2, A
ACALL DELAY
LOOP: RL A
MOV P2, A
ACALL DELAY
DJNZ R0, LOOP
MOV R0, #08H
LJMP LOOP
//延时函数程序
DELAY: DJNZ B, DELAY
MOV B, #255
DJNZ R1, DELAY
MOV R1, #255
RET
//中断函数
INT_0: PUSH PSW //保护现场,临时保存程序状态字寄存器
PUSH ACC
CPL P1.1 //P1.1取反
POP ACC
POP PSW
RETI
END
现象:主程序时流水灯,当P3.2连接的按键按下后,P1.1状态取反,与之相连的灯如果是熄灭的这次按下会点亮,如果是点亮的则按下后熄灭
外部中断1
ORG 0000H
AJMP START
ORG 0013H //外部中断INT1地址
AJMP INT_1 //转中断程序
ORG 0030H
START: MOV SP, #30H //设置堆栈指针
MOV R0, #08H
MOV B, #255
MOV R1, #255
CLR P1.1 //P1.1清0
//INT1初始化
MOV IP, #04H //设置外部中断INT1为最高级
SETB IT1 //设置INT1为边沿触发
SETB EA //开总中断
SETB EX1 //开外部中断
ACALL LED
//流水灯程序
LED: MOV A, #01
MOV P2, A
ACALL DELAY
LOOP: RL A
MOV P2, A
ACALL DELAY
DJNZ R0, LOOP
MOV R0, #08H
LJMP LOOP
//延时函数程序
DELAY: DJNZ B, DELAY
MOV B, #255
DJNZ R1, DELAY
MOV R1, #255
RET
//中断函数
INT_1: PUSH PSW //保护现场,临时保存程序状态字寄存器
PUSH ACC
CPL P1.1 //P1.1取反
POP ACC
POP PSW
RETI
END
现象:主程序时流水灯,当P3.3连接的按键按下后,P1.1状态取反,与之相连的灯如果是熄灭的这次按下会点亮,如果是点亮的则按下后熄灭
定时器0中断
ORG 0000H
LJMP START
ORG 000BH //定时器0地址
LJMP Timer0Interrupt //转定时器中断函数
START:
MOV SP, #60H //设置堆栈指针
MOV R0, #00
CLR P1.1 //P1.1清0
LCALL InitTimer0 //转初始化中断定时器0
SJMP $ //主程序卡在死循环中
InitTimer0:
MOV TMOD, #10H //设置工作方式位1
//赋初值,定时1ms
MOV TH0, #0FCH
MOV TL0, #18H
SETB EA //开总中断
SETB ET0 //开定时器1中断
SETB TR0 //启动定时器
RET
//中断函数
Timer0Interrupt:
//定时器中断保护现场通常写法
PUSH DPH //数据指针DPTR高8位入栈
PUSH DPL //数据指针DPTR低8位入栈
PUSH ACC
//重装初值
MOV TH0, #0FCH
MOV TL0, #18H
INC R0 //定时次数加1
CJNE R0, #255, NEXT //定时255ms
MOV R0, #00 //清0,开始下次计时
CPL P1.1 //P1.1状态取反
NEXT:
POP ACC
POP DPL
POP DPH
RETI
END
现象:定时器定时1ms,共计时255ms,与P1.1相连的小灯状态变化一次
定时器1中断
ORG 0000H
LJMP START
ORG 001BH //定时器1地址
LJMP Timer1Interrupt //转定时器中断函数
START:
MOV SP, #60H //设置堆栈指针
MOV R0, #00
CLR P1.1 //P1.1清0
LCALL InitTimer1 //转初始化中断定时器1
SJMP $ //主程序卡在死循环中
InitTimer1:
MOV TMOD, #10H //设置工作方式位1
//赋初值,定时1ms
MOV TH1, #0FCH
MOV TL1, #18H
SETB EA //开总中断
SETB ET1 //开定时器1中断
SETB TR1 //启动定时器
RET
//中断函数
Timer1Interrupt:
//定时器中断保护现场通常写法
PUSH DPH //数据指针DPTR高8位入栈
PUSH DPL //数据指针DPTR低8位入栈
PUSH ACC
//重装初值
MOV TH1, #0FCH
MOV TL1, #18H
INC R0 //定时次数加1
CJNE R0, #255, NEXT //定时255ms
MOV R0, #00 //清0,开始下次计时
CPL P1.1 //P1.1状态取反
NEXT:
POP ACC
POP DPL
POP DPH
RETI
END
现象:定时器定时1ms,共计时255ms,与P1.1相连的小灯状态变化一次