STC15系列单片机学习6:外部中断

一、什么是外部中断

外部中断,就是通过单片机IO引脚电平的变化触发的中断。

二、STC15系列单片机有哪些外部中断

STC15系列单片机的外部中断源一共有5个,分别是外部中断0(INT0)、外部中断1(INT1)、外部中断2(INT2)、外部中断3(INT3)、外部中断4(INT4);当然不是所有的STC15系列单片机都有着5个外部中断。

三、外部中断的触发方式

中断源触发行为
外部中断0(INT0)IT0 = 1:下降沿;IT0 = 0:上升沿和下降沿均可
外部中断1(INT1)IT1 = 1:下降沿;IT1 = 0:上升沿和下降沿均可
外部中断2(INT2)仅下降沿
外部中断3(INT3)仅下降沿
外部中断4(INT4)仅下降沿

INT0和INT1:既可以上升沿触发,又可以下降沿触发,可以设置中断优先级

 

INT2、INT3、INT4:只能下降沿触发,不能设置中断优先级,优先级固定为0

四、外部中断的中断入口地址、查询次序、优先级、请求标志、允许位

中断源中断向量地址相同优先级内的查询次序中断优先级设置优先级0(最低)优先级1(最高)中断请求标志位中断允许控制位
INT00003H0(最高)PX001IE0EX0、EA
INT10013H2PX101IE1EX1、EA
INT20053H1000EX2、EA
INT3005BH1100EX3、EA
INT40083H1600EX4、EA

五、与外部中断相关的寄存器(红框的部分是用得上的)

 

 

中断允许寄存器IE

STC15系列单片机CPU对中断源的开放和屏蔽,是通过内部的中断允许寄存器IE来控制的。针对外部中断,IE寄存器里面能用到的位分别是EA、EX1、EX0。

EA:CPU的中断总开关,EA=1,CPU开放中断;EA=0,CPU屏蔽所有中断;

EX1:外部中断1中断允许位,EX1=1,允许外部中断1中断;EX1=0,禁止外部中断1中断;

EX0:外部中断1中断允许位,EX0=1,允许外部中断0中断;EX0=0,禁止外部中断0中断;

按道理外部中断2、外部中断3、外部中断4的中断允许也在这个IE寄存器里面设置吧,再怎么也得在IE2寄存器里面设置吧;这是因为STC15系列单片机是一个加强型的单片机,在intel原始的51内核上添加了太多功能,又要兼容原始的51内核,只能扩充更多的寄存器了,接下来的INT_CLKO(AUXR2)寄存器就是STC15系列单片机扩充出来的。就好比买了一艘破船,装修一下,乱七八糟什么武器都往上面装,搞得功能超级强大。

外部中断允许和时钟输出寄存器INT_CLKO(AUXR2)

前面说过INT_CLKO(AUXR2)寄存器是STC15系列单片机扩充出来的,外部中断2/3/4的中断允许为就放在这个寄存器里面,分别是EX2/EX3/EX4。

EX4:外部中断4中断允许位,EX4=1,允许外部中断4中断;EX4=0,禁止外部中断4中断;

EX3:外部中断3中断允许位,EX3=1,允许外部中断3中断;EX3=0,禁止外部中断3中断;

EX2:外部中断2中断允许位,EX2=1,允许外部中断2中断;EX2=0,禁止外部中断4中断;

中断优先级控制寄存器IP

STC15系列单片机的中断有两个中断优先等级,优先级0(低优先级)和优先级1(高优先级),外部中断0(INT0)和外部中断1(INT1)可以设置在这两个等级中的一个,外部中断2/3/4就只能设置在等级0,也不用设置,单片机设计的时候就已经设置好了。所以IP寄存器里面能用到的就两个位PX1和PX0。

PX1:外部中断1优先级控制位;

        当PX1 = 0时,外部中断1为最低优先级中断(优先级0);

        当PX1 = 1时,外部中断1为最高优先级中断(优先级1);

PX0:外部中断0优先级控制位;

        当PX0 = 0时,外部中断0为最低优先级中断(优先级0);

        当PX0 = 1时,外部中断0为最高优先级中断(优先级1);

定时器/计数器控制寄存器TCON

TCON是定时器/计数器T0和T1的控制寄存器,估计STC公司也是想节约资源,把外部中断0和外部中断1的请求中断源和中断状态标志位也放在这个寄存器里面。前面说过外部中断0和外部中断1可以设置成上升沿还活着下降沿触发外部中断,需要用到的寄存器就是TCON,对应的位是IT1和IT0,还有对应的中断状态标志位分别是IE1和IE0。

IE1:外部中断1的中断请求标志,IE1=1,外部中断向CPU请求中断,当CPU响应改中断时,由硬件清零IE1;

IT1:外部中断1中断源类型选择位。IT1=0,P3.3(INT1)引脚上只要有电平变化,不管是上升沿还是下降沿,都可触发外部中断1。IT1=1时,只有下降沿可以触发外部中断1。

IE0:外部中断0的中断请求标志,IE0=1,外部中断向CPU请求中断,当CPU响应改中断时,由硬件清零IE0;

IT0:外部中断0中断源类型选择位。IT0=0,P3.2(INT0)引脚上只要有电平变化,不管是上升沿还是下降沿,都可触发外部中断0。IT0=1时,只有下降沿可以触发外部中断0。

六、外部中断的应用

在Keil C中声明中断函数

void Int0_Routine(void)        interrupt0;
void Int1_Routine(void)        interrupt2;
void Int2_Routine(void)        interrupt10;
void Int3_Routine(void)        interrupt11;
void Int4_Routine(void)        interrupt16;

七、外部中断的C语言实现

外部中断0(上升沿与下降沿都触发)

#include "STC15.h" 
#include "intrins.h"

bit FLAG;//中断边沿的类型的判断

sbit	P10	= P1^0; //随便定义一个测试引脚,用于检验中断是否发生


void main()
{
	/*INT0在STC15.h头文件中有定义 sbit INT0 = P3^2;*/
	INT0	= 1; //将外部中断0的引脚INT0,也就是P3^2初始电平设置为高电平
	IT0 	= 0; //IT0 = 0,表示上升沿和下降沿都可以触发中断
	EX0 	= 1; //外部中断0的使能位打开
	EA 		= 1; //中断总开关打开
	
	/*至此,只要P3^2引脚的电平边沿有变化,就会触发外部中断0,
	程序就会跳转到中断服务程序*/
	
	while(1);
}

/*外部中断0 的中断服务程序*/
void Int0_Routine(void)        interrupt0
{
	P10 = !P10; //将测试引脚电平翻转
	
	/*FLAG用于记录中断引脚的电平;
	INT0 = 0,电平从1变成0,是下降沿;
	INT0 = 1,电平从0变成1,是上升沿;*/
	FLAG = INT0; 
}

外部中断0(下降沿触发)

#include "STC15.h" 
#include "intrins.h"


sbit	P10	= P1^0; //随便定义一个测试引脚,用于检验中断是否发生


void main()
{
	/*INT0在STC15.h头文件中有定义 sbit INT0 = P3^2;*/
	INT0	= 1; //将外部中断0的引脚INT0,也就是P3^2初始电平设置为高电平
	IT0 	= 1; //IT0 = 1,表示下降沿触发中断
	EX0 	= 1; //外部中断0的使能位打开
	EA 		= 1; //中断总开关打开
	
	/*至此,只要P3^2引脚的电平边沿有变化,就会触发外部中断0,
	程序就会跳转到中断服务程序*/
	
	while(1);
}

/*外部中断0 的中断服务程序*/
void Int0_Routine(void)        interrupt0
{
	P10 = !P10; //将测试引脚电平翻转
}

外部中断1(上升沿与下降沿都触发)

#include "STC15.h" 
#include "intrins.h"

bit FLAG;//中断边沿的类型的判断

sbit	P10	= P1^0; //随便定义一个测试引脚,用于检验中断是否发生


void main()
{
	/*INT1在STC15.h头文件中有定义 sbit INT1 = P3^3;*/
	INT1	= 1; //将外部中断1的引脚INT1,也就是P3^3初始电平设置为高电平
	IT1 	= 0; //IT1 = 0,表示上升沿和下降沿都可以触发中断
	EX1 	= 1; //外部中断1的使能位打开
	EA 		= 1; //中断总开关打开
	
	/*至此,只要P3^3引脚的电平边沿有变化,就会触发外部中断1,
	程序就会跳转到中断服务程序*/
	
	while(1);
}

/*外部中断1 的中断服务程序*/
void Int1_Routine(void)        interrupt2
{
	P10 = !P10; //将测试引脚电平翻转
	
	/*FLAG用于记录中断引脚的电平;
	INT1 = 0,电平从1变成0,是下降沿;
	INT1 = 1,电平从0变成1,是上升沿;*/
	FLAG = INT1; 
}

外部中断1(下降沿触发)

#include "STC15.h" 
#include "intrins.h"


sbit	P10	= P1^0; //随便定义一个测试引脚,用于检验中断是否发生


void main()
{
	/*INT1在STC15.h头文件中有定义 sbit INT1 = P3^3;*/
	INT1	= 1; //将外部中断0的引脚INT0,也就是P3^2初始电平设置为高电平
	IT0 	= 1; //IT0 = 1,表示下降沿触发中断
	EX0 	= 1; //外部中断0的使能位打开
	EA 		= 1; //中断总开关打开
	
	/*至此,只要P3^2引脚的电平边沿有变化,就会触发外部中断0,
	程序就会跳转到中断服务程序*/
	
	while(1);
}

/*外部中断1 的中断服务程序*/
void Int1_Routine(void)        interrupt2
{
	P10 = !P10; //将测试引脚电平翻转
}

外部中断2(下降沿触发)

#include "STC15.h" 
#include "intrins.h"

/*一般sfr INT_CLKO = 0x8F;这条语句在STC15.h中有,在程序中就不用再写了*/
sfr		INT_CLKO = 0x8F; //外部中断与时钟输出控制寄存器

sbit	P10	= P1^0; //随便定义一个测试引脚,用于检验中断是否发生


void main()
{
	INT_CLKO	|= 0x10; //相当于EX2=1,使能外部中断2
	
	EA 		= 1; //中断总开关打开
	
	/*至此,只要INT2引脚有下降沿,就会触发外部中断2,
	程序就会跳转到中断服务程序*/
	
	while(1);
}

/*外部中断2 的中断服务程序*/
void Int2_Routine(void)        interrupt10
{
	P10 = !P10; //将测试引脚电平翻转
	
	/*如果需要手动清除中断标志位,先关闭中断,系统会自动清除内部的中断标志;
	再重新开启中断*/
	//INT_CLKO &= 0xEF;
	//INT_CLKO |= 0x10;
}

外部中断3(下降沿触发)

#include "STC15.h" 
#include "intrins.h"

/*一般sfr INT_CLKO = 0x8F;这条语句在STC15.h中有,在程序中就不用再写了*/
sfr		INT_CLKO = 0x8F; //外部中断与时钟输出控制寄存器

sbit	P10	= P1^0; //随便定义一个测试引脚,用于检验中断是否发生


void main()
{
	INT_CLKO	|= 0x20; //相当于EX3=1,使能外部中断3
	
	EA 		= 1; //中断总开关打开
	
	/*至此,只要INT3引脚的有下降沿,就会触发外部中断3,
	程序就会跳转到中断服务程序*/
	
	while(1);
}

/*外部中断3 的中断服务程序*/
void Int3_Routine(void)        interrupt11
{
	P10 = !P10; //将测试引脚电平翻转
	
	/*如果需要手动清除中断标志位,先关闭中断,系统会自动清除内部的中断标志;
	再重新开启中断*/
	//INT_CLKO &= 0xDF;
	//INT_CLKO |= 0x20;
}

外部中断4(下降沿触发)

#include "STC15.h" 
#include "intrins.h"

/*一般sfr INT_CLKO = 0x8F;这条语句在STC15.h中有,在程序中就不用再写了*/
sfr		INT_CLKO = 0x8F; //外部中断与时钟输出控制寄存器

sbit	P10	= P1^0; //随便定义一个测试引脚,用于检验中断是否发生


void main()
{
	INT_CLKO	|= 0x40; //相当于EX4=1,使能外部中断4
	
	EA 		= 1; //中断总开关打开
	
	/*至此,只要INT4引脚的有下降沿,就会触发外部中断4,
	程序就会跳转到中断服务程序*/
	
	while(1);
}

/*外部中断4 的中断服务程序*/
void Int4_Routine(void)        interrupt16
{
	P10 = !P10; //将测试引脚电平翻转
	
	/*如果需要手动清除中断标志位,先关闭中断,系统会自动清除内部的中断标志;
	再重新开启中断*/
	//INT_CLKO &= 0xBF;
	//INT_CLKO |= 0x40;
}

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值