[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 }
复制代码


相关文章
|
物联网 API 网络架构
Zigbee 组网过程分析|学习笔记
快速学习Zigbee 组网过程分析
753 0
Zigbee 组网过程分析|学习笔记
|
4月前
|
物联网 5G 智能硬件
【专栏】无线通信的基础术语,如频段、带宽、调制与解调,以及Wi-Fi、蓝牙、ZigBee等无线技术
【4月更文挑战第28天】本文介绍了无线通信的基础术语,如频段、带宽、调制与解调,以及Wi-Fi、蓝牙、ZigBee等无线技术。还涉及无线信号传播、信道容量、信噪比等概念。理解这些术语有助于深入理解无线通信原理,便于设计和优化无线系统。随着无线技术的不断发展,持续学习是关键。开始你的无线通信探索之旅吧!
107 0
|
物联网
zigbee DL-20无线串口收发模块使用(双车通讯,电赛模块推荐)
zigbee DL-20无线串口收发模块使用(双车通讯,电赛模块推荐)
422 0
|
编解码 语音技术
【经典蓝牙】 蓝牙HFP层协议分析
HFP(Hands-Free Profile), 是蓝牙免提协议, 可以让蓝牙设备对对端蓝牙设备的通话进行控制,例如蓝牙耳机控制手机通话的接听、 挂断、 拒接、 语音拨号等。HFP中蓝牙两端的数据交互是通过定义好的AT指令来通讯的
2160 0
【经典蓝牙】 蓝牙HFP层协议分析
|
编解码
【经典蓝牙】蓝牙AVRCP协议分析
蓝牙AVRCP协议是蓝牙设备之间音视频的控制协议。定义了音频/视频的控制、浏览、查询、通知等一系列的命令集。常用来蓝牙耳机对手机的音乐进行控制,以及获取手机的音乐信息等场景。AVRCP协议有两个角色,分别是controller(CT)和 target(TG)。CT: 发送控制命令到对端,控制对端媒体播放器的设备,例如蓝牙耳机,蓝牙遥控器等。TG:接收对端的控制命令,并执行操作,进行回复的设备,例如手机,电脑等。
2594 0
【经典蓝牙】蓝牙AVRCP协议分析
|
编解码 算法 数据格式
【经典蓝牙】蓝牙 A2DP协议分析
A2DP(Advanced Audio Distribution Profile)是蓝牙高音质音频传输协议, 用于传输单声道, 双声道音乐(一般在 A2DP 中用于 stereo 双声道) , 典型应用为蓝牙耳机。         A2DP旨在通过蓝牙连接传输高质量的立体声音频流。它使用的基本压缩算法是SBC(Sub-Band Coding)来减小音频数据的大小,同时保持高音质,SBC压缩虽然效率较低,但是是必须支持的基本备用方案。A2DP还支持其他高级编解码器,例如AAC、aptX和LDAC,这些编解码器比SBC提供更好的音质,但这些编解码器的支持取决于设备本身的支持情况。
2087 0
【经典蓝牙】蓝牙 A2DP协议分析