前言
上一篇介紹了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] 3、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅
PS:如果您覺得還不錯,點個贊,讓更多人受益~
@beautifulzzzz 2016-07-10 continue~
e-mail:beautifulzzzz@qq.com
sina:http://weibo.com/beautifulzzzz?is_all=1