學習目標:掌握中斷使能寄存器IEN0、IEN1、IEN2,中斷標志寄存器PxIFG、IRCON、
IRCON2,端口中斷觸發沿控制寄存器
PICTL
CC2541有18個中斷源,每個中斷源都可以產生中斷請求,這18個中斷源如下
中斷請求通過SFR寄存器IEN0、IEN1、IEN2使能或禁止,定義如下:
其中IEN0和IEN1可以位尋址,寄存器IEN2不可以位尋址
EA:1開總中斷
IEN1.P0IE:P0端口中斷使能
IEN2.P1IE:P1端口中斷使能
IEN2.P2IE:P2端口中斷使能
IEN1寄存器的第5位控制P0口的中斷,當設置IEN1.P0IE時,將設置P0端口所有引腳的中斷使能
IEN2寄存器的第4位和第1位分別控制P1端口和P2端口,控制P1和P2端口的所有引腳中斷使能
如果要對P0、P1、P2端口具體某一個引腳設置使能,則需要設置寄存器P0IEN、P1IEN、P2IEN,其定義如下:
0xAB、0x8D、0xAC 不可位尋址
| 端口 | Bit位 | 名稱 | 初始化 | 讀寫 | 描述 |
| P0IEN | 7:0 | P0_[7:0]IEN | 0x00 | R/W | 端口0,位7至位0中斷使能。0:中斷禁止;1:中斷使能 |
| P1IEN | 7:0 | P1_[7:0]IEN | 0x00 | R/W | 端口1,位7至位0中斷使能。0:中斷禁止;1:中斷使能 |
| P2IEN | 7:6 | --- | 00 | R0 | 未使用 |
| P2IEN | 5 | DPIEN | 0 | R/W | USB D+ 中斷使能。 |
| P2IEN | 4:0 | P2_[4:0]IEN | 00000 | R/W | 端口2,位4至位0中斷使能。0:中斷禁止;1:中斷使能 |
所以通用I/O口中斷使能有三層:總中斷使能、端口中斷使能、引腳中斷使能
I/O中斷除了配置中斷使能之外,還需要配置中斷觸發方式,中斷觸發方式可由端口中斷控制寄存器PICTL設置,I/O中斷觸發方式分為輸入的上升沿觸發和下降沿觸發,PICTL寄存器定義如下:
0x8c 不可位尋址
| 端口 | Bit位 | 名稱 | 初始化 | 讀寫 | 描述 |
| PICTL | 7 | PADSC | 0 | R/W | 強制引腳在輸出模式。選擇輸出驅動能力,由DVDD引腳提供。0:最小驅動能力;1:最大驅動能力 |
| PICTL | 6:4 | --- | 000 | R0 | 未使用 |
| PICTL | 3 | P2ICON | 0 | R/W | 端口2,引腳4至0輸入模式下的中斷配置,0:輸入的上升沿引起中斷;1:輸入的下降沿引起中斷 |
| PICTL | 2 | P1ICONH | 0 | R/W | 端口1,引腳7至4輸入模式下的中斷配置,0:輸入的上升沿引起中斷;1:輸入的下降沿引起中斷 |
| PICTL | 1 | P1ICONL | 0 | R/W | 端口1,引腳3至0輸入模式下的中斷配置,0:輸入的上升沿引起中斷;1:輸入的下降沿引起中斷 |
| PICTL | 0 | P0ICON | 0 | R/W | 端口0,引腳7至0輸入模式下的中斷配置,0:輸入的上升沿引起中斷;1:輸入的下降沿引起中斷 |
與中斷使能有三層類似,中斷標志也有兩層,分別為端口中斷標志和引腳中斷標志
端口中斷標志位在寄存器IRCON和IRCON1中,分別為P0IF、P1IF、P2IF,都可以位尋址
由於CC2541的外部中斷共用一個中斷向量,因此需要判斷是哪個引腳發生中斷,通過判斷中斷狀態標志寄存器(
P0IFG,P1IFG,P2IFG)可以判斷是哪一個引腳發生中斷,寄存器定義如下:
0x89、0x8A、0x8B 不可位尋址
| 端口 | Bit位 | 名稱 | 初始化 | 讀/寫 | 描述 |
| P0IFG | 7:0 | P0IF[7:0] | 0x00 | R/W0 | 端口0,位7至位0輸入中斷狀態標志。0:未發生中斷,1:發生中斷 |
| P1IFG | 7:0 | P1IF[7:0] | 0x00 | R/W0 | 端口1,位7至位0輸入中斷狀態標志。0:未發生中斷,1:發生中斷 |
| P2IFG | 7:5 | --- | 000 | R0 | 未使用 |
| P2IFG | 4:0 | P2IF[4:0] | 0x00 | R/W0 | 端口2,位4至位0輸入中斷狀態標志。0:未發生中斷,1:發生中斷 |
通用I/O口中斷配置過程:
- 設置需要發生中斷的I/O口為通用I/O口,配置寄存器PxSEL
- 設置I/O口為輸入方式,配置寄存器PxDIR
- 清除中斷標志,對應的寄存器PxIFG狀態標志位置0
- 設置I/O口的中斷觸發方式
- 開端口中斷,設置對應引腳的端口的中斷使能位為1,設置寄存器IEN0或IEN1
- 開總中斷,設置IEN0中的EA為1
1 /****************************************************************************** 2 *函 數 名:InitKey 3 *功 能:按鍵中斷初始化 4 *入口參數:無 5 *出口參數:無 6 ******************************************************************************/ 7 void InitKey(void) 8 { 9 P0SEL &= ~0x02; //P0.1設置為通用I/O口 10 P0DIR &= ~0x02; //P0.1設置為輸入 11 P0IFG &= ~0x02; //P0.1中斷狀態標志位清0 12 PICTL |= 0x02; //P0端口下降沿觸發 13 P0IEN |= 0x02; //P0.1中斷使能 14 IEN1 |= 0x20; //端口P0中斷使能 15 EA = 1; //開總中斷 16 }
- 判斷引腳中斷是否發生(如果該端口只有一個引腳中斷,可以不判斷)
- 完成具體中斷工作
- 清引腳中斷標志,PxIFG對應引腳位清0(必須軟件清0,不清0的話中斷服務程序反復執行)
- 清端口中斷標志,P0IF/P1IF/P2IF位清0(實驗驗證端口中斷標志不清0也可以,但是該位不會自動清0,需要軟件清0,為了保險,統一為清0)
1 /****************************************************************************** 2 *函 數 名:P0_ISR 3 *功 能:中斷服務子程序 4 *入口參數:無 5 *出口參數:無 6 ******************************************************************************/ 7 #pragma vector = P0INT_VECTOR 8 __interrupt void P0_ISR(void) 9 { 10 if(0x02 & P0IFG) //判斷按鍵中斷 11 { 12 //具體功能代碼 13 } 14 P0IFG = 0; //清中斷標志 15 P0IF = 0; //清中斷標志,IRCON[5],P0口中斷 16 }
示例程序:按鍵控制LED燈
1 /****************************************************************************** 2 *文 件 名:KEY.c 3 *作 者:陳照 4 *時 間:2015-04-23 5 *版 本:1.0 6 *描 述:按鍵中斷方式控制流水燈 7 ******************************************************************************/ 8 #include <iocc2541.h> 9 #include "delay.h" 10 11 typedef unsigned char uchar; 12 typedef unsigned int uint; 13 14 #define LED1 P1_0 15 #define LED2 P1_1 16 #define LED3 P1_4 17 #define KEY P0_1 18 19 /****************************************************************************** 20 *函 數 名:InitLED 21 *功 能:LED燈初始化 22 *入口參數:mode,mode為1則點亮所有LED,mode為0則熄滅所有LED 23 *出口參數:無 24 ******************************************************************************/ 25 void InitLED(uchar mode) 26 { 27 P1SEL &= ~0x13; //P1.0,P1.1,P1.4設置為通用I/O口 28 P1DIR |= 0x13; //P1.0,P1.1,P1.4設置為輸出 29 LED1 = mode; //LED燈亮熄控制 30 LED2 = mode; 31 LED3 = mode; 32 } 33 34 /****************************************************************************** 35 *函 數 名:InitKey 36 *功 能:按鍵中斷初始化 37 *入口參數:無 38 *出口參數:無 39 ******************************************************************************/ 40 void InitKey(void) 41 { 42 P0SEL &= ~0x02; //P0.1設置為通用I/O口 43 P0DIR &= ~0x02; //P0.1設置為輸入 44 P0IFG &= ~0x02; //P0.1中斷狀態標志位清0 45 PICTL |= 0x02; //P0端口下降沿觸發 46 P0IEN |= 0x02; //P0.1中斷使能 47 IEN1 |= 0x20; //端口P0中斷使能 48 EA = 1; //開總中斷 49 } 50 51 /****************************************************************************** 52 *函 數 名:P0_ISR 53 *功 能:中斷服務子程序 54 *入口參數:無 55 *出口參數:無 56 ******************************************************************************/ 57 #pragma vector = P0INT_VECTOR 58 __interrupt void P0_ISR(void) 59 { 60 if(0x02 & P0IFG) //判斷按鍵中斷 61 { 62 LED1 = !LED1; //流水燈 63 Delay1ms(1000); //延時1s 64 LED2 = !LED2; 65 Delay1ms(1000); 66 LED3 = !LED3; 67 Delay1ms(1000); 68 } 69 P0IFG = 0; //清中斷標志 70 P0IF = 0; //清中斷標志,IRCON[5],P0口中斷 71 } 72 73 /****************************************************************************** 74 *程序入口函數 75 ******************************************************************************/ 76 int main(void) 77 { 78 InitLED(0); //LED初始化,熄滅LED1~3 79 InitKey(); //按鍵中斷初始化 80 81 while(1) 82 { 83 } 84 }






