打印
[Zigbee]

CC2530外部中断

[复制链接]
960|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gwsan|  楼主 | 2019-7-31 10:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1 理论分析
1.1 CC2530 通用 IO 中断详解
通用 I/O 引脚设置为输入后,可以用于产生中断。中断可以设置在外部信号的上升或下降沿触发。P0、P1 或 P2 端口都有中断使能位,对位于 IENl-2 寄存器内的端口所有的位都是公共的,如下:
        IENI.P0 IE:P0 中断使能
        IEN2.PI IE:P1 中断使能
        IEN2.P2IE:P2 中断使能

除了这些公共中断使能之外,每个端口的位都有位于 SFR 寄存器 P0IEN、P1IEN和 P2IEN 的单独的中断使能。即使配置为外设 I/O 或通用输出的 I/O 引脚使能时都有中断产生。

当中断条件发生在 I/O 引脚之一上面,P0-P2 中断标志寄存器 P0IFG、P1IFG 或 P2IFG 中相应的中断状态标志将设置为 1。不管引脚是否设置了它的中断使能位,中断状态标志都被设置。当中断已经执行,中断状态标志被清除,该标志写入 0。这个标志必须在清除 CPU 端口中断标志(PxIF)之前被清除。
用于中断的 SFR 寄存器描述在下一节。寄存器总结如下:

        P0IEN: P0 中断使能
        P1IEN:P1 中断使能
        P2IEN:P2 中断使能
        PICTL:P0、P1 和 P2 触发沿设置
        P0FG:P0 中断标志
        P1IFG:P1 中断标志
        P2IFG:P2 中断标志


使用特权

评论回复

相关帖子

沙发
gwsan|  楼主 | 2019-7-31 10:49 | 只看该作者
1.2 流程图

下面是很实验的流程图,大家可以结合这个图来学习编写程序。


使用特权

评论回复
板凳
gwsan|  楼主 | 2019-7-31 10:49 | 只看该作者
2 实验详解
2.1实验目的
1)、通过实验掌握CC2530芯片GPIO的配置方法,带你一步步走进嵌入式大门
2)、握Led驱动电路及开关Led的原理
3)、过按键S1产生外部中断改变LED1\LED2\LED3状态

2.2实验设备
硬件:PC 机一台 ZB2530(底板、核心板、仿真器、USB 线) 一套
软件:win7 系统,IAR 8.20 集成开发环境

使用特权

评论回复
地板
gwsan|  楼主 | 2019-7-31 10:50 | 只看该作者
2.3实验相关电路图

图2 LED电路图

图3 按键电路图

使用特权

评论回复
5
gwsan|  楼主 | 2019-7-31 10:50 | 只看该作者
2.4实验分析
        启用通用 IO 中断步骤

(1)清除中断标志;
(2)如果有,则设置 SFR 寄存器中对应的各中断使能位为 1;
(3)设置寄存器 IEN0、IEN1 和 IEN2 中对应的中断使能位为 1;
(4)设置 IEN0 中的 EA 位为 1 使能全局中断;
(5)在该中断对应的向量地址上,运行该中断的服务程序。

使用特权

评论回复
6
gwsan|  楼主 | 2019-7-31 10:51 | 只看该作者
寄存器配置

也就是说,通用 IO 端口使用中断模式时,需要配置 PxIEN、PICTL、PxIFG、IENx、EA、PxSEL、PxDIR、PxINP 这些寄存器(或其相关位) ;而 LED 灯控制端口配置的是 PxSEL、PxDIR、PxINP 这三个寄存器:
通用寄存器的作用和配置方法如表1、2、3所示(以P1为例):

表1 端口1的功能选择


表2 端口1的方向


表3 端口1的输入模式


CC2530外部中断需要配置P0IEN 、PICTL 、P0IFG、IEN1寄存器。外部中断寄存器


使用特权

评论回复
7
gwsan|  楼主 | 2019-7-31 10:51 | 只看该作者
说明如表4、5、6、7所示(以端口0为例):

表4 端口0的中断屏蔽


表5 端口中断控制


表6 端口0的中断状态标志


表7 中断使能


按照表格寄存器的内容,对LED3配置如下:
P1SEL &=~0x01; //配置P1.0为通用IO口,默认为0的,可以不设
P1DIR |= 0x01; //P10 定义为输出

按键S1配置如下:
P0IEN |= 0x02; // P0.1 设置为中断方式1:中断使能
PICTL |= 0x00; //上升沿触发
IEN1 |= 0x20; //允许P0口中断;
P0IFG = 0x00; //初始化中断标志位
EA = 1; //打开总中断


使用特权

评论回复
8
gwsan|  楼主 | 2019-7-31 10:52 | 只看该作者
2.5参考代码
/**Includes*********************************************************************/
#include <ioCC2530.h>

/**宏定义***********************************************************************/
//定义数据类型
#define uint unsigned int
#define uchar unsigned char

//定义控制LED灯的端口
#define LED1 P1_0        //定义LED1为P1.0口控制
#define KEY1 P0_1       //中断口

/**函数声明*********************************************************************/

void Delayms(uint);                //延时函数
void InitLed(void);                //初始化P1口
void InitKey();                 //按键初始化

/**
  * @brief     中断处理
  * @param     None
  * @retval    None
  */
#pragma vector = P0INT_VECTOR    //格式:#pragma vector = 中断向量,紧接着是中断处理程序
  __interrupt void P0_ISR(void)
{
  Delayms(10);            //去除抖动
  LED1=~LED1;             //改变LED1状态
  P0IFG = 0;              //清中断标志
  P0IF = 0;               //清中断标志
}

/**
  * @brief     主函数
  * @param     None
  * @retval    None
  */
void main(void)
{
  InitLed();                //调用初始化函数
  InitKey();
  while(1)
  {
  }
}

/**
  * @brief     普通延时函数
  * @param     xms 延时长度
  * @retval    None
  */
void Delayms(uint xms)   //i=xms 即延时i毫秒
{
  uint i,j;
  for(i=xms;i>0;i--)
    for(j=587;j>0;j--);
}

/**
  * @brief     LED初始化
  * @param     None
  * @retval    None
  */
void InitLed(void)
{
  P1DIR |= 0x01; //P1_0定义为输出
  LED1 = 1;       //LED1灯熄灭     
}

/**
  * @brief     KEY初始化程序--外部中断方式
  * @param     None
  * @retval    None
  */
void InitKey()
{
  P0IEN |= 0X02;  //P01设置为中断方式
  PICTL |= 0X00; // 上升沿触发中断   
  IEN1 |= 0X20;   // 允许P0口中断;
  P0IFG = 0x00;   // 初始化中断标志位
  EA = 1;
}

使用特权

评论回复
9
gwsan|  楼主 | 2019-7-31 10:52 | 只看该作者
2.6实验现象
使用外部中断,通过按键控制LED的反转。

使用特权

评论回复
10
gwsan|  楼主 | 2019-7-31 10:52 | 只看该作者
2.7 实验总结
2.7.1 CC2530 中断机制
(1) 当按键 KEY1 按下时,因为 KEY1 所对应的 I/O 口为 P0_1,所以 P0 端口将会发出一个中断请求,并自动将 P0IFG 寄存器对应位(即 D4 位)置 1,等待 CPU 响应;

(2) CPU 在执行完一条指令之后就会检测是否有中断请求,如果检测到中断请求并且 IEN1 的 D5 位为 1 和 P0IEN 的 D4 为 1 时,对应的中断使能位中断使能,则根据中断类型号获得中断向量,根据中断向量得到中断服务子程序的地址,执行终端服务子程序。当中断服务子程序执行完毕后返回执行原来的程序

2.7.2 P1IEN 寄存器与 IEN2 寄存器的区别
P0IEN 和 IEN1 同样都是中断屏蔽寄存器, P0IEN 控制 P0 口每一个端口的中断使能,IEN1 控制整个 P0 的中断使能。当 IEN1 中设置了 P0 口中断屏蔽时(D5=0) ,无论 P0IEN 中对应的使能位设置成屏蔽还是使能,该 I/O 发出的中断请求 CPU 都不予接受。例如:若将本例中 InitKey ()函数中的 IEN1|= 0X20; 代码行注释掉,KEY 按下后 LED1将没有变化。

使用特权

评论回复
11
gwsan|  楼主 | 2019-7-31 10:53 | 只看该作者
2.7.3中断向量
我们先看头文件中关于中断向量定义的代码:



图4 IAR 里打开文件的方法


图 5CC2530 中断向量表
看图5中注释或者通过 datasheet 可知,0X6B 为 P0 口的中断向量,#define P0INT_VECTOR VECT( 13, 0x6B )将 P0 口的中断向量定位为 P0INT_VECTOR。同理,上面所列出的代码还将其他的中断向量分别作了定义。

表8 CC2530datasheet 中断概览



使用特权

评论回复
12
gwsan|  楼主 | 2019-7-31 10:53 | 只看该作者
2.7.4中断服务子程序格式
#pragma vector = 中断向量
__interrupt void 任意函数名(void)
{
//中断处理,处理完成后通常需要清除中断标志
}

使用特权

评论回复
13
gwsan|  楼主 | 2019-7-31 10:53 | 只看该作者
2.7.5启用通用 IO 中断步骤
(1)清除中断标志;
(2)如果有,则设置 SFR 寄存器中对应的各中断使能位为 1;
(3)设置寄存器 IEN0、IEN1 和 IEN2 中对应的中断使能位为 1;
(4)设置 IEN0 中的 EA 位为 1 使能全局中断;
(5)在该中断对应的向量地址上,运行该中断的服务程序

使用特权

评论回复
14
conjunction| | 2019-7-31 14:06 | 只看该作者
感谢楼主分享!很不错的经验

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

3426

帖子

1

粉丝