CC2530外部中断
一、中断基础概念
内核与外设之间的主要交互方式有两种:轮询和中断。中断系统使得内核具备了应对突发事件的能力。
在执行CPU当前程序时,由于系统中出现了某种急需处理的情况,CPU暂停正在执行的程序,转而去执行另外一段特殊程序来处理出现的紧急事务,处理结束后,CPU自动返回到原来暂停的程序中去继续执行。 这种程序在执行过程中由于外界的原因而被中间打断的情况,称为中断。
采用中断技术后,可以为计算机系统带来以下好处:
1)实现分时操作
速度较快的CPU和速度较慢的外设可以各做各的事情,外设可以在完成工作后再与CPU进行交互,而不需要CPU去等待外设完成工作,能够有效提高CPU的工作效率。
2)实现实时处理
在控制过程中,CPU能够根据当时情况及时做出反应,实现实时控制的要求。
3)实现异常处理
系统在运行过程中往往会出现一些异常情况,中断系统能够保证CPU及时知道出现的异常,以便CPU去解决这些异常,避免整个系统出现大的问题。
两个重要的概念:
<1> 中断服务函数: 内核响应中断后执行的相应处理程序。例如ADC转换完成中断被响应后,CPU执行相应的中断服务函数,该函数实现的功能一般是从ADC结果寄存器中取走并使用转换好的数据。
<2> 中断向量:中断服务程序的入口地址,当CPU响应中断请求时,会跳转到该地址去执行代码。
二、 CC2530中断
CC2530具有18个中断源,每个中断源都有它自己的位于一系列SFR 寄存器中的中断请求标志。相应标志位请 求的每个中断可以分别使能或禁用。

Tip:
(1)当调用中断服务例程时清除硬件。
(2)另外的 IRQ 掩码和 IRQ 标志位存在。
三、CC2530中断处理函数格式书写
中断服务函数与一般自定义函数不同,有特定的书写格式:
#pragma vector = 中断向量
__interrupt void 函数名称 (void)
{
/*此处编写中断处理函数的具体程序*/
PxIFG = 0; //先清除Px引脚的中断状态标志位
PxIF = 0; //再清除Px端口组的中断状态标志位
}
<1> 在每一个中断服务函数之前,都要加上一句起始语句:
#pragma vector = <中断向量>
<中断向量>表示接下来要写的中断服务函数是为那个中断源服务的,该 语句有两种写法:
#pragma vector = 0x7B或者#pragma vector = P1INT_VECTOR
前者是中断向量的入口地址,后者是头文件“ioCC2530.h”中的宏定义。
<2> _ _interrupt关键字表示该函数是一个中断服务函数,<函数名称>可以 自定义,函数体不能带有参数,也不能有返回值。
四、外部中断
(1)CC2530的P0、P1和P2端口中的每个引脚都具有外部中断输入功能,要使某些引脚具有外部中断功能,需要对IENx寄存器、PxIEN寄存器和PICTL寄存器进行适当的设置。 除了各个中断源都有自己的中断使能开关之外,中断系统还有一个总开关,可以同“EA = 1;”来打开总中断。
IENx寄存器 使能端口组的中断功能。

PxIEN寄存器 使能具体的外部中断引脚。


PICTL寄存器 设置中断触发方式。

(2)P0、P1和P2端口分别使用P0IF、P1IF和P2IF作为中断标志位,任何一个端口组上的引脚产生外部中断时,都会将对应端口组的中断标志自动置位。注意,外部中断标志必须在中断服务函数中手工清除,否则CPU会反复进入中断。 端口状态标志寄存器P0IFG、P1IGF和P2IFG,分别对应3个端口中各引脚的中断触发状态,当某引脚发生外部中断触发时,对应的标志位会自动置位,这个标志同样需要手工清除。


题目:
将Zigbee小模块上SW1按键设置为外部中断输入引脚。在中断服务函数中,控制一个LED6灯的开关切换,也就是原来LED是点亮的熄灭,原来熄灭的点亮。同时在主程序中,运行一段跑马灯程序,使LED3和LED4轮流点亮和熄灭。
思路:
(1)端口初始化和跑马灯程序
(2)定义一个外部中断初始化函数,将SW1引脚,即P1_ _2引脚配置成外部中断输入端口,将其中断触发方式设置为下降沿触发。
(3)为外部中断定义-一个中断服务函数,要照中断服务函数的书写格式编程,注意要在中断服务函数中把相应的中断标志位清除。必须先清除引脚的中断标志,再清除端口组的中断标志。
解题:
【1】设计外部中断初始化函数Init_INTP()
外部中断初始化函数,主要是完成跟中断相关的特殊功能寄存器配置工作:
<1> 配置IENx寄存器,使能端口组的中断功能。
<2> 配置PxIEN寄存器,使能具体的外部中断引脚。
<3> 配置PICTL寄存器,设置中断触发方式。
void Init_INTP()
{
IEN2 |= 0x10; //端口1中断使能 0001 0000 端口1 中断使能
P1IEN |= 0x04; //端口P1_2外部中断使能 0000 0100 P1_2 使能具体的外部中断引脚。
PICTL |= 0x02; //端口P1_0到P1_3下降沿触发 0000 0010 P1_0和P1_1 下降沿触发
EA = ; //使能总中断
}
【2】设计外部中断服务函数Int1_Sevice()
在编写中断服务函数的时候,书写格式要正确,中断向量不能搞错。特别要注意:在函数里面把端口组和引脚的标志位清除,否则CPU将会反复进入中断,必须先清除引脚标志位PxIFG,再清除端口组标志位PxIF。
#pragma vector = P1INT_VECTOR //外部中断1的向量入口
__interrupt void Int1_Sevice()
{
LED6 = ~LED6;
/*先清除引脚标志位,再清除端口标志位,否则会不断进入中断*/
P1IFG &= ~ 0x04; //软件清除P1_2引脚的标志位
P1IF = ; //软件清除P1端口组的标志位
}
最终代码:
#include "ioCC2530.h" #define LED6 P1_4
#define LED3 P1_0
#define LED4 P1_1
/*===================延时函数=========================*/
void Delay(unsigned int t)
{
while(t--);
}
/*==================端口初始化函数=====================*/
void Init_Port()
{
//将P1_0、P1_1和P1_4设置为通用I/O端口功能
P1SEL &= ~0x13;
//将P1_0、P1_1和P1_4的端口传输方式设置为输出
P1DIR |= 0x13; P1SEL &= ~0x04; //P1_2作为通用I/O端口
P1DIR &= ~0x04; //P1_2端口输入
P1INP &= ~0x04; //P1_2设置为上拉/下拉模式
P2INP &= ~0x40; //P1_2设置为上拉 LED6 = ;
LED3 = ;
LED4 = ;
}
/*==================跑马灯子函数=====================*/
void LED_Running()
{
LED3 = ;
Delay();
LED4 = ;
Delay();
LED3 = ;
Delay();
LED4 = ;
Delay();
}
/*===============外部中断初始化函数==================*/
void Init_INTP()
{
IEN2 |= 0x10; //端口1中断使能 0001 0000 端口1 中断使能
P1IEN |= 0x04; //端口P1_2外部中断使能 0000 0100 P1_2 使能具体的外部中断引脚。
PICTL |= 0x02; //端口P1_0到P1_3下降沿触发 0000 0011 P1_0和P1_1 下降沿触发
EA = ; //使能总中断
}
/*================外部中断1服务函数====================*/
#pragma vector = P1INT_VECTOR //外部中断1的向量入口
__interrupt void Int1_Sevice()
{
LED6 = ~LED6;
/*先清除引脚标志位,再清除端口标志位,否则会不断进入中断*/
P1IFG &= ~ 0x04; //软件清除P1_2引脚的标志位
P1IF = ; //软件清除P1端口组的标志位
}
/*====================主函数==========================*/
void main()
{
Init_Port(); //初始化通用I/O端口
Init_INTP(); //初始化外部中断
while()
{
LED_Running(); //跑马灯
}
}
总结
void Init_INTP() //中断初始化函数
{
EA = 1; //开总中断
IENx = ? ; //要用哪一个端口组?P0,P1还是P2?
/*
IEN1 |= 0x20;开P0端口组中断
IEN2 |= 0x10;开P1端口组中断
IEN2 |= 0x01;开P2端口组中断
以上都为固定开各个端口组中断的写法,至于为什么是这样子才能开P0,P1,或P2端口组的中断,翻看手册就知道了
*/
PxIEN = ? ; //开端口组中断之后,要选择用哪一个引脚?
PICTL = ? ; //开引脚中断之后,选择沿触发方式,上升沿还是下降沿?
}
#pragma vector = 中断向量
__interrupt void 函数名称 (void)
{
/*此处编写中断处理函数的具体程序*/
PxIFG = 0; //先清除Px引脚的中断状态标志位
PxIF = 0; //再清除Px端口组的中断状态标志位
}
CC2530外部中断的更多相关文章
- CC2530 外部中断 提醒
#include "ioCC2530.h" #define uchar unsigned char #define led1 P1_0 #define led2 P1_ ...
- 【CC2530入门教程-03】CC2530的中断系统及外部中断应用
第3课 CC2530的中断系统及外部中断应用 广东职业技术学院 欧浩源 一.中断相关的基础概念 内核与外设之间的主要交互方式有两种:轮询和中断. 轮询的方式貌似公平,但实际工作效率很低,且不能及 ...
- 掌握所有IO口的外部中断
外部中断配置流程 1.初始化IO口工作在普通IO.上拉输入状态. 2.首先开IO口组中断(P0IE=1.P1IE=1.P2IE=1): 3.开组内对应的具体某IO口中断(P0IEN.P1IEN.P2I ...
- STM32f103之外部中断
一.背景 有个需求,IO口检测上升沿,然后做相应的动作.在此记录STM32F103的外部中断结构及配置方法, 以备下次快速上手使用. 有许多不太明白,又是老司机(:-D)帮忙,真的是站在别人的肩膀上会 ...
- STM32之EXTI——外部中断
互联网的广大网友,大家早上中午晚上好.EXTI...故名思义..EX表外,出..I表示Intrrupt..所以合起来就是外部中断...说到这..我觉得我最近的六级水平(背单词)又进了一步,稍微自夸了下 ...
- 转别人的 STM32外部中断使用注意事项
前言:这些问题都是我之前在工作中遇到的,后来觉得需要总结,自己记忆不好,所以在这个给自己打个mark. 一:触发方式 STM32 的外部中断是通过边沿来触发的,不支持电平触发: 二:外部中断分组 ST ...
- STM32外部中断初理解
PA0,PB0...PG0--->EXTI0 PA1,PB1...PG1--->EXTI1 ....... PA15,PB15...PG15--->EXTI15 以上为GPIO和中断 ...
- STM32——外部中断EXIT实现
外部中断实现步骤: 一.初始化,包括:1.AFIO时钟中断和GPIO时钟使能: 2.GPIO初始化 ...
- STM32 GPIO外部中断总结
一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...
随机推荐
- 用一个完整的案例讲解Python数据分析的整个流程和基础知识
先来想一下数据分析的流程,第一步获取数据,因此本节内容就是获取数据以及对数据的基本操作. 1.数据导入 1.1 导入.xlsx文件 要导入一个.xlsx后缀的Excel文件,可以使用pd.read_e ...
- JS 中的自定义事件和模拟事件
在 JS 中模拟事件指的是模拟 JS 中定义的一些事件,例如点击事件,键盘事件等. 自定义事件指的是创建一个自定义的,JS 中之前没有的事件. 接下来分别说一下创建这两种事件的方法. 创建自定义事件 ...
- 如何可视化深度学习网络中Attention层
前言 在训练深度学习模型时,常想一窥网络结构中的attention层权重分布,观察序列输入的哪些词或者词组合是网络比较care的.在小论文中主要研究了关于词性POS对输入序列的注意力机制.同时对比实验 ...
- Spark SQL源码解析(二)Antlr4解析Sql并生成树
Spark SQL原理解析前言: Spark SQL源码剖析(一)SQL解析框架Catalyst流程概述 这一次要开始真正介绍Spark解析SQL的流程,首先是从Sql Parse阶段开始,简单点说, ...
- SringMVC入门程序
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架 1.Spring优点 轻量级,简单易学 高效 , 基于请求响应的MVC框架 与Spring兼 ...
- vim环境下空格和tab键互换
对于已保存的文件,可以使用下面的方法进行空格和TAB的替换 TAB替换为空格::set ts=4:set expandtab:%retab! 空格替换为TAB::set ts=4:set noexpa ...
- Apache jena SPARQL endpoint及推理
一.Apache Jena简介 Apache Jena(后文简称Jena),是一个开源的Java语义网框架(open source Semantic Web Framework for Java),用 ...
- [nodejs] 同步/异步创建多层目录
背景 有时项目里需要同时创建多层目录的功能,但低版本的nodejs并没有提供快捷的api 尽管在v10.12.0版本 mkdir() 第二个参数支持recursive 参数,为true时能递归创建,但 ...
- for嵌套setTimeout的心得
export default { data() { return { dialogList: [] } }, created() { this.setList() }, methods: { setL ...
- Inno Setup, Pascal 字符串带双引号如何写
Windows 的路径中如果有空格,就需要用双引号括起来.只能填 ASCII-Code-Number (decimal),不能用一般的 escape 方法. # + path + # 查询这个表的第一 ...