CC2530的中断系统及外部中断应用
Posted 364.99°
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CC2530的中断系统及外部中断应用相关的知识,希望对你有一定的参考价值。
1.中断的相关概念
- 内核与外设之间的主要交互方式:轮询、中断
轮询的方式貌似公平,但实际工作效率很低,不能及时响应紧急事件
中断系统使得内核具备了应对突发条件的能力
- 中断
程序在执行过程中由于外界的原因而被中间打断的情况称为中断:
- 在执行CPU当前程序时,由于系统中出现了某种急需处理的情况,CPU暂停正在执行的程序,转而去执行另一段特殊程序来处理出现的紧急事务
- 处理结束后CPU自动返回到原来暂停的程序中去继续执行
- 两个重要概念
中断服务函数: 内核响应中断后执行的相应处理程序
中断向量: 中断服务程序的入口地址
每个中断源都对应一个固定的入口地址。当内核响应中断请求时,就会暂停当前的程序执行,然后跳转到该入口地址执行代码
2.CC2530中断系统
- 18个中断源,由一系列特殊功能寄存器来进行控制
- 可以编译设置优先级以及使能中断申请响应等
- 常用中断源
3.CC2530中断处理函数编写方法
中断服务函数与一般的自定义函数不同,有特定的书写格式
#pragma vector = <中断向量>
__interrupt void<函数名称>(void){ //注意:此处是两个下划线连在一起
/*编写具体的中断处理程序*/
}
- 在每一个中断服务函数之前,都要加上一句起始语句:
#pragma vector = <中断向量>
<中断向量>
:表示接下来要写的中断服务函数是为哪个中断源服务的,由两种写法:
- 中断向量的入口地址:
#pragma vector = 0x7B
- 头文件"
ioCC2530.h
"的宏定义:#pragma vector = P1INT_VECTOR
__interrupt
:表示该函数是一个中断服务函数
<函数名称>
:可以自定义,函数体不能带有参数,也不能有返回值
4.CC2530外部中断
- P0、P1和P2端口分别使用P0IF、P1IF和P2IF作为中断标志位,任何一个端口组上的引脚产生外部中断时,都会将对应端口组的中断标志自动置位
- 端口状态标志寄存器P0IFG、P1IFG和P2IFG,分别对应三个端口中各引脚的中断触发状态,当某引脚发生外部中断触发时,对应的标志位会自动置位
注意: 1.外部中断标志必须在中断服务函数中手动清除
2.端口状态标志也需要手动清除
5.案例:外部中断输入控制LED灯
要求:
将ZigBee小模块上SW1按键设置为外部中断输入引脚。在中断服务函数中,控制一个LED6灯的开关切换,也就是原来的LED是点亮的熄灭,原来是熄灭的点亮。同时在主程序中,运行一段跑马灯程序,使LED3和LED4灯轮流点亮熄灭
设计思路:
- 端口初始化和跑马灯程序,参考CC2530的通用IO端口(GPIO)输入和输出控制
- 定义一个外部中断初始化函数,将SW1即P1_2引脚配置成外部中断输入端口,将其中断触发方式设置为下降沿触发
- 为外部中断定义一个中断服务函数,要按照中断服务函数的书写格式,注意:在中断服务函数中把相应的中断标志位清除。必须先清除引脚的中断标志,再清除端口组的中断标志
- 涉及外部中断初始化函数Init_INTP()
外部中断初始化函数:主要完成跟中断相关的特殊功能寄存器的配置工作
- 配置IENx寄存器,使能端口组的中断功能
- 配置PxIEN寄存器,使能具体的外部中断引脚
- 配置PICTL寄存器,设置中断触发方式
- 涉及外部中断服务函数Int1_Sevice()
- 在编写中断服务函数时,注意书写格式和中断向量要正确
- 注意: 在函数里面把端口组和引脚的标志为手动清除,否则CPU将反复进入中断,必须先清除引脚标志位PxIFG,再清除端口组标志位PxIF
完整源代码
#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;
//设置LED灯不亮
LED6 = 0;
LED3 = 0;
LED4 = 0;
}
/*========================跑马灯子函数=======================*/
void LED_Running(){
LED3 = 1;
Delay(50000);
LED4 = 1;
Delay(50000);
LED3 = 0;
Delay(50000);
LED4 = 0;
Delay(50000);
}
/*========================外部中断初始化函数================*/
void Init_INTP(){
//端口1中断使能
IEN2 |= 0x10;
//端口P1_2外部中断使能
P1IEN |= 0x04;
//端口P1_0到P1_3下降沿触发
PICTL = 0x02;
//使能总中断
EA = 1;
}
/*========================外部中断1服务函数=================*/
//外部中断1的向量输入
#pragma vector = P1INT_VECTOR
__interrupt void Int1_Sevice(){
LED6 = ~lED6;
/*先清除引脚标志位,再清除端口标志位,否则会不断进入中断*/
P1IFG &= ~0x04;//软件清楚P1_2引脚的标志位
P1IF = 0;//软件清除P1端口组的标志位
}
/*========================主函数============================*/
void main(){
//初始化通用i/o端口
Init_Port();
//初始化外部中断
Init_INTP();
while(1){
//跑马灯
Led_Running();
}
}
以上是关于CC2530的中断系统及外部中断应用的主要内容,如果未能解决你的问题,请参考以下文章