前言
本節(jié)我們開始,我們學(xué)習(xí)51單片機(jī)的中斷系統(tǒng),51單片機(jī)有5個(gè)中斷源,我們首先學(xué)習(xí)外部中斷,并通過中斷方式檢測P3^2接口是否有低電平產(chǎn)生。
一、基礎(chǔ)知識(shí)
1.中斷簡介
中斷是指CPU在執(zhí)行A事件的時(shí)候,突然收到B事件發(fā)出的(中斷)請求,CPU停止手中的事情,轉(zhuǎn)而去執(zhí)行B事件,B事件執(zhí)行完畢后,又回到原來A事件被打斷的地方,繼續(xù)執(zhí)行程序的過程,示意圖如下所示:

51單片機(jī)共有5個(gè)中斷源,分別是外部中斷0、外部中斷1、定時(shí)器中斷0、定時(shí)器中斷1和串口中斷,這5個(gè)中斷源有二個(gè)中斷優(yōu)先級(jí),每個(gè)中斷源可以編程為高優(yōu)先級(jí)和低優(yōu)先級(jí)中斷,可實(shí)現(xiàn)二級(jí)中斷服務(wù)程序嵌套。

2.中斷寄存器
(1) 中斷允許寄存器TCON(88H)
TCON為定時(shí)器/計(jì)數(shù)器T0、T1的控制器,同時(shí)也鎖存了T0、T1的溢出中斷源和外部中斷源

各個(gè)控制位功能如下表

(2) 中斷允許寄存器IE(A8H)
寄存器IE為特殊功能寄存器,控制CPU對(duì)中斷源的開放或者屏蔽,以及每個(gè)中斷源是否允許中斷

各個(gè)控制位功能如下表

(3) 中斷優(yōu)先級(jí)寄存器IP(B8H)
特殊功能寄存器IP為中斷優(yōu)先級(jí)寄存器,保存各種中斷源優(yōu)先級(jí)控制位,用戶可以通過軟件控制

各個(gè)控制位功能如下表

當(dāng)系統(tǒng)復(fù)位后,IP各位均為0,所有中斷處于低優(yōu)先級(jí)狀態(tài),低優(yōu)先級(jí)中斷可以被高優(yōu)先級(jí)中斷打斷,反之則不行,一種中斷一旦得到相應(yīng),與他同級(jí)的中斷不能再中斷打斷,中斷優(yōu)先級(jí)默認(rèn)如下

3.中斷處理流程
系統(tǒng)啟動(dòng)后需要使用軟件設(shè)置中斷類型以及中斷觸發(fā)方式,并打開中斷
void interrupt_init(void)
{
EA=1; // 打開總中斷
IT0=1; // 外部中斷0, P3.2引腳 下降沿觸發(fā)
EX0=1
}
當(dāng)中斷源發(fā)出中斷請求時(shí)候,CPU停止手頭的工作,進(jìn)入中斷服務(wù)程序運(yùn)行,中斷服務(wù)程序按照如下流程處理

中斷處理過程主要包括三個(gè)階段,分別是:中斷響應(yīng)、中斷處理、中斷返回
4.硬件連接
硬件連接如下所示,通過杜邦線連接P32和GND,控制杜邦線插拔和GND連接一端,控制P32中斷源輸入的電平

二、示例程序
1.創(chuàng)建工程
將上一節(jié)工程復(fù)制出來,并修改名字為06-interrupt

2.修改程序
/*------------------------------------------------------
*店鋪網(wǎng)址:https://shop321633213.taobao.com/?spm=a1z10.3-c.0.0.33816af5iLgN2F
*適用于A08開發(fā)板
*實(shí)驗(yàn)現(xiàn)象:驅(qū)動(dòng)LCD1602
*QQ群:906015840
-------------------------------------------------------*/
#include<reg51.h> //頭文件
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table_xiaoyi[]="XIAOYI IOT"; //
uchar code table_xiaoyi_welcome[]="Welcome!";
uchar code table_xiaoyi_interrupt[]="INT0!";
sbit LCD_EN=P3^7; //液晶使能信號(hào)
sbit LCD_RS=P3^5; //數(shù)據(jù)/命令選擇端
sbit LCD_WR=P3^6;
int interrupt_flag = 0;
void delay_ms(uint ms)
{
uint x,y;
for(x=ms;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com) //命令
{
LCD_RS=0; //選擇寫命令
P0=com;
delay_ms(5);
LCD_EN=1; //使能信號(hào)
LCD_EN=0; //關(guān)閉使能
}
void write_data(uchar date) //數(shù)據(jù)
{
LCD_RS=1; //選擇寫數(shù)據(jù)
P0=date;
delay_ms(5);
LCD_EN=1;
LCD_EN=0;
}
void init()
{
LCD_EN=0;
write_com(0x38); //00111000 設(shè)置16*2顯示,5*7點(diǎn)陣 8為數(shù)據(jù)接口
write_com(0x0c); //00001100 設(shè)置開顯示,不顯示光標(biāo)
write_com(0x06); // 00000110 寫一個(gè)字符后地址指針加 1
write_com(0x01); //00000001 顯示清0,數(shù)據(jù)指針清零 /* */
}
void interrupt_init(void)
{
EA=1; // 打開總中斷
IT0=1; // 外部中斷0, P3.2引腳 下降沿觸發(fā)
EX0=1;
}
void main(void) //主函數(shù)
{
uchar i;
LCD_WR=0;
interrupt_init();
init();
// 寫第一行數(shù)據(jù)
write_com(0x80);
for(i=0;i<10;i++)
{
write_data(table_xiaoyi[i]);
delay_ms(5);
}
// 寫第二行數(shù)據(jù)
write_com(0x80+0x40);
for(i=0;i<8;i++)
{
write_data(table_xiaoyi_welcome[i]);
delay_ms(5);
}
while(1)
{
if (interrupt_flag == 1)
{
// 第二行顯示清空
write_com(0x80+0x40);
for(i=0;i<8;i++)
{
write_data(0x20);
delay_ms(5);
}
// 寫第二行數(shù)據(jù) 程序中interrupt_init()函數(shù)初始化外部中斷0,中斷處理函數(shù)int0_func()中先關(guān)閉總中斷,防止被高優(yōu)先級(jí)中斷打斷,然后賦值標(biāo)志位,最后開啟總中斷
三、運(yùn)行
將上述程序生成的hex文件燒錄到板子中,使用杜邦線將P32引腳接地,可以看到LCD1602第二行顯示INT0!,說明進(jìn)入中斷成功。

注意:
不建議直接在中斷處理函數(shù)中處理數(shù)據(jù),本文是中斷處理函數(shù)中設(shè)置interrupt_flag標(biāo)志位,然后主程序中查詢標(biāo)志位進(jìn)行數(shù)據(jù)處理。
