1、中斷的概念
對(duì)于單片機(jī)中斷的概念,我們可以這樣理解:?jiǎn)纹瑱C(jī)處理某一事件A時(shí),發(fā)生了另一事件B請(qǐng)求(中斷請(qǐng)求);單片機(jī)暫時(shí)中斷當(dāng)前工作,轉(zhuǎn)去處理事件B(中斷響應(yīng)和中斷服務(wù));待單片機(jī)將事件B處理完畢,再回到原來事件A被中斷的地方繼續(xù)處理事件A(中斷返回),這一過程稱為中斷。 引起單片機(jī)中斷的根源或原因: 中斷源向單片機(jī)提出中斷請(qǐng)求。
2、中斷優(yōu)先級(jí) 單片機(jī)的中斷系統(tǒng)一般允許多個(gè)中斷源,當(dāng)幾個(gè)中斷源同時(shí)向單片機(jī)請(qǐng)求中斷,要求為它服務(wù)的時(shí)候,這就存在單片機(jī)優(yōu)先響應(yīng)哪一個(gè)中斷源請(qǐng)求的問題。通常根據(jù)中斷源的輕重緩急排隊(duì),優(yōu)先處理最緊急事件的中斷請(qǐng)求源,即規(guī)定每一個(gè)中斷源有一個(gè)優(yōu)先級(jí)別。單片機(jī)總是先響應(yīng)優(yōu)先級(jí)別最高的中斷請(qǐng)求。 中斷優(yōu)先級(jí)的三條原則: a:?jiǎn)纹瑱C(jī)同時(shí)接收到幾個(gè)中斷時(shí),響應(yīng)優(yōu)先級(jí)別最高的中斷請(qǐng)求。 b:正在進(jìn)行的中斷過程不能被新同級(jí)或低優(yōu)先級(jí)的中斷請(qǐng)求所中斷。 c:正在進(jìn)行的低優(yōu)先級(jí)中斷服務(wù),能被高優(yōu)先級(jí)中斷請(qǐng)求所中斷。
3、中斷嵌套
當(dāng)單片機(jī)正在處理一個(gè)中斷請(qǐng)求源的時(shí)候(執(zhí)行相應(yīng)的中斷服務(wù)程序),發(fā)生了另外一個(gè)優(yōu)先級(jí)比它還高的中斷源請(qǐng)求。單片機(jī)暫停對(duì)原來中斷源的服務(wù)程序,轉(zhuǎn)而去處理優(yōu)先級(jí)更高的中斷請(qǐng)求源,處理完以后,再回到原低級(jí)中斷服務(wù)程序,這樣的過程稱為中斷嵌套。 4、單片機(jī)內(nèi)部中斷電路和寄存器
我們以STC單片機(jī)為例進(jìn)行介紹: 上圖是單片機(jī)內(nèi)部和中斷有關(guān)的電路,從圖中我們知道單片機(jī)可以有5個(gè)中斷源,分別是/INT0,T0,/INT1,T1,RX和TX。/INT0和/INT1為外部中斷源;T0和T1為定時(shí)器/計(jì)數(shù)器中斷;RX和TX為串口收發(fā)中斷。 相關(guān)寄存器有TCON,IE,IP,這些寄存器又是起什么作用的呢: TF1是定時(shí)器1的溢出標(biāo)志位,當(dāng)定時(shí)器1發(fā)生溢出時(shí),此位變成1,同時(shí)提出中斷請(qǐng)求,一直保持到CPU響應(yīng)中斷時(shí),才由硬件清0。如果程序不是采用中斷的方式,而是采用查詢的方式,那么這位需要軟件清0。 TR1是定時(shí)器1的運(yùn)行控制位,當(dāng)它為1時(shí)允許定時(shí)器1開始計(jì)數(shù),為0時(shí)禁止定時(shí)器1計(jì)數(shù)。 TF0和TR0的功能分別與TF1和TR1類似,它們對(duì)應(yīng)的是定時(shí)器0。 對(duì)于IE1,IT1,IEO,IT0的功能在上圖中有描述了,就不多說了。

IE寄存器是中斷允許寄存器,只有相應(yīng)的位置為1了,相關(guān)的中斷才能被允許哦。 IP寄存器是中斷優(yōu)先級(jí)控制寄存器,當(dāng)某位被設(shè)成1了,那么對(duì)應(yīng)的中斷源就是高優(yōu)先級(jí)了哦,就可以中斷低優(yōu)先級(jí)中斷源的處理函數(shù)了哦。
好了,今天給大家介紹了單片機(jī)內(nèi)部中斷電路和相關(guān)的寄存器,明天給結(jié)合程序給大家講述如何實(shí)現(xiàn)單片機(jī)中斷功能。
上一條分享我們提到單片機(jī)一般有5個(gè)中斷源,在這條分享中我們看看如何通過編程實(shí)現(xiàn)這些中斷功能。
1、外部中斷
外部中斷源有:INT0和INT1,可由外部信號(hào)引發(fā)單片機(jī)的中斷,我們需要將信號(hào)引到單片機(jī)的INT0和INT1管腳上。外部中斷INTO和INT1即可底電平觸發(fā),也可下降沿觸發(fā)。相關(guān)的寄存器有TCON,IE,IP。
下面我們通過一段例程序理解下,怎樣編寫代碼:
#include “reg51.h”
void init_int0(void) //中斷功能的初始化函數(shù),只有對(duì)相關(guān)的寄存器進(jìn)行了正確的
配置,采用運(yùn)用單片機(jī)的中斷功能哦。
{
IT0=1; //IT0是寄存器TCON的最低位,在這里設(shè)成1,單片機(jī)管腳INT0上的信號(hào)低跳變(下降沿)引發(fā)中斷。
EX0=1; //EX0是寄存器IE的最低位,在這里設(shè)成1,允許發(fā)生INT0中斷。
EA=1; //EA是寄存器IE的最高位,在這里設(shè)成1,相當(dāng)于開啟了允許中斷的總開關(guān)。只有EA和EX0都設(shè)成1了, 才開啟了INTO中斷功能哦。
}
void main(void)
{
init_int0(); //需要在主函數(shù)中,對(duì)INT0的相關(guān)寄存器進(jìn)行初始化配置的。
while(1);
}
Void exint0() interrupt 0 //中斷函數(shù),把我們希望實(shí)現(xiàn)的功能加進(jìn)入,這里面的代碼應(yīng)該盡量簡(jiǎn)潔,短 小,以免占用太多的時(shí)間哦。
{
加上你希望實(shí)現(xiàn)的功能。
}
在看懂上面這段代碼的基礎(chǔ)上大家在想想如果希望是低電平引發(fā)中斷,程序該怎么寫呢?
外部中斷INT1的初始化函數(shù)和中斷處理函數(shù)該怎么寫呢?
2、定時(shí)中斷
與定時(shí)器/計(jì)數(shù)器T0,定時(shí)器/計(jì)數(shù)器T1中斷相關(guān)的寄存器主要有TMOD,THX,TLX,TCON,IE。下面我們通過一段例程看看怎樣實(shí)現(xiàn)定時(shí)器/計(jì)數(shù)器的中斷功能(以定時(shí)器/計(jì)數(shù)器0為例)。
#include “reg51.h”
void timer0_init(void)//定時(shí)器0中斷初始化函數(shù)
{
TMOD=0x80; //將定時(shí)器/計(jì)數(shù)器0當(dāng)成13位定時(shí)器/計(jì)數(shù)器,TL0只用低5位參與分頻,TH0整個(gè)8位全用。
TH0=0xXX; //設(shè)定定時(shí)器0初始計(jì)數(shù)值的高8位
TL0=0xXX; //設(shè)定定時(shí)器0初始計(jì)數(shù)值的低8位
TR0=1; //定時(shí)器0開始計(jì)數(shù)
ET0=1; //開定時(shí)器0中斷允許
EA= 1; //開總中斷允許
}
void main(void)
{
timer0_init();
while(1);
}
void timer0int interrupt 1
{
TH0=0xXX; //在中斷處理函數(shù)里面記得給TH0重新賦初值哦
TL0=0xXX; //在中斷處理函數(shù)里面記得給TL0重新賦初值哦
加上你希望實(shí)現(xiàn)的功能哦。
}
這樣在單片機(jī)工作頻率固定的前提下,我們可以通過調(diào)節(jié)TH0和TL0的初值來改變定時(shí)0的定時(shí)時(shí)長,從而改變定時(shí)中斷發(fā)生的時(shí)間間隔。這樣就以我們希望的時(shí)間間隔執(zhí)行中斷處理函數(shù)中的指令。
定時(shí)器1的中斷的初始化和定時(shí)器0的中斷初始化類似。
需要指出的是定時(shí)器0和定時(shí)器1有4中不同的工作方式,不同的工作方式的選擇可以通過設(shè)置寄存器TMOD來實(shí)現(xiàn)。
3、串口收發(fā)中斷
#include
//FOSC = 11.0592MHz,12T模式,SMOD=0
#define reload_count_1200bps 0xe8
#define reload_count_2400bps 0xf4
#define reload_count_4800bps 0xfa
#define reload_count_9600bps 0xfd
void serial_port_initial(char TH,char TL)
{
SCON=SCON|0x50; //確定串口工作方式,8位可變波特率,無奇偶校驗(yàn)位
TMOD=TMOD|0x20; //設(shè)置定時(shí)器1為8位自動(dòng)重裝記數(shù)器
PCON=PCON|0x00; //這個(gè)寄存器里有一位SMOD,它和波特率的確定有關(guān)。
TH1 = TH; //設(shè)置定時(shí)器1自動(dòng)重裝數(shù)TH1,它和波特率的確定有關(guān)。
TL1 = TL; //設(shè)置定時(shí)器1自動(dòng)重裝數(shù)TL1,它和波特率的確定有關(guān)。
ES=1; //允許串口中斷
EA=1; //開總中斷
TR1=1; //開定時(shí)器1
}
波特率=(2SMOD/32)x(定時(shí)器1的溢出率) 定時(shí)器1的溢出率 = SYSclk/12(256-TH1)
char UARTReceive(void) //串口數(shù)據(jù)接收函數(shù)
{
char ch;
ch=SBUF;
return (ch); // 暫存接收到的數(shù)據(jù)
}
void main(void)
{
serial_port_initial(reload_count_2400bps,reload_count_2400bps);
//初始化串口參數(shù)
while(1);
}
void UART_Interrupr_Receive(void) interrupt 4 //串口接收中斷處理函數(shù)
{
ES = 0;
RI = 0; //當(dāng)串口接收到數(shù)據(jù)時(shí),RI回被置1,同時(shí)引發(fā)中斷,在中斷處理函數(shù)中將其清零。
buf = UARTReceive();
ES = 1;
}
好了,今天簡(jiǎn)單地和大家分享了一下單片機(jī)中斷的一些基本知識(shí),在這里只是簡(jiǎn)單地具了幾個(gè)例,中斷的用法很有技巧,這需要大家在項(xiàng)目的實(shí)踐中去掌握,吃透。
|