首先先来了解一下相关知识。。
按键相关基础知识:
在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;
}