一、什么是外部中断
外部中断,就是通过单片机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(最高) | 中断请求标志位 | 中断允许控制位 |
INT0 | 0003H | 0(最高) | PX0 | 0 | 1 | IE0 | EX0、EA |
INT1 | 0013H | 2 | PX1 | 0 | 1 | IE1 | EX1、EA |
INT2 | 0053H | 10 | 0 | 0 | 无 | 无 | EX2、EA |
INT3 | 005BH | 11 | 0 | 0 | 无 | 无 | EX3、EA |
INT4 | 0083H | 16 | 0 | 0 | 无 | 无 | EX4、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中声明中断函数文章来源:https://www.toymoban.com/news/detail-839080.html
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;
文章来源地址https://www.toymoban.com/news/detail-839080.html
七、外部中断的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;
}
到了这里,关于STC15系列单片机学习6:外部中断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!