单片机中断原理(外部中断)
中断概念:
中断发生:CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理。
中断响应和中断服务:CPU暂时中断当前的工作,转去处理事件B。
中断返回:待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A。
这一过程被称为中断。
中断过程示意图:
一些关于中断过程的名词:
中断源:引起CPU中断的根源。
中断源向CPU提出中断请求。
断点:原来被中断的地方。
中断系统:实现上述中断功能的部件。
80C51中断系统的结构:
5个中断源(8052有6个),2个优先级。
可实现二级中断嵌套。
结构如下图:
中断过程:
IT0(TCON.0)可选择P3.2时低电平有效还是下降沿有效。
当CPU检测到P3.2引脚上出现有效的中断信号时,中断标志IE0(TCON.1)置1,向CPU申请中断。
要实现上述平平无奇看似简单的中断过程,你需要了解单片机中的如下端口!!
是由这些端口的控制中断过程才能完成的~
中断允许控制:
CPU对中断系统所有中断以及某个中断源的开放和屏蔽都是由中断允许寄存器IE控制的.
IE说明:
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
字节地址:A8H | EA | ES | ET1 | EX1 | ET0 | EX0 | IE |
EX0:外部中断0允许位.
ET0:定时/计数器T0中断允许位.
EX1:外部中断1允许位.
ET1:定时/计数器T1中断允许位.
ES:串行口中断允许位.
EA:CPU中断允许位.(总允许位).
中断请求标志:
TCON说明:
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
字节地址:88H | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 | TCON |
IT0:外部中断0触发方式控制位.
IT0=O:电平触发方式.
IT0=1:边沿触发方式(下降沿有效).
IE0: 外部中断0中断请求标志位.
IT1:外部中断1触发方式控制位.
IT1=0:电平触发方式.
IT1=1:边沿触发方式(下降沿有效).
IE1: 外部中断0中断请求标志位.
TF0:定时/计数器T0溢出中断请求标志位.
TF1:定时/计数器T1溢出中断请求标志位.
中断优先级控制:
80C51有两个中断优先级.
每个中断源的中断优先级都是由中断优先级寄存器IP(interrupt priority)中的相应位的状态来规定的.
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
字节地址:B8H | PT2 | PS | PT1 | PX1 | PT0 | PX0 | IP |
PT2(IP.5):若=1,定时器2中断设为高优先级(只适用于8052及其增强型)
PS(IP.4):若=1,串行中断设为高优先级
PT1(IP.3):若=1,定时器1中断设为高优先级
PX1(IP.2):若=1,外部中断1设为高优先级
PT0(IP.1):若=1,定时器0中断设为高优先级
PX0(IP.0):若=1,外部中断0设为高优先级
如果同一优先级的中断申请不止一个,那么它们的顺序怎么确定呢?
中断系统硬件内存在自然优先级,可以解决中断优先权的排序问题.
(就是说内部程序已经默认定义好优先级啦~)
单片机的外部中断口:
80C52单片机提供了两个外部中断口: INT0(P3.2)和INT1(P3.3)。
划重点啦,所以如何实现一次中断呢?
中断响应条件:
1.中断源有中断请求.
当你按下按钮或者xxx,特定端口出现了中断信号(你刚刚设定了的中断信号的触发方式,电平or边沿).
2.此中断源对应的终端允许位=1.
3.总允许位EA=1.
仿真实验:
-
#include<reg52.h>
-
#define uint unsigned int
-
#define uchar unsigned char
-
-
sbit dula=P2^
6;
-
sbit wela=P2^
7;
//为了控制七段数码管的段选与位选
-
uchar num;
-
uchar code table[]={
0x3f ,
0x06 ,
0x5b ,
0x4f,
0x66 ,
0x6d,
0x7d ,
0x07 ,
0x7f,
0x6f};
//便于数码管显示
-
sbit LA=P2^
5;
-
void delay(uint z);
//延迟
-
void main()
-
{
-
EA=
1;
//总允许
-
EX0=
1;
//对应中断允许位
-
IT0=
1;
//中断信号触发方式:电平
-
-
P1=
0xff;
//LED灯们全熄灭
-
-
wela=
1;
//位选信号
-
IT0=
1;
-
P0=
0xc0;
-
wela=
0;
-
-
while(
1)
-
{
-
for(num=
0;num<
9;num++)
-
{
-
P1=
0xff;
-
-
wela=
1;
-
P0=
0xc0;
-
wela=
0;
-
-
dula=
1;
-
P0=table[num];
//数码管显示
-
dula=
0;
-
-
delay(
1000);
-
-
}
-
-
}
-
-
}
-
void delay(uint z)
-
{
-
uint x,y;
-
for(x=z;x>
0;x--)
-
for(y=
110;y>
0;y--);
-
}
-
-
//中断函数写法
-
-
void enter0() interrupt 0
-
{
-
LA=
1;
-
P1=
0x00;
//LED灯全点亮
-
-
}
敲黑板划重点!请注意中断函数的写法!
interrupt 0: 指明中断源。
interrupt 0 指明是外部中断0;
interrupt 1 指明是定时器中断0;
interrupt 2 指明是外部中断1;
interrupt 3 指明是定时器中断1;
interrupt 4 指明是串行口中断;
-
void enter0() interrupt 0
-
{
-
LA=
1;
-
P1=
0x00;
-
-
}
这个代码实现的功能很简单呐。
数码管0-9依次变化,当按下按钮(即制造出中断信号)时,数码管停止变化,LED灯们点亮。
仿真截图:
一个很简单的中断信号产生电路哈哈哈哈。
下次要总结电平触发方式和边沿触发方式对功能实现的差别~
奥里给!
转载:https://blog.csdn.net/weixin_44972816/article/details/104499756