CC2530基礎實驗二 外部中斷實驗
一、任務要求
使用SW1按鍵作為外部中斷輸入來控制流水燈效果的啟停,即實驗板通電後兩個發光二極體以下述方式工作:
①通電後LED1和LED2都熄滅。
②延時一段時間後LED1點亮。
③延時一段時間後LED2點亮,此時LED1和LED2都處在點亮狀態。
④延時一段時間後LED1熄滅。
⑤延時一段時間後LED2熄滅,此時LED1和LED2都處在熄滅狀態。
⑥返回步驟②迴圈執行。
⑦在任何時間,當按下一次SW1按鍵後,便暫停流水燈效果,即兩個LED燈保持SW1按鍵按下時的亮/滅狀態。直到再按下一次SW1按鍵後,流水燈效果從暫停狀態繼續執行。
二、什麼是中斷
“中斷”即打斷,是指CPU在執行當前程式時,由於系統中出現了某種急需處理的情況,CPU暫停正在執行的程式,轉而去執行另一段特殊程式來處理出現的緊急事務,處理結束後CPU自動返回到原先暫停的程式中去繼續執行。這種程式在執行過程中由於外界的原因而被中間打斷的情況稱為中斷。
中斷使得計算機系統具備應對突發事件能力,提高了CPU的工作效率。如果沒有中斷系統,CPU就只能按照程式編寫的先後次序,對各個外設進行依次查詢和處理,即輪詢工作方式。輪詢方式貌似公平,但實際工作效率卻很低,且不能及時響應緊急事件。
採用中斷技術後,可以為計算機系統帶來以下好處:
1)實現分時操作
速度較快的CPU和速度較慢的外設可以各做各的事情,外設可以在完成工作後再與CPU進行互動,而不需要CPU去等待外設完成工作,能夠有效提高CPU的工作效率。
2)實現實時處理
在控制過程中,CPU能夠根據當時情況及時做出反應,實現實時控制的要求。
3)實現異常處理
系統在執行過程中往往會出現一些異常情況,中斷系統能夠保證CPU及時知道出現的異常,以便CPU去解決這些異常,避免整個系統出現大的問題。
三、中斷的基本概念
1)主程式
在發生中斷前,CPU正常執行的處理程式。
2)中斷源
引起中斷的原因,或是發出中斷申請的來源。微控制器一般具有多箇中斷源,如外部中斷、定時/計數器中斷或ADC中斷等。
3)中斷請求
中斷源要求CPU提供服務的請求。例如ADC中斷在進行ADC轉換結束後,會向CPU提出中斷請求,要求CPU讀取A/D轉換結果。中斷源會使用某些特殊功能暫存器中的位來表示是否有中斷請求,這些特殊位叫做中斷標誌位,當有中斷請求出現時,對應標誌位會被置位。
4)斷點
CPU響應中斷後,主程式被打斷的位置。當CPU處理完中斷事件後,會返回到斷點位置繼續執行主程式。
5)中斷服務函式
CPU響應中斷後所執行的相應處理程式,例如ADC轉換完成中斷被響應後,CPU執行相應的中斷服務函式,該函式實現的功能一般是從ADC結果暫存器中取走並使用轉換好的資料。
6)中斷向量
中斷服務程式的入口地址,當CPU響應中斷請求時,會跳轉到該地址去執行程式碼。
(4)中斷巢狀和中斷優先順序
當有多箇中斷源向CPU提出中斷請求時,中斷系統採用中斷巢狀的方式來依次處理各個中斷源的中斷請求,如下圖所示
在中斷巢狀過程中,CPU通過中斷源的中斷優先順序來判斷優先為哪個中斷源服務。中斷優先順序高的中斷源可以打斷優先順序低的中斷源的處理過程,而同級別或低級別的中斷源請求不會打斷正在處理的中斷服務函式,要等到CPU處理完當前的中斷請求,才能繼續響應後續中斷請求。為便於靈活運用,微控制器各個中斷源的優先順序通常是可以通過程式設計設定的。
四、CC2530的中斷源
如圖:
(1)CC2530的中斷源
CC2530具有18箇中斷源,每個中斷源都由各自的一系列特殊功能暫存器來進行控制。18箇中斷源的描述如表3-1所示。
18箇中斷源可以根據需要來決定是否讓CPU對其進行響應,只需要程式設計設定相關特殊功能暫存器便可,在後續學習過程中我們會逐步接觸各個中斷源的使用方法。
(2)CC2530中斷源的優先順序
CC2530將18箇中斷源劃分成6箇中斷優先順序組IPG0~IPG5,每組包含3箇中斷源,如表所示。
6箇中斷優先順序組可以分別被設定成0~3級,即由使用者指定中斷優先順序,其中0級屬於最低優先順序,3級為最高優先順序。
同時,為保證中斷系統正常工作,CC2530的中斷系統還存在自然優先順序,即:
如果多個組被設定成相同級別,則組號小的要比組號大的優先順序高;
同一組中所包含的3箇中斷源,最左側的優先順序最高,最右側的優先順序最低。
要將6箇中斷優先順序組設定成不同優先級別,使用的是IP0和IP1兩個暫存器,兩個暫存器的定義如表3-3所示。要為優先順序組設定優先級別,可參照表3-4來分別配置IP0和IP1。
五、中斷初始化
中斷初始化
1、CUP中斷總開關
EA = 1;
2、對應的組開關
P0組的中斷開關在 IEN1 的第5位
P1組的中斷開關在 IEN2 的第4位 IEN2|=(3<<1);
P2組的中斷開關在 IEN2 的第1位
3、組內腳的開關
P0IEN、P1IEN、P2IEN 每個暫存器都有8位
4、選擇上升沿還是下降沿
中斷產生條件:
中斷函式(P1產生中斷)
#pragma vector = P1INT_VECTOR
__interrupt void P1()
{
/*****************
//程式碼
*****************/
}
P0/P1/P2口中斷向量
P0INT_VECTOR
P1INT_VECTOR
P2INT_VECTOR
T1定時器中斷向量
串列埠0/串列埠1 傳送中斷向量
UTX0_VECTOR
UTX1_VECTOR
串列埠0/串列埠1 接收中斷向量
URX0_VECTOR
中斷標誌位
PxIFG:每一組的中斷標誌位,P1IFG有8位分別對應P1口的8位。如P1_0產生中斷,
P1IFG = 0x01;
PxIF::CPU的中斷標誌位,有P0IF、 P1IF、 P2IF。如P1_0產生中斷,P1IF = 1;
P0IFG &= ~(1<<1) ; //0000 0010
P0IF=0;
P1中斷的相關暫存器
PICTL
0表示上升沿,1表示下降沿
IEN2、IEN1
PxIEN
六、程式碼
#include "ioCC2530.h" //引用CC2530標頭檔案
#define LED1 (P1_0) //LED1埠巨集定義
#define SW1 (P1_2) //SW1埠巨集定義
/**************************************************************
函式名稱:delay
功 能:軟體延時
入口引數:time--延時迴圈執行次數
出口引數:無
返 回 值:無
**************************************************************/
void delay(unsigned int time)
{
unsigned int i;
unsigned char j;
for(i = 0;i < time;i++)
for(j = 0;j < 240;j++)
{
asm("NOP");//asm用來在C程式碼中嵌入組合語言操作,匯
asm("NOP");//編命令nop是空操作,消耗1個指令週期。
asm("NOP");
}
}
/**************************************************************
函式名稱:main
功 能:程式主函式
入口引數:無
出口引數:無
返 回 值:無
**************************************************************/
void main(void)
{
P1SEL &= ~0x05; //設定P1_0口和P1_2為通用I/O口
P1DIR |= 0x01; //設定P1_0口為輸出口
P1DIR &= ~0x04; //設定P1_2口為輸入口
P1INP &= ~0x04; //設定P1_2口為上拉或下拉
P2INP &= ~0x40; //設定P1口所有引腳使用上拉
LED1 = 0; //熄滅LED1
while(1)//程式主迴圈
{
if(SW1 == 0) //如果按鍵被按下
{
delay(100); //為消抖進行延時
if(SW1 == 0) //經過延時後按鍵仍舊處在按下狀態
{
LED1 = ~LED1; //反轉LED1的亮滅狀態
while(!SW1); //等待按鍵鬆開
}
}
}
}