标签:
前言
上一篇介绍了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
标签:
原文地址:http://www.cnblogs.com/zjutlitao/p/5658395.html