ZigBee按鍵中斷


何為按鍵中斷?

在了解按鍵中斷之前,我們先來了解一下什么是中斷?中斷就是程序執行當前代碼,當前任務的時候;

突然有自身函數或外部的影響,而使程序執行到別的任務再回來。

舉個栗子:

當你在做飯的時候,電話突然響了,這時候你只能停下當前做飯的動作,去執行聽電話的動作

(同理,當你的程序要打印一句很長很長的話,突然有個中斷出來,你要去執行那個中斷,那個中斷

可能是算一個數,也可能是讓你程序復位程序執行)

 

中斷優先級別

而說起中斷,我們的中斷也有個先后順序中斷,是中斷去算數還是去中斷復位呢?這就需要看你

程序的定義了,默認情況下,你是先把數算出來,再把程序復位才合理的,要是你把程序復位了,再

去算數,也進不去算了。不過話說回來,你最后復位了程序,算出來的結果,一樣回不去顯示出來,

畢竟被自己復位清會原始值了。但是做飯期間來電話,中間必定要做的事情還是要有的,因為你不知

道你的這個電話要聊多久,所以你會先把爐子給關了,然后才去接電話的,要不你的這頓飯就吃不下

了。

 

下面來看個例子怎么設置中斷的優先級吧

 

首先,我們說一下規則

為了保證中斷系統正常工作,CC2530的中斷系統還存在自然優先級,即:

(1)如果多個組被設置成相同級別,則組號的要比組號的優先級

(2)同一組中所包含的3個中斷源,最側的優先級最,最側的優先級最

而將6個中斷優先級組設置成不同優先級別,使用的是IP0IP1兩個寄存器,兩個寄存器的定義見表2-7,。

要為優先級組設置優先級別,可參照表2-6來分別配置IP0IP1

 

例如,要設置的中斷源優先級為P0INT>P1INT>P2INT,則可以使用以下代碼實現

IP1=0x30;  //IPG5級別為3,IPG4級別為2,IPG1級別為1,其他

IP0=0x22;  //組級別為0。

 

看了上面的例子,可能一大部分人還是很懵,沒事,我一開始也一樣懵。

首先我們來把上面例子的IP1和IP0兩個寄存器拆開來看

IP1  0011  0000

IP0  0010  0010

可能拆開來,我們還是不知道什么意思,但是我們看看IP1和IP0的第5位上,合起來后變成11,再回到表2-6

11便是級別3-highest(最高級別),同理,我們的第4位和第1位,便設置成了級別2和級別1。

而我們為什么不在其他位設置11(級別3),10(級別2)和01(級別1)呢?原因很簡單,我們再看回到表2-7

P0INT在IPG5組上

P1INT在IPG4組上

P2INT在IPG1組上

而剩下的因為不需要分配優先級,便默認成為組級別0。

 

按鍵中斷

說了半天,中斷優先級別在我們今天這個文章里面暫時用不到,但是既然說到中斷,我們也要先了解着,因為

CC2530單片機程序上,運用到中斷的除了按鍵(外部)中斷外,還有定時器中斷和串口中斷,后面遲早會用

到的。而同上個教程一樣,我們要用中斷,同樣要用到寄存器。而相關寄存器看下面相關資料,也可百度自行

擴展。

 

先關寄存器

 

IEN0:中斷使能0,0為中斷禁止,1為中斷使能

 

D7

D6

D5

D4

D3

D2

D1

D0

總中斷EA

未用

睡眠定時器中斷

AES加密/解密中斷

USART1 RX中斷

USART0 RX中斷

ADC中斷

RF TX/RF FIFO中斷

 

  

 

IEN1:中斷使能1,0為中斷禁止,1為中斷使能

 

D7

D6

D5

D4

D3

D2

D1

D0

未用

未用

端口0

定時器4

定時器3

定時器2

定時器1

DMA傳輸

 

 

 

P0IFGP1IFG相同):中斷狀態標志寄存器,當輸入端口有中斷請求時,相應的標志位將置1

 

D7

D6

D5

D4

D3

D2

D1

D0

P0_7

P0_6

P0_5

P0_4

P0_3

P0_2

P0_1

P0_0

 

 

 

P2INP D0~D4控制P2_0~P2_4的輸入模式,0為上拉/下拉,1為三態;

 

                 D5~D7設置對P0P1P2的上拉或下拉的選擇。0為上拉,1為下拉;

 

D7

D6

D5

D4

D3

D2

D1

D0

端口2選擇

端口1選擇

端口0選擇

P2_4模式

P2_3模式

P2_2模式

P2_1模式

P2_0模式

 

  

 

P2IFGD0~D4P2_0~P2_4的中斷標志位

 

       D5USB D+中斷狀態標志,當D+線有一個中斷請求未決時設置該標志,用於檢測USB掛起狀態下的USB恢復事件。當USB控制器沒有掛起時不設置該標志。

 

 

 

D7

D6

D5

D4

D3

D2

D1

D0

未用

未用

USB D+

P2_4

P2_3

P2_2

P2_1

P2_0

 

 

 

P2IEND0~D4控制P2_0~P2_4的中斷使能

 

                D5控制USB D+的中斷使能

 

D7

D6

D5

D4

D3

D2

D1

D0

未用

未用

USB D+

P2_4

P2_3

P2_2

P2_1

P2_0

 

  

 

IEN2:中斷使能2,0為中斷禁止,1為中斷使能

 

D7

D6

D5

D4

D3

D2

D1

D0

未用

未用

看門狗定時器

端口1

USART1 TX

USART0 TX

端口2

RF一般中斷

 

PICTLD0~D3設置各個端口的中斷觸發方式,0為上升沿觸發,1為下降沿觸發。

           D7控制I/O引腳在輸出模式下的驅動能力。選擇輸出驅動能力增強來補償引腳DVDD的低I/O電壓,

確保在較低的電壓下的驅動能力和較高電壓下相同。0為最小驅動能力增強。1為最大驅動能力增強。

 

D7

D6

D5

D4

D3

D2

D1

D0

I/O驅動能力

未用

未用

未用

P2_0~P2_4

P1_4~P1_7

P1_0~P1_3

P0_0~P0_7

 

 

程序

 

下面來兩個程序實例,看看效果吧

 

 1 //*********************************************
 2 /*利用中斷控制方式,使用SW1按鍵控制LED1的亮/滅狀態,具體要求如下:
 3 /*①系統上電后LED1熄滅
 4 /*②每次按下一次SW1按鍵並松開時,LED1切換自身的亮/滅狀態。
 5 /*
 6 /*
 7 /*
 8 //********************************************/
 9 
10 #include"ioCC2530.h"
11 #define D4 P1_1//LED1
12 
13 typedef unsigned char uint8;
14 typedef unsigned int uint16;
15 
16 uint8 flag = 0;//定義LED1的亮滅狀態標志
17 
18 void port()//初始化LED燈
19 {
20   P1DIR = 0x1b;//設置為輸出
21   P1 &=~ 0x1b;//關閉LED燈
22 }
23 
24 void inter()//初始化中斷
25 {
26   IEN2 = 0x10;//端口1中斷使能
27   P1IEN = 0x04;//P1_2中斷使能
28   PICTL = 0x02;//P1_3~P1_0下降沿觸發中斷
29   EA = 1;//開啟總中斷
30 }
31 
32 main()
33 {
34   port();
35   inter();
36   while(1)
37   {
38     if(flag==0)
39     {
40       D4=0;
41     }
42     if(flag==1)
43     {
44       D4=1;
45     }
46   }
47 }
48 
49 #pragma vector = P1INT_VECTOR
50 __interrupt void P1_INT ()
51 {
52   if(P1IFG & 0x04)//如果P1_2端口中斷標志位置位
53   {
54     flag = !flag;//每進入一次中斷,改變一次中斷
55     P1IFG &=~ 0x04;//清除P1_2端口中斷標志位
56   }  
57   P1IF = 0;//清除P1端口中斷標志位
58 }

 

 

 1 //*********************************************
 2 /*使用中斷方式,用SW1按鍵控制LED1和LED2的顯示效果,具體要求如下:
 3 /*①系統上電后LED1和LED2全部熄滅
 4 /*②第一次按下SW1按鍵后,LED1點亮
 5 /*③第二次按下SW1按鍵后,LED2點亮
 6 /*④第三次按下SW1按鍵后,LED2熄滅
 7 /*⑤第四次按下SW1按鍵后,LED1熄滅
 8 /*⑥四次按鍵過后,從要求②開始進入新的控制周期
 9 /*
10 //********************************************/
11 
12 
13 
14 #include"ioCC2530.h"
15 #define D3 P1_0//LED2
16 #define D4 P1_1//LED1
17 
18 typedef unsigned char uint8;
19 typedef unsigned int uint16;
20 
21 uint8 flag=0;//每次按鍵按下,改變LED狀態的標志
22 
23 void port()//初始化LED
24 {
25   P1DIR = 0x1b;//LED設置為輸出
26   P1 &=~ 0x1b;//LED熄滅
27 }
28 
29 void inter()//按鍵中斷初始化
30 {
31   IEN2 = 0x10;//P1端口中斷使能
32   P1IEN = 0x04;//P1_2中斷使能
33   PICTL = 0x02;//P1_3~P1_0設置下降沿觸發中斷
34   EA = 1;//開啟總中斷
35 }
36 
37 main()
38 {
39   port();
40   inter();
41   while(1)
42   {
43     if(flag==1)
44     {
45       D4=1;
46       D3=0;
47     }
48     else if(flag==2)
49     {
50       D4=1;
51       D3=1;
52     }
53     else if(flag==3)
54     {
55       D4=1;
56       D3=0;
57     }
58     else if(flag==4)
59     {
60       D4=0;
61       D3=0;
62     }
63   }
64 }
65 
66 
67 #pragma vector = P1INT_VECTOR
68 __interrupt void P1_INT()
69 {
70   if(P1IFG & 0x04)//如果P1_2端口中斷標志位置位
71   {
72     flag++;
73     if(flag==5)
74     {
75       flag=1;
76     }
77     P1IFG &=~ 0x04;//清除P1_2端口中斷標志位
78   }
79   P1IF = 0;//清除P1端口中斷標志位
80 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM