Zigbee中CC2530按键中断;CC2530按键控制流水灯。

首先先来了解一下相关知识。。

按键相关基础知识:

在CC2530中有21个可用于编程的I/O引脚,P0、P1的0-8口,P2的0-4口。

P0的口带有A/D转换功能。

寄存器相关基础知识(实现按键中断涉及到的寄存器):

PxSEL: 该寄存器可理解为IO口模式选择寄存器,可以配置Px口某一个IO口的模式。

(例如:P0SEL &=~(1<<0)  意思是设置P0_0口为普通IO口)  0为普通IO口,1为第二功能IO口,如用于AD转换。

PxDIR:   该寄存器配置IO口的方向可以是输入可以输出,简单举例控制led亮灯是输出,获取传感器的数据是输入。

(例如:P0DIR |=(1<<0)意思是设置P0_0口的方向为输出口)1为输出口,0为输入口。

PICTL:该寄存器是中断控制寄存器(Port Interrupt Control)可以控制P0,P1,P2的中断边缘选择。

该寄存器是8位寄存器:

0位设置端口0(P0_0到P0_7)的触发方式;1位设置IO口P1_0到P1_3的触发方式;2位设置IO口P1_4到P1_7的触发方式;3位设置IO口P2_0到P2_4的触发方式;

1为低电平触发,0为高电平触发。

实例:

 PICTL |=(1<<0);  //设置P0口的触发方式为下降沿触发 
 PICTL |=(1<<1);  //设置P1_0到P1_3口的触发方式为下降沿触发

PxIF:该寄存器是中断状态标志寄存器,其大小为1位。

举例说明:P0IF==1 说明P0口的某一个IO口发生了中断,具体是哪一位在这里无法断知。

PxIFG:该寄存器用于标记哪一个脚发生了中断。

例如:P0IFG==0x01说明P0口的0脚发生了中断。

中断允许:总共需要设置3级允许,分别是:总中断允许,端中断允许和脚中断允许。

(1)EA是总中断允许。

(2)端中断允许在IENx中,IEN1中的5是P0IE,0端中断允许。IEN2中的4是P1IE,1端中断允许。

(3)脚中断允许在PxIEN中设置。例如:

  P0IEN |=(1<<1);  //开引脚P0_1中断允许
  P1IEN |=(1<<2);  //开引脚P1_2中断允许 
  //P2_0到P2_4的中断允许在P2IEN中的0-4

到此初始化配置寄存器的知识差不多了。

实例代码:

#include"ioCC2530.h"

#define d3 P1_0  //灯3
#define d4 P1_1  //灯4
#define d5 P1_3  //灯5
#define d6 P1_4  //灯6
#define sw1 P1_2 //按钮1
#define sw2 P0_1 //按钮1


#define u8 unsigned char
#define u16 unsigned int

u8 flag=0;

//延时函数1
void delay(u8 t)
{
  u16 i,j;
  while(t--)
  for(i=100;i>0;i--)
  for(j=587;j>0;j--)
  {
    while(flag);
  }
}

//延时函数2
void delayMs(u8 t)
{
  u16 j;
  while(t--)  
  for(j=587;j>0;j--);
}

//初始化函数
void init()
{
  P1SEL &=~(1<<0);
  P1SEL &=~(1<<1);
  P1SEL &=~(1<<4);
  P1SEL &=~(1<<3);
  P1DIR |=(1<<0);
  P1DIR |=(1<<1);
  P1DIR |=(1<<3);
  P1DIR |=(1<<4);
  
  PICTL |=(1<<1);
  PICTL |=(1<<0);
  
  P1IFG=0;   //用于标记P1具体哪一个脚发生中断
  P0IFG=0;   //用于标记P0具体哪一个脚发生中断
  P1IF=0;    //当P1的任意一个脚发生中断则其为1
  P0IF=0;    //当P0的任意一个脚发生中断则其为1
  
  EA=1;//中断总开关
  
  //P0IE=1; 
  IEN1 |=(1<<5);//IEN1中的5是P0IE,0端中断允许
  IEN2 |=(1<<4);//IEN2中的4是P1IE,1端中断允许
  //IEN2中的1是PIE,2端的中断允许
  
  P0IEN |=(1<<1);  //开引脚P0_1中断允许
  P1IEN |=(1<<2);  //开引脚P1_2中断允许 
  //P2_0到P2_4的中断允许在P2IEN中的0-4
 
}

//实现流水灯的函数
void display()
{
    d5=1;d6=0;d3=0;d4=0;delay(10);
    d5=0;d6=1;d3=0;d4=0;delay(10);
    d5=0;d6=0;d3=1;d4=0;delay(10);
    d5=0;d6=0;d3=0;d4=1;delay(10);
}


//主函数
void main()
{
  init();
  while(1)
  {
    display();
  }
}


//P1口的中断服务函数
#pragma vector=P1INT_VECTOR
__interrupt void P1ISR(void)
{
  if(P1IFG &(1<<2))
  {
    delayMs(10);
    if(sw1==0)
    {
      flag=1;
    }
    P1IFG^=(1<<2);
  }
  P1IF=0;
}


//P0口的中断服务函数
#pragma vector=P0INT_VECTOR
__interrupt void P0ISR(void)
{
  if(P0IFG &(1<<1))
  {
    delayMs(10);
    if(sw2==0)
    {
      flag=0;
    }
    P0IFG^=(1<<1);
  }
  P0IF=0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41967600/article/details/89444707