[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个引脚中断模式设置为下降沿触发。

[ZigBee] 4、ZigBee基础实验——中断_第1张图片

  

  当中断条件发生在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 
 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)
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:[email protected] 
sina:http://weibo.com/beautifulzzzz?is_all=1

 

 

你可能感兴趣的:([ZigBee] 4、ZigBee基础实验——中断)