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

51單片機共有5個中斷源,分別是外部中斷0、外部中斷1、定時器中斷0、定時器中斷1和串口中斷,這5個中斷源有二個中斷優先級,每個中斷源可以編程為高優先級和低優先級中斷,可實現二級中斷服務程序嵌套。

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

各個控制位功能如下表

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

各個控制位功能如下表

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

各個控制位功能如下表

當系統復位后,IP各位均為0,所有中斷處于低優先級狀態,低優先級中斷可以被高優先級中斷打斷,反之則不行,一種中斷一旦得到相應,與他同級的中斷不能再中斷打斷,中斷優先級默認如下

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

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

二、示例程序
1.創建工程
將上一節工程復制出來,并修改名字為06-interrupt

2.修改程序
/*------------------------------------------------------
*店鋪網址:https://shop321633213.taobao.com/?spm=a1z10.3-c.0.0.33816af5iLgN2F
*適用于A08開發板
*實驗現象:驅動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; //液晶使能信號
sbit LCD_RS=P3^5; //數據/命令選擇端
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; //使能信號
LCD_EN=0; //關閉使能
}
void write_data(uchar date) //數據
{
LCD_RS=1; //選擇寫數據
P0=date;
delay_ms(5);
LCD_EN=1;
LCD_EN=0;
}
void init()
{
LCD_EN=0;
write_com(0x38); //00111000 設置16*2顯示,5*7點陣 8為數據接口
write_com(0x0c); //00001100 設置開顯示,不顯示光標
write_com(0x06); // 00000110 寫一個字符后地址指針加 1
write_com(0x01); //00000001 顯示清0,數據指針清零 /* */
}
void interrupt_init(void)
{
EA=1; // 打開總中斷
IT0=1; // 外部中斷0, P3.2引腳 下降沿觸發
EX0=1;
}
void main(void) //主函數
{
uchar i;
LCD_WR=0;
interrupt_init();
init();
// 寫第一行數據
write_com(0x80);
for(i=0;i<10;i++)
{
write_data(table_xiaoyi[i]);
delay_ms(5);
}
// 寫第二行數據
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);
}
// 寫第二行數據 程序中interrupt_init()函數初始化外部中斷0,中斷處理函數int0_func()中先關閉總中斷,防止被高優先級中斷打斷,然后賦值標志位,最后開啟總中斷
三、運行
將上述程序生成的hex文件燒錄到板子中,使用杜邦線將P32引腳接地,可以看到LCD1602第二行顯示INT0!,說明進入中斷成功。

注意:
不建議直接在中斷處理函數中處理數據,本文是中斷處理函數中設置interrupt_flag標志位,然后主程序中查詢標志位進行數據處理。
