圖1外部中斷及矩陣鍵盤中斷信號示意圖
外部中斷是單片機實時地處理外部事件的一種內部機制。當外部事件發生時,單片機的中斷系統將迫使CPU暫停正在執行的程序,轉而去進行中斷事件的處理,中斷完畢后返回被中斷的程序處,繼續執行下去。
中斷過程:
1.中斷當前程序并保護斷點
2.轉入中斷服務入口
3.保護現場
4.執行中斷服務程序
5.恢復現場
6.中斷返回
中斷的好處:
1、 提高了CPU的效率
CPU 是計算機的指揮中心,它與外圍設備(如按鍵、顯示器等)通訊的方法有查詢和中斷 2 種。
查詢的方法是無論外圍IO 是否需要服務,CPU 每隔一段時間都要依次查詢一遍,這種方法 CPU 需要花費一些時間在做查詢服務工作。
而中斷則是在外圍設備需要通訊服務時主動告訴 CPU, CPU 停下當前工作去處理中斷程序, 從而提高了CPU 效率。
2、 可以實現實時處理
外設任何時刻都可能發出請求中斷信號,CPU 接到請求后及時處理,以滿足實時系統的需要。
3、 可以及時處理故障
計算機系統運行過程中難免會出現故障,有許多事情是無法預料的,如電源掉電、存儲器出錯、外圍設備工作不正常等,這時可以通過中斷系統向中斷源 CPU 發送中斷請求,由 CPU 及時轉到相應的出錯處理程序,從而提高計算機的可靠性。
圖2中斷名稱
IE 中斷允許控制寄存器
圖3IE中斷允許控制寄存器
EA:EA = 0 時,所有中斷禁止(即不產生中斷)。
EA = 1 時,各中斷的產生由個別的允許位決定。
EX1:外部中斷INT1中斷允許。
EX0:外部中斷INT0中斷允許。
中斷程序格式:
圖4外部中斷程序格式
矩陣鍵盤中斷掃描程序:
#include< reg52.h > //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義#define KeyPort P0
sbit dula=P2^1;
sbit wela=P2^0;
unsigned char code DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};// 顯示段碼值0~F
unsigned char num;
void DelayUs2x(unsigned char t);//us級延時函數聲明
void DelayMs(unsigned char t); //ms級延時
unsigned char KeyScan(void);//鍵盤掃描
unsigned char KeyPro(void);
void display(unsigned char aa);
/*------------------------------------------------
主函數
------------------------------------------------*/
void main (void)
{
dula=1;
P1=0xff;
dula=0;
wela=1;
P1=0x00;
wela=0;
EA=1; //全局中斷開
EX0=1; //外部中斷0開
IT0=1; //邊沿觸發
while (1) //主循環
{
display(num);
KeyPort=0xf0;// 賦值用于中斷檢測
}
}
void display(unsigned char aa)
{
dula=1;
P1=DuanMa[aa];
dula=0;
}
/*------------------------------------------------
uS延時函數,含有輸入參數 unsigned char t,無返回值
unsigned char 是定義無符號字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時請使用匯編,大致延時
長度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延時函數,含有輸入參數 unsigned char t,無返回值
unsigned char 是定義無符號字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時請使用匯編
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延時1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
按鍵掃描函數,返回掃描鍵值
------------------------------------------------*/
unsigned char KeyScan(void) //鍵盤掃描函數,使用行列逐級掃描法
{
unsigned char Val;
KeyPort=0xf0;//高四位置高,低四位拉低
if(KeyPort!=0xf0)//表示有按鍵按下
{
DelayMs(10); //去抖
if(KeyPort!=0xf0)
{ //表示有按鍵按下
KeyPort=0xfe; //檢測第一行
if(KeyPort!=0xfe)
{
Val=KeyPort&0xf0;
Val+=0x0e;
while(KeyPort!=0xfe);
DelayMs(10); //去抖
while(KeyPort!=0xfe);
return Val;
}
KeyPort=0xfd; //檢測第二行
if(KeyPort!=0xfd)
{
Val=KeyPort&0xf0;
Val+=0x0d;
while(KeyPort!=0xfd);
DelayMs(10); //去抖
while(KeyPort!=0xfd);
return Val;
}
KeyPort=0xfb; //檢測第三行
if(KeyPort!=0xfb)
{
Val=KeyPort&0xf0;
Val+=0x0b;
while(KeyPort!=0xfb);
DelayMs(10); //去抖
while(KeyPort!=0xfb);
return Val;
}
KeyPort=0xf7; //檢測第四行
if(KeyPort!=0xf7)
{
Val=KeyPort&0xf0;
Val+=0x07;
while(KeyPort!=0xf7);
DelayMs(10); //去抖
while(KeyPort!=0xf7);
return Val;
}
}
}
return 0xff;
}
/*------------------------------------------------
按鍵值處理函數,返回掃鍵值
------------------------------------------------*/
unsigned char KeyPro(void)
{
switch(KeyScan())
{
case 0x7e:return 0;break;//0 按下相應的鍵顯示相對應的碼值
case 0x7d:return 1;break;//1
case 0x7b:return 2;break;//2
case 0x77:return 3;break;//3
case 0xbe:return 4;break;//4
case 0xbd:return 5;break;//5
case 0xbb:return 6;break;//6
case 0xb7:return 7;break;//7
case 0xde:return 8;break;//8
case 0xdd:return 9;break;//9
case 0xdb:return 10;break;//a
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
/*------------------------------------------------
外部中斷0程序
------------------------------------------------*/
void ISR_INT0(void) interrupt 0
{
num=KeyPro();
IE0=0;
}
接線方式:
杜邦線連接(用杜邦線連接<單片機 IO>和<模塊接口>)
表6.1接線
-
單片機
+關注
關注
6035文章
44554瀏覽量
634635 -
cpu
+關注
關注
68文章
10854瀏覽量
211578 -
中斷
+關注
關注
5文章
898瀏覽量
41470 -
矩陣鍵盤
+關注
關注
7文章
206瀏覽量
31454 -
外部中斷
+關注
關注
1文章
131瀏覽量
15816
發布評論請先 登錄
相關推薦
評論