CC2530按键中断应用

任务分析

1.单片机复位 LED1和LED2灭
2.按下KEY1 LED1和LED2亮
3.再按下KEY1 LED1和LED2灭
4.循环以上

知识储备

相关寄存器知识

由于我手上的开发板LED1,LED2,KEY1对应的引脚分别是P1_0,P1_1,P1_2。所以我下面主要介绍和P1相关的寄存器。其他端口类似。

IEN2 – 中断使能2

CC2530中文数据手册截图:
在这里插入图片描述
令IEN2 |= 0x10;即可打开P1(端口1)中断。
同理 令IEN2 |= 0x02;即可使能P2(端口2)中断
P0(端口0)类似,相应寄存器说明截图如下:
在这里插入图片描述

P1IEN – 端口1中断屏蔽

在这里插入图片描述
令P1IEN |= 0x04;即可使能P1_2中断*

PICTL – 端口中断控制

在这里插入图片描述
令PICTL |= 0x02即可使P1_0~P1_3下降沿触发中断

总中断 – EA

在这里插入图片描述
令EA = 1即可开启总中断

相关寄存器总结:

综上所述,配置P1_2所连接的KEY1的中断的步骤是:
1.开启总中断 — EA = 1
2.使能P1中断 — IEN2 |= 0x10
3.使能P1_3中断 — P1IEN |= 0x04
4.配置中断下降沿触发 — PICTL |= 0x02

代码

#include <ioCC2530.h>

#define LED1 P1_0
#define LED2 P1_1
#define KEY1 P1_2

unsigned int Flag = 0;

void delay(unsigned int i)
{
  while(i--);
}

void LedInit()
{
  P1SEL &= ~0x03;
  P1DIR |= 0x03;
}

void KeyInit()
{
  P1IEN |= 0x04;//中断使能
  PICTL |= 0x02;//P1_0~P1_3下降沿触发中断
  IEN2 |= 0x10;//开P1中断
  EA = 1;//开总中断
}

void main()
{
  LedInit();
  KeyInit();
  
  LED1 = 0;
  LED2 = 0;
  
  while(1)
  {
    switch(Flag)
    {
    case 1 : LED1 = 1;LED2 = 1;break;
    case 0 : LED1 = 0;LED2 = 0;break;
    default : break;
    }
  }
  
}

#pragma vector=P1INT_VECTOR
__interrupt void P1_ISR()
{
  if(P1IFG &= 0x04)
  {
    delay(200);
    if(P1IFG &= 0x04)
    {
      if(Flag == 0)
      {
        Flag = 1;
      }else if(Flag == 1)
      {
        Flag = 0;
      }
    }
  }
  P1IFG = 0;
  P1IF = 0;
}

代码分析

引脚初始化配置

void LedInit()
{
  P1SEL &= ~0x03;
  P1DIR |= 0x03;
}

中断初始化配置

void KeyInit()
{
  P1IEN |= 0x04;//中断使能
  PICTL |= 0x02;//P1_0~P1_3下降沿触发中断
  IEN2 |= 0x10;//开P1中断
  EA = 1;//开总中断
}

中断回调函数分析

#pragma vector=P1INT_VECTOR
__interrupt void P1_ISR()
{
  if(P1IFG &= 0x04)
  {
    delay(200);
    if(P1IFG &= 0x04)
    {
      if(Flag == 0)
      {
        Flag = 1;
      }else if(Flag == 1)
      {
        Flag = 0;
      }
    }
  }
  P1IFG = 0;
  P1IF = 0;
}

CC2530中断函数有特定的书写方式
(一):#pragma vector=中断向量
再ioCC2530.h中可以找到相关的定义

/* ------------------------------------------------------------------------------------------------
 *                                        Interrupt Vectors
 * ------------------------------------------------------------------------------------------------
 */
#define  RFERR_VECTOR   VECT(  0, 0x03 )   /*  RF TX FIFO Underflow and RX FIFO Overflow   */
#define  ADC_VECTOR     VECT(  1, 0x0B )   /*  ADC End of Conversion                       */
#define  URX0_VECTOR    VECT(  2, 0x13 )   /*  USART0 RX Complete                          */
#define  URX1_VECTOR    VECT(  3, 0x1B )   /*  USART1 RX Complete                          */
#define  ENC_VECTOR     VECT(  4, 0x23 )   /*  AES Encryption/Decryption Complete          */
#define  ST_VECTOR      VECT(  5, 0x2B )   /*  Sleep Timer Compare                         */
#define  P2INT_VECTOR   VECT(  6, 0x33 )   /*  Port 2 Inputs                               */
#define  UTX0_VECTOR    VECT(  7, 0x3B )   /*  USART0 TX Complete                          */
#define  DMA_VECTOR     VECT(  8, 0x43 )   /*  DMA Transfer Complete                       */
#define  T1_VECTOR      VECT(  9, 0x4B )   /*  Timer 1 (16-bit) Capture/Compare/Overflow   */
#define  T2_VECTOR      VECT( 10, 0x53 )   /*  Timer 2 (MAC Timer)                         */
#define  T3_VECTOR      VECT( 11, 0x5B )   /*  Timer 3 (8-bit) Capture/Compare/Overflow    */
#define  T4_VECTOR      VECT( 12, 0x63 )   /*  Timer 4 (8-bit) Capture/Compare/Overflow    */
#define  P0INT_VECTOR   VECT( 13, 0x6B )   /*  Port 0 Inputs                               */
#define  UTX1_VECTOR    VECT( 14, 0x73 )   /*  USART1 TX Complete                          */
#define  P1INT_VECTOR   VECT( 15, 0x7B )   /*  Port 1 Inputs                               */
#define  RF_VECTOR      VECT( 16, 0x83 )   /*  RF General Interrupts                       */
#define  WDT_VECTOR     VECT( 17, 0x8B )   /*  Watchdog Overflow in Timer Mode             */

这玩意有两种写法 :

#pragma vector=P1INT_VECTOR
#pragma vector=0x7B

(二):__interrupt void 函数名称()
__interrupt表明这个函数是中断函数
函数名称随便取

**(三):**函数内容

if(P1IFG &= 0x04)
  {
    delay(200);
    if(P1IFG &= 0x04)
    {
      if(Flag == 0)
      {
        Flag = 1;
      }else if(Flag == 1)
      {
        Flag = 0;
      }
    }
  }
  P1IFG = 0;
  P1IF = 0;

P1IFG &= 0x04判断是不是P1_2出发的中断
逻辑函数完成后不要忘记

P1IFG = 0;//清除P1_2引脚标志位
P1IF = 0;//清除P1端口标志位
  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值