ZigBee按键中断

何为按键中断?

在了解按键中断之前,我们先来了解一下什么是中断?中断就是程序执行当前代码,当前任务的时候;

突然有自身函数或外部的影响,而使程序执行到别的任务再回来。

举个栗子:

当你在做饭的时候,电话突然响了,这时候你只能停下当前做饭的动作,去执行听电话的动作

(同理,当你的程序要打印一句很长很长的话,突然有个中断出来,你要去执行那个中断,那个中断

可能是算一个数,也可能是让你程序复位程序执行)

中断优先级别

而说起中断,我们的中断也有个先后顺序中断,是中断去算数还是去中断复位呢?这就需要看你

程序的定义了,默认情况下,你是先把数算出来,再把程序复位才合理的,要是你把程序复位了,再

扫描二维码关注公众号,回复: 4929884 查看本文章

去算数,也进不去算了。不过话说回来,你最后复位了程序,算出来的结果,一样回不去显示出来,

毕竟被自己复位清会原始值了。但是做饭期间来电话,中间必定要做的事情还是要有的,因为你不知

道你的这个电话要聊多久,所以你会先把炉子给关了,然后才去接电话的,要不你的这顿饭就吃不下

了。

下面来看个例子怎么设置中断的优先级吧

首先,我们说一下规则

为了保证中断系统正常工作,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 }

猜你喜欢

转载自www.cnblogs.com/Cion-Da/p/10274351.html