任务分析
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端口标志位
任务分析
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端口标志位
举报