一、什么是外部中斷
外部中斷,就是通過單片機IO引腳電平的變化觸發(fā)的中斷。
二、STC15系列單片機有哪些外部中斷
STC15系列單片機的外部中斷源一共有5個,分別是外部中斷0(INT0)、外部中斷1(INT1)、外部中斷2(INT2)、外部中斷3(INT3)、外部中斷4(INT4);當然不是所有的STC15系列單片機都有著5個外部中斷。
三、外部中斷的觸發(fā)方式
中斷源 | 觸發(fā)行為 |
外部中斷0(INT0) | IT0 = 1:下降沿;IT0 = 0:上升沿和下降沿均可 |
外部中斷1(INT1) | IT1 = 1:下降沿;IT1 = 0:上升沿和下降沿均可 |
外部中斷2(INT2) | 僅下降沿 |
外部中斷3(INT3) | 僅下降沿 |
外部中斷4(INT4) | 僅下降沿 |
INT0和INT1:既可以上升沿觸發(fā),又可以下降沿觸發(fā),可以設(shè)置中斷優(yōu)先級
?
INT2、INT3、INT4:只能下降沿觸發(fā),不能設(shè)置中斷優(yōu)先級,優(yōu)先級固定為0
四、外部中斷的中斷入口地址、查詢次序、優(yōu)先級、請求標志、允許位
中斷源 | 中斷向量地址 | 相同優(yōu)先級內(nèi)的查詢次序 | 中斷優(yōu)先級設(shè)置 | 優(yōu)先級0(最低) | 優(yōu)先級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 |
五、與外部中斷相關(guān)的寄存器(紅框的部分是用得上的)
?
?
中斷允許寄存器IE
STC15系列單片機CPU對中斷源的開放和屏蔽,是通過內(nèi)部的中斷允許寄存器IE來控制的。針對外部中斷,IE寄存器里面能用到的位分別是EA、EX1、EX0。
EA:CPU的中斷總開關(guān),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寄存器里面設(shè)置吧,再怎么也得在IE2寄存器里面設(shè)置吧;這是因為STC15系列單片機是一個加強型的單片機,在intel原始的51內(nèi)核上添加了太多功能,又要兼容原始的51內(nèi)核,只能擴充更多的寄存器了,接下來的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中斷;
中斷優(yōu)先級控制寄存器IP
STC15系列單片機的中斷有兩個中斷優(yōu)先等級,優(yōu)先級0(低優(yōu)先級)和優(yōu)先級1(高優(yōu)先級),外部中斷0(INT0)和外部中斷1(INT1)可以設(shè)置在這兩個等級中的一個,外部中斷2/3/4就只能設(shè)置在等級0,也不用設(shè)置,單片機設(shè)計的時候就已經(jīng)設(shè)置好了。所以IP寄存器里面能用到的就兩個位PX1和PX0。
PX1:外部中斷1優(yōu)先級控制位;
? ? ? ? 當PX1 = 0時,外部中斷1為最低優(yōu)先級中斷(優(yōu)先級0);
????????當PX1 = 1時,外部中斷1為最高優(yōu)先級中斷(優(yōu)先級1);
PX0:外部中斷0優(yōu)先級控制位;
? ? ? ? 當PX0 = 0時,外部中斷0為最低優(yōu)先級中斷(優(yōu)先級0);
????????當PX0 = 1時,外部中斷0為最高優(yōu)先級中斷(優(yōu)先級1);
定時器/計數(shù)器控制寄存器TCON
TCON是定時器/計數(shù)器T0和T1的控制寄存器,估計STC公司也是想節(jié)約資源,把外部中斷0和外部中斷1的請求中斷源和中斷狀態(tài)標志位也放在這個寄存器里面。前面說過外部中斷0和外部中斷1可以設(shè)置成上升沿還活著下降沿觸發(fā)外部中斷,需要用到的寄存器就是TCON,對應(yīng)的位是IT1和IT0,還有對應(yīng)的中斷狀態(tài)標志位分別是IE1和IE0。
IE1:外部中斷1的中斷請求標志,IE1=1,外部中斷向CPU請求中斷,當CPU響應(yīng)改中斷時,由硬件清零IE1;
IT1:外部中斷1中斷源類型選擇位。IT1=0,P3.3(INT1)引腳上只要有電平變化,不管是上升沿還是下降沿,都可觸發(fā)外部中斷1。IT1=1時,只有下降沿可以觸發(fā)外部中斷1。
IE0:外部中斷0的中斷請求標志,IE0=1,外部中斷向CPU請求中斷,當CPU響應(yīng)改中斷時,由硬件清零IE0;
IT0:外部中斷0中斷源類型選擇位。IT0=0,P3.2(INT0)引腳上只要有電平變化,不管是上升沿還是下降沿,都可觸發(fā)外部中斷0。IT0=1時,只有下降沿可以觸發(fā)外部中斷0。
六、外部中斷的應(yīng)用
在Keil C中聲明中斷函數(shù)文章來源:http://www.zghlxwxcb.cn/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;
文章來源地址http://www.zghlxwxcb.cn/news/detail-839080.html
七、外部中斷的C語言實現(xiàn)
外部中斷0(上升沿與下降沿都觸發(fā))
#include "STC15.h"
#include "intrins.h"
bit FLAG;//中斷邊沿的類型的判斷
sbit P10 = P1^0; //隨便定義一個測試引腳,用于檢驗中斷是否發(fā)生
void main()
{
/*INT0在STC15.h頭文件中有定義 sbit INT0 = P3^2;*/
INT0 = 1; //將外部中斷0的引腳INT0,也就是P3^2初始電平設(shè)置為高電平
IT0 = 0; //IT0 = 0,表示上升沿和下降沿都可以觸發(fā)中斷
EX0 = 1; //外部中斷0的使能位打開
EA = 1; //中斷總開關(guān)打開
/*至此,只要P3^2引腳的電平邊沿有變化,就會觸發(fā)外部中斷0,
程序就會跳轉(zhuǎn)到中斷服務(wù)程序*/
while(1);
}
/*外部中斷0 的中斷服務(wù)程序*/
void Int0_Routine(void) interrupt0
{
P10 = !P10; //將測試引腳電平翻轉(zhuǎn)
/*FLAG用于記錄中斷引腳的電平;
INT0 = 0,電平從1變成0,是下降沿;
INT0 = 1,電平從0變成1,是上升沿;*/
FLAG = INT0;
}
外部中斷0(下降沿觸發(fā))
#include "STC15.h"
#include "intrins.h"
sbit P10 = P1^0; //隨便定義一個測試引腳,用于檢驗中斷是否發(fā)生
void main()
{
/*INT0在STC15.h頭文件中有定義 sbit INT0 = P3^2;*/
INT0 = 1; //將外部中斷0的引腳INT0,也就是P3^2初始電平設(shè)置為高電平
IT0 = 1; //IT0 = 1,表示下降沿觸發(fā)中斷
EX0 = 1; //外部中斷0的使能位打開
EA = 1; //中斷總開關(guān)打開
/*至此,只要P3^2引腳的電平邊沿有變化,就會觸發(fā)外部中斷0,
程序就會跳轉(zhuǎn)到中斷服務(wù)程序*/
while(1);
}
/*外部中斷0 的中斷服務(wù)程序*/
void Int0_Routine(void) interrupt0
{
P10 = !P10; //將測試引腳電平翻轉(zhuǎn)
}
外部中斷1(上升沿與下降沿都觸發(fā))
#include "STC15.h"
#include "intrins.h"
bit FLAG;//中斷邊沿的類型的判斷
sbit P10 = P1^0; //隨便定義一個測試引腳,用于檢驗中斷是否發(fā)生
void main()
{
/*INT1在STC15.h頭文件中有定義 sbit INT1 = P3^3;*/
INT1 = 1; //將外部中斷1的引腳INT1,也就是P3^3初始電平設(shè)置為高電平
IT1 = 0; //IT1 = 0,表示上升沿和下降沿都可以觸發(fā)中斷
EX1 = 1; //外部中斷1的使能位打開
EA = 1; //中斷總開關(guān)打開
/*至此,只要P3^3引腳的電平邊沿有變化,就會觸發(fā)外部中斷1,
程序就會跳轉(zhuǎn)到中斷服務(wù)程序*/
while(1);
}
/*外部中斷1 的中斷服務(wù)程序*/
void Int1_Routine(void) interrupt2
{
P10 = !P10; //將測試引腳電平翻轉(zhuǎn)
/*FLAG用于記錄中斷引腳的電平;
INT1 = 0,電平從1變成0,是下降沿;
INT1 = 1,電平從0變成1,是上升沿;*/
FLAG = INT1;
}
外部中斷1(下降沿觸發(fā))
#include "STC15.h"
#include "intrins.h"
sbit P10 = P1^0; //隨便定義一個測試引腳,用于檢驗中斷是否發(fā)生
void main()
{
/*INT1在STC15.h頭文件中有定義 sbit INT1 = P3^3;*/
INT1 = 1; //將外部中斷0的引腳INT0,也就是P3^2初始電平設(shè)置為高電平
IT0 = 1; //IT0 = 1,表示下降沿觸發(fā)中斷
EX0 = 1; //外部中斷0的使能位打開
EA = 1; //中斷總開關(guān)打開
/*至此,只要P3^2引腳的電平邊沿有變化,就會觸發(fā)外部中斷0,
程序就會跳轉(zhuǎn)到中斷服務(wù)程序*/
while(1);
}
/*外部中斷1 的中斷服務(wù)程序*/
void Int1_Routine(void) interrupt2
{
P10 = !P10; //將測試引腳電平翻轉(zhuǎn)
}
外部中斷2(下降沿觸發(fā))
#include "STC15.h"
#include "intrins.h"
/*一般sfr INT_CLKO = 0x8F;這條語句在STC15.h中有,在程序中就不用再寫了*/
sfr INT_CLKO = 0x8F; //外部中斷與時鐘輸出控制寄存器
sbit P10 = P1^0; //隨便定義一個測試引腳,用于檢驗中斷是否發(fā)生
void main()
{
INT_CLKO |= 0x10; //相當于EX2=1,使能外部中斷2
EA = 1; //中斷總開關(guān)打開
/*至此,只要INT2引腳有下降沿,就會觸發(fā)外部中斷2,
程序就會跳轉(zhuǎn)到中斷服務(wù)程序*/
while(1);
}
/*外部中斷2 的中斷服務(wù)程序*/
void Int2_Routine(void) interrupt10
{
P10 = !P10; //將測試引腳電平翻轉(zhuǎn)
/*如果需要手動清除中斷標志位,先關(guān)閉中斷,系統(tǒng)會自動清除內(nèi)部的中斷標志;
再重新開啟中斷*/
//INT_CLKO &= 0xEF;
//INT_CLKO |= 0x10;
}
外部中斷3(下降沿觸發(fā))
#include "STC15.h"
#include "intrins.h"
/*一般sfr INT_CLKO = 0x8F;這條語句在STC15.h中有,在程序中就不用再寫了*/
sfr INT_CLKO = 0x8F; //外部中斷與時鐘輸出控制寄存器
sbit P10 = P1^0; //隨便定義一個測試引腳,用于檢驗中斷是否發(fā)生
void main()
{
INT_CLKO |= 0x20; //相當于EX3=1,使能外部中斷3
EA = 1; //中斷總開關(guān)打開
/*至此,只要INT3引腳的有下降沿,就會觸發(fā)外部中斷3,
程序就會跳轉(zhuǎn)到中斷服務(wù)程序*/
while(1);
}
/*外部中斷3 的中斷服務(wù)程序*/
void Int3_Routine(void) interrupt11
{
P10 = !P10; //將測試引腳電平翻轉(zhuǎn)
/*如果需要手動清除中斷標志位,先關(guān)閉中斷,系統(tǒng)會自動清除內(nèi)部的中斷標志;
再重新開啟中斷*/
//INT_CLKO &= 0xDF;
//INT_CLKO |= 0x20;
}
外部中斷4(下降沿觸發(fā))
#include "STC15.h"
#include "intrins.h"
/*一般sfr INT_CLKO = 0x8F;這條語句在STC15.h中有,在程序中就不用再寫了*/
sfr INT_CLKO = 0x8F; //外部中斷與時鐘輸出控制寄存器
sbit P10 = P1^0; //隨便定義一個測試引腳,用于檢驗中斷是否發(fā)生
void main()
{
INT_CLKO |= 0x40; //相當于EX4=1,使能外部中斷4
EA = 1; //中斷總開關(guān)打開
/*至此,只要INT4引腳的有下降沿,就會觸發(fā)外部中斷4,
程序就會跳轉(zhuǎn)到中斷服務(wù)程序*/
while(1);
}
/*外部中斷4 的中斷服務(wù)程序*/
void Int4_Routine(void) interrupt16
{
P10 = !P10; //將測試引腳電平翻轉(zhuǎn)
/*如果需要手動清除中斷標志位,先關(guān)閉中斷,系統(tǒng)會自動清除內(nèi)部的中斷標志;
再重新開啟中斷*/
//INT_CLKO &= 0xBF;
//INT_CLKO |= 0x40;
}
到了這里,關(guān)于STC15系列單片機學習6:外部中斷的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!