1、什么是“中断”?
顾名思义,中断就是中断当前工作去处理一些临时发生的时间,处理完后,则继续原工作过程。例如:你在看书,电话响了,你在书上做好记号后去接电话,接完之后再原记号处继续往下看书。
2、51单片机也需要“中断”?
通常单片机中只有一个CPU,但却要应对诸如:运行程序、数据输入、数据输出、以及特殊情况处理等多项任务,为此单片机必须具备中断处理的功能,以应对特殊情况的紧急处理。
3、“中断过程”是怎样的?
中断的目的是为了暂停主程序的运行,先去执行中断服务程序,其功能是为了提高CPU工作效率。在中断源提出中断请求后,处理器执行完当前指令便进行中断响应,一旦中断服务程序执行完毕后,仍须返回到主程序被中断处(断点处)继续执行原先程序,其过程如图所示
4、谁能“中断”51单片机?
中断源:能引发中断的来源称为中断源。
51单片机一共支持5个中断源(2个外部中断源,3个内部中断源),这些中断源分别是:
(1)外部中断请求0,由INT0(P3.2引脚)输入。
(2)外部中断请求1,由INT1(P3.3引脚)输入。
(3)片内定时/计数器0溢出中断(T0)请求。
(4)片内定时/计数器0溢出中断(T1)请求。
(5)片内串行口发送/接收中断请求。
5、“中断源”同时来临,怎么办?
中断优先级:处理中断源的优先顺序称为中断优先级
51单片机将优先级整个划分为2个大等级:高优先级和低优先级。高优先级的中断先响应,等高优先级的中断响应完之后才响应低优先级的中断,高低优先级的分配可通过IP寄存器来设置。
当多个中断都分配为同一个优先等级,并且发生中断时,由查询电路来确定最终优先级。
对于同一优先级,单片机对其中断次序安排如下:外部中断0>定时/计数器T0>外部中断1>定时/计数器T1>串行口。
6、“中断源”的信号可否屏蔽?
51单片机是可以屏蔽中断信号的。有总开关和分开关。
7、中断响应可否嵌套?
高优先级中断是可以打断低优先级的中断处理过程。
8、每个“中断”响应程序放在哪里呢?
51单片机给每个中断安排了一个唯一的中断入口地址。
中断源的入口地址表
0003H | |
000BH | |
0013H | |
001BH | |
0023H |
★★★中断允许寄存器(IE)
![这里写图片描述](https://img-blog.csdn.net/20180705231013334?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE3MDE3NTQ1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) EA:中断总开关位。EA = 1,开中断;EA = 0,禁止所有中断。(分开关类似)
★★★中断优先级寄存器(IP)
对应中断源 |
以上表格中,若某位=1,则该对应的中断源设置为高优先级;若该位=0,则该对应的中断源设置为低优先级。 **★★★各中断源的标志位** **TCON**
SCON
IT0、IT1:外部中断0、1触发方式选择位,由软件设置。1:下降沿触发方式;0:低电平触发方式
IE0、IE1:外部中断0、1请求标志位。当外部中断0、1依据触发方式满足产生中断请求是,由硬件置位。
RI :串行口接收中断请求标志位。当串行口接收完一帧数据后请求中断时,由硬件置位(RI=1)。RI必须由软件清0。
TI:串行口发送中断请求标志位。当串行口发送完一帧数据后请求中断时,由硬件置位(TI=1)。TI必须由软件清0。
(1)中断初始化
中断系统的初始化:在为某个中断源编写中断服务程序前,首先应在主程序中对中断系统进行初始化,初始化步骤应包括:
1)软件清除相应中断源的中断标志位,以消除以前中断标志对现在的影响。
2)默认或设置中断优先级。
3)其他设置:若为外部中断,应设置是电平触发方式还是下降沿触发方式;若为定时/计数器中断,应将定时/计数初值送入寄存器THx、TLx中。
4)打开相应中断源的分开关和总开关EA。
(2)中断服务程序的预先安排
汇编语言要哟昂到ORG伪指令和JMP跳转指令,C语言要用到关键字interrupt。
中断服务程序入口地址设置
INT0_i | ||||
T0_i | ||||
INT1_i | ||||
T1_i | ||||
COM_i |
(3)中断服务程序的预先安排
ORG OOOOH
JMP Start ;跳转到主程序
ORG 00BH
JMP T0_i ;跳转到T0中断服务程序处
ORG 0030H
Start: ;主程序
……
T0_i: ;T0的中断服务程序
……
RETI ;中断返回
END
(4)中断返回
一旦某个中断请求得到响应,单片机必须把它的相应对应中断标志位清0,否则,单片机会因中断标志未能得到及时清除而重新相应同一中断请求,这是绝对不允许的。
1、外部中断标志的清除
当外部中断工作在电平触发方式下,外部中断标志IE0或IE1是依靠单片机检测其引脚INT0或INT1上为低电平而置位的。尽管RETI指令能使中断标志IE0或IE1自动清除成“0”状态,但无法改变引脚INT0或INT1上电平始终为低电平的事实,所以单机在运行过程中会再次检测到INT0或INT1引脚上的低电平而置位IE0或IE1。
2、串行口中断标志的清除
串行口有两个中断标志位TI和RI,硬件无法判别是哪个中断标志引发的中断请求,所以中断响应后,RETI指令无法自动清除中断标志,只能由软件清除。编程时应在中断服务程序的适当位置采用指令清除TI或RI。
#实验
汇编代码
******************************************************************/
* 【课程10】 ****中断系统的应用***********
* 【说 明】 ****使用T0定时1秒让LED灯闪烁一次
* 【描 述】 ****使用T0定时1秒让LED灯闪烁一次,并通过按键来控制定时器的开启和关闭。
******************************************************************/
ORG 0000H
JMP MAIN ;跳到主程序
ORG 000BH
JMP Timer0 ;跳到Timer0的中断服务程序
ORG 0030H
Timer0: MOV TH0,#3CH ;定时器T0赋初值
MOV TL0,#0B0H
INC R3 ;R3保存N值
MOV A,R3
CJNE A,#19,L1 ;A不等于19,则跳转到L1处
CLR P2.7 ;P2.7=0,点亮D1灯
L1: CJNE A,#20,L2
SETB P2.7 ;P2.7=1,熄灭D1灯
MOV R3,#00H ;N=0
L2: RETI
MAIN: MOV TMOD,#01H ;定时器T0工作在方式1下
MOV TH0,#3CH ;T0赋初值
MOV TL0,#0B0H
SETB ET0 ;ET0=1,定时器t0中断允许
SETB EA ;开中断总开关
SETB TR0 ;启动T0,开始定时
MOV R3,#00H ;R3保存N值,N=0
CLR 20H ;位地址20H处,保存标志量
LOOP: JB P3.2,$ ;如果P3.2=1,则跳到自身处继续运行
CALL DELAY
JB P3.2,LOOP
JNB P3.2,$
JB 20H,L3
SETB 20H
CLR TR0 ;关闭T0
JMP LOOP
L3: CLR 20H
SETB TR0 ;开启T0
JMP LOOP
DELAY: MOV R7,#0FFH
W1: MOV R6,#03FH
W2: DJNZ R6,W2
DJNZ R7,W1
RET
END
C代码
******************************************************************/
* 【课程10】 ****中断系统的应用***********
* 【说 明】 ****使用T0定时1秒让LED灯闪烁一次
* 【描 述】 ****使用T0定时1秒让LED灯闪烁一次,并通过按键来控制定时器的开启和关闭。
******************************************************************/
#include
#include
//---------常用的两个宏定义--------------
#define uint8 unsigned char
#define uint16 unsigned int
sbit Key=P3^2;
sbit Led=P2^7;
uint8 num; //一秒的计数变量
uint8 flag;
/************************************
函数名:Timer0_I()
功能:中断服务程序
************************************/
void Timer0_I() interrupt 1
{
TH0=0x3c; //重装初值
TL0=0xb0;
num++; //计时变量+1
if(num==20) {Led=~Led; num=0;}
}
/************************************
函数名:main()
功能:主程序
************************************/
void main()
{
TMOD=0x01; //选择定时器0工作在定时方式1
TH0=0x3c; //定时50ms,装初值
TL0=0xb0;
ET0=1; //开启定时中断
EA=1; //开总中断
TR0=1; //开启定时器T0
num=0;
flag=0;
while(1)
{
if(Key==0) //有键按下
{
if(flag==0)
{flag=1; TR0=0;} //关闭定时器T0
else
{flag=0; TR0=1;} //开启定时器T0
}
}
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』