单片机学习小组
直播中

王莉

7年用户 1305经验值
私信 关注

如何利用CC2530按键中断控制LED的亮灭?

如何利用CC2530按键中断控制LED的亮灭?

回帖(1)

张涵

2022-1-25 10:31:34
任务分析

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


#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
1
(二):__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端口标志位
举报

更多回帖

发帖
×
20
完善资料,
赚取积分