[ZigBee] 4、ZigBee基礎實驗——中斷


 

 

前言

  上一篇介紹了CC2530的IO的基礎知識,並用LED的控制來展示如何配置並控制GPIO的輸出,用KEY狀態的讀取實驗來展示如何讀取GPIO的狀態。從上一節的KEY狀態讀取的代碼看出是采用輪訓方式的,這種方式是很浪費資源,本節將介紹一種中斷方式來替換輪訓的方案。

 

一、中斷

  電路依然沒變,若要使用CC2530的外部中斷需要使用P0IEN、PICTL、P0IFG、INE1寄存器。

 

按鍵中斷初始設置為:

 1 /****************************************************************************
 2 * 名    稱: InitKey()
 3 * 功    能: 設置KEY相應的IO口,采用中斷方式 
 4 * 入口參數: 無
 5 * 出口參數: 無
 6 ****************************************************************************/
 7 void InitKey()
 8 {
 9     P0IEN |= 0x2;    // P0.1 設置為中斷方式 1:中斷使能
10     PICTL |= 0x1;    //下降沿觸發   
11     IEN1 |= 0x20;    //允許P0口中斷; 
12     P0IFG = 0x00;    //初始化中斷標志位
13     EA = 1;          //打開總中斷
14 }

  通用I/O 引腳設置為輸入后,可以用於產生中斷。中斷可以設置在外部信號的上升或下降沿觸發。P0、P1或P2 端口都有中斷使能位,對位於IENl(端口中斷使能寄存器)寄存器內的端口所有的位都是公共的,如下:所以代碼中第11行允許P0口中斷為IEN1 |= 0x20;(第5位)

􀁺 IENI.P0 IE:P0 中斷使能
􀁺 IEN2.PI IE:P1 中斷使能
􀁺 IEN2.P2IE:P2 中斷使能

 

  除了這些公共中斷使能之外,每個端口的位都有位於SFR 寄存器P0IEN、P1IEN 和P2IEN(單獨引腳中斷使能寄存器)的單獨的中斷使能。即使配置為外設I/O 或通用輸出的I/O 引腳使能時都有中斷產生。因此代碼第9行將P0IEN設置為P0IEN|=0x2;即為使能P01引腳的中斷。

 

  使能中斷時候,還需要配置中斷方式,這里需要用到PICTRL寄存器(配置中斷方式)代碼第10行 PICTL |= 0x1;即為將端口0的8個引腳中斷模式設置為下降沿觸發。

  

  當中斷條件發生在I/O 引腳之一上面,P0-P2 中斷標志寄存器P0IFG、P1IFG 或P2IFG(中斷標志寄存器)中相應的中斷狀態標志將設置為1。不管引腳是否設置了它的中斷使能位,中斷狀態標志都被設置。當中斷已經執行,中斷狀態標志被清除,該標志寫入0。因此代碼中第12行P0IFG = 0x00; 是初始化中斷標志位為0:、

  這個標志必須在清除CPU 端口中斷標志(PxIF)之前被清除。用於中斷的SFR 寄存器描述在下一節。寄存器總結如下:

􀁺 P0IEN: P0 中斷使能
􀁺 P1IEN: P1 中斷使能
􀁺 P2IEN: P2 中斷使能
􀁺 PICTL: P0、P1 和P2 觸發沿設置
􀁺 P0FG: P0 中斷標志
􀁺 P1IFG: P1 中斷標志
􀁺 P2IFG: P2 中斷標志

 

   類似51單片機,中斷發生時會觸發相應的回調函數:

 1 /****************************************************************************
 2 * 名    稱: P0_ISR(void) 中斷處理函數 
 3 * 描    述: #pragma vector = 中斷向量,緊接着是中斷處理程序
 4 ****************************************************************************/
 5 #pragma vector = P0INT_VECTOR    
 6 __interrupt void P0_ISR(void) 
 7 { 
 8     DelayMS(10);     //延時去抖
 9     LED1 = ~LED1;    //改變LED1狀態
10     P0IFG = 0;       //清中斷標志 
11     P0IF = 0;        //清中斷標志 
12 } 

 

二、代碼主要邏輯

  經過上面講解,代碼主要邏輯已經比較容易理解——在配置(黃色部分代碼)好KEY端口的中斷之后,一旦按鍵被按下,會產生下降沿電平,觸發P0中斷,進入P0_ISR回調函數(綠色部分代碼)。在回調函數中對LED狀態進行控制,並清除中斷標志位。

 1 /****************************************************************************
 2 * 文 件 名: main.c
 3 * 作    者: Andy
 4 * 修    訂: 2013-01-08
 5 * 版    本: 1.0
 6 * 描    述: 通過按鍵S1產生外部中斷改變LED1狀態
 7 ****************************************************************************/
 8 #include <ioCC2530.h>
 9 
10 typedef unsigned char uchar;
11 typedef unsigned int  uint;
12 
13 #define LED1 P1_0       // P1.0口控制LED1
14 #define KEY1 P0_1       // P0.1口控制S1
15 
16 
17 /****************************************************************************
18 * 名    稱: DelayMS()
19 * 功    能: 以毫秒為單位延時,系統時鍾不配置時默認為16M(用示波器測量相當精確)
20 * 入口參數: msec 延時參數,值越大,延時越久
21 * 出口參數: 無
22 ****************************************************************************/
23 void DelayMS(uint msec)
24 { 
25     uint i,j;
26     
27     for (i=0; i<msec; i++)
28         for (j=0; j<535; j++);
29 }
30 
31 /****************************************************************************
32 * 名    稱: InitLed()
33 * 功    能: 設置LED燈相應的IO口
34 * 入口參數: 無
35 * 出口參數: 無
36 ****************************************************************************/
37 void InitLed(void)
38 {
39     P1DIR |= 0x01;   //P1.0定義為輸出口
40     LED1 = 1;        //LED1燈上電默認為熄滅 
41 }
42 
43 /****************************************************************************
44 * 名    稱: InitKey()
45 * 功    能: 設置KEY相應的IO口,采用中斷方式 
46 * 入口參數: 無
47 * 出口參數: 無
48 ****************************************************************************/
49 void InitKey() 50 { 51     P0IEN |= 0x2;    // P0.1 設置為中斷方式 1:中斷使能
52     PICTL |= 0x1;    //下降沿觸發 
53     IEN1 |= 0x20;    //允許P0口中斷; 
54     P0IFG = 0x00;    //初始化中斷標志位
55     EA = 1;          //打開總中斷
56 } 57 
58 /****************************************************************************
59 * 名    稱: P0_ISR(void) 中斷處理函數 
60 * 描    述: #pragma vector = 中斷向量,緊接着是中斷處理程序
61 ****************************************************************************/
62 #pragma vector = P0INT_VECTOR    
63 __interrupt void P0_ISR(void) 64 { 65     DelayMS(10);     //延時去抖
66     LED1 = ~LED1;    //改變LED1狀態
67     P0IFG = 0;       //清中斷標志 
68     P0IF = 0;        //清中斷標志 
69 } 
70 
71 /****************************************************************************
72 * 程序入口函數
73 ****************************************************************************/
74 void main(void)
75 {
76     InitLed();   //設置LED燈相應的IO口
77     InitKey();   //設置S1相應的IO口
78     while(1)
79     {
80     }
81 }

 

三、鏈接

Zigbee系列:

[ZigBee] 1、 ZigBee簡介

[ZigBee] 2、 ZigBee開發環境搭建

[ZigBee] 3、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅

 

PS:如果您覺得還不錯,點個贊,讓更多人受益~

@beautifulzzzz 2016-07-10 continue~  
e-mail:beautifulzzzz@qq.com 
sina:http://weibo.com/beautifulzzzz?is_all=1

 

 


免責聲明!

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



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