外部中断(CC2530)

一、实验目的
(1)通过实验掌握CC2530芯片GPIO的配置方法及中断概念与方法。
(2)掌握Led驱动电路及开关Led的原理
(3)通过按键S1产生外部中断改变LED
二 中断概念
1.CPU在执行当前程序时,由于系统出现了某急需处理的的情况,CPU暂停正在执行的程序,转而去执行另外一段特殊程序来处理出现的紧急事务,处理结束后,CPU自动返回到带原来暂停的程序中去继续执行,这种程序在执行过程中由于外界的原因被打断的情况称为中断。
(1)中断服务函数:内核响应中断后执行的相应处理程序。
(2)中断向量:中断服务程序的入口地址。每个中断源都对应一个固定的入口地址。当内核响应中断请求时,就会暂停当前的程序执行,然后跳转到该入口地址执行代码。
2.CC2530具有18个中断源,每个中断源都由各自的一系列特殊功能寄存器来进行控制。可以编程设计相关特殊功能寄存器,设置18个中断源的优先级以及使能中断申请响应等,我们常用的中断源有下面几个:
在这里插入图片描述
三、CC2530中断处理函数编写方法
中断服务韩束花与一般自定义函数不同,有特定的书写格式:
在每个中断服务函数之前,都要加上一句起始语句:

#pragma vector = <中断向量>
<中断向量>表示接下来要写的中断服务函数是为那个中断源服务的,该语句有两种写法:
#pragma vector = 0x7B

#pragma vector = P1INT_VECTOR
前者是中断向量的入口地址,后者是头文件“ioCC2530.h”中的宏定义

在这里插入图片描述

_ _interrupt void <函数名称>(void){

/*在这里编写中断处理函数的具体程序*/

}
_ _interruppt关键字表示该函数是一个中断服务函数,<函数名称>可以自定义,函数体不能带有参数也不能有返回值。
interrupt前面有两个"_"下划线 ,编写出错的话编译会报错
四、CC2530的外部中断
CC2530的P0、P1、P2端口中的每个引脚都具有外部中断输入功能,要使某些引脚具有外部中断功能,需要配置响应的寄存器(IENX寄存器、PXIEN寄存器和PICTL寄存器)进行适当的设置,除了各个中断源都有自己的中断使能开关之外,中断系统还有一个总开关,可以用EA = 1;来打开总开关。
P0、P1和P2端口分别使用P0IF、P1IF和P2IF作为中断标志位,任何一个端口组上的引脚产生外部中断时,都会将对应端口组的中断标志自动置位。外部中断标志必须在中断服务函数中手动清除,否则CPU会反复进入中断。端口标志寄存器P0IFG、P1IFG、P1IFG分别对应3个端口中各引脚的中断触发状态,当某引脚发生外部中断触发时,对应的标志位会自动置位,这个标志同样需要手动清除。

四、实验相关电路图
通过P1_0控制开关亮灭,用PO_1判断按键是否被按下。
在这里插入图片描述
在这里插入图片描述
五、配置相关寄存器
CC2530 外部中断需要配置P0IEN、P1CTL、P0IFG、IEN1寄存器。外部寄存器说明如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
P1DIR |= 0x01;将P1DIR(P1端口方向寄存器)上的第P1_0设为高电平,即将P1_0方向设为输出,输出低电平0V或高电平3.3V控制LED等亮灭。

P0IEN |= 0x02;将P0IEN(P0口的中断使能)上的P0_1位置设为1即中断使能。

PICTL |=0x01;将PICTL(P0、P1、P2端口中断控制寄存器)最后一位设为0即P0端口0到第7位输入模式下的中断配置,P0端口沿下降沿触发。

IEN1 |= 0x20;将IEN1(中断使能1)第五位设置为1,即将P0端口中断使能允许中断。

P0IFG = 0x00;将P0IFG(端口0中断状态标志)也就是端口0 第0位到第7位输入中断状态标志。当输入端口中断请求未决信号时,其相应标志位将置1.(有中断请求时候,改位被置为1)
EA = 1;打开总中断。
在这里插入图片描述
主函数执行完;LED灯初始化和按键初始化后进入死循环,若按键没有被按下不会发生中断,当程序进入死循环的时候,我们按下按键发生按键按下事件时执行中断函数P0ISR,改变LED灯的状态,要清除中断标志位不然会一直执行中断函数。
实验代码
/* 描 述: 通过按键S1产生外部中断改变LED1状态
****************************************************************************/


#include <ioCC2530.h>

typedef unsigned char uchar;
typedef unsigned int  uint;

#define LED1 P1_0       // P1.0口控制LED1
#define KEY1 P0_1       // P0.1口控制S1


/****************************************************************************
* 名    称: DelayMS()
* 功    能: 以毫秒为单位延时,系统时钟不配置时默认为16M(用示波器测量相当精确)
* 入口参数: msec 延时参数,值越大,延时越久
* 出口参数: 无
****************************************************************************/
void DelayMS(uint msec)
{ 
    uint i,j;
    
    for (i=0; i<msec; i++)
        for (j=0; j<535; j++);
}

/****************************************************************************
* 名    称: InitLed()
* 功    能: 设置LED灯相应的IO口
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitLed(void)
{
    P1DIR |= 0x01;   //P1.0定义为输出口
    LED1 = 1;        //LED1灯上电默认为熄灭 
}

/****************************************************************************
* 名    称: InitKey()
* 功    能: 设置KEY相应的IO口,采用中断方式 
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void InitKey()
{
    P0IEN |= 0x2;    // P0.1 设置为中断方式 1:中断使能
    PICTL |= 0x1;    //下降沿触发   
    IEN1 |= 0x20;    //允许P0口中断; 
    P0IFG = 0x00;    //初始化中断标志位
    EA = 1;          //打开总中断
}

/****************************************************************************
* 名    称: P0_ISR(void) 中断处理函数 
* 描    述: #pragma vector = 中断向量,紧接着是中断处理程序
****************************************************************************/
#pragma vector = P0INT_VECTOR    
__interrupt void P0_ISR(void) 
{ 
    DelayMS(10);     //延时去抖
    LED1 = ~LED1;    //改变LED1状态
    P0IFG = 0;       //清中断标志 
    P0IF = 0;        //清中断标志 
} 

/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void)
{
    InitLed();   //设置LED灯相应的IO口
    InitKey();   //设置S1相应的IO口
    while(1)
    {
    }
}

六、实验现象

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值