3. 外部中断控制LED
任务说明
本案例基于TI CC2530开发板,将按键S1(连接P1_0引脚)配置为外部中断输入,LED1(连接P1_1引脚)作为输出指示。当按键按下时触发外部中断,在中断服务函数中翻转LED1的亮灭状态。通过本案例掌握CC2530外部中断的配置流程、中断服务函数的编写方法以及中断标志的清除操作。
硬件连接
- 按键S1一端接P1_0,另一端接GND(按下为低电平)
- LED1阳极经限流电阻接P1_1,阴极接GND(高电平点亮)
实现原理
CC2530的P1端口每个引脚均可独立配置为外部中断输入。将P1_0配置为输入模式并使能其上拉电阻,同时将P1中断使能寄存器P1IEN的bit0置1,PICTL寄存器bit0设为0(下降沿触发)。当按键按下产生下降沿时,P1IFG的bit0被硬件置1,P1IF中断标志置位,CPU响应中断进入中断服务函数。在ISR中翻转P1_1输出状态,并清除P1IFG和P1IF标志位,防止重复触发。
代码实现
#include <iocc2530.h>
#define LED1 P1_1
#define KEY P1_0
/* 端口初始化 */
void initPort(void)
{
P1SEL &= ~0x03; // P1_0、P1_1设为通用IO
P1DIR |= 0x02; // P1_1输出
P1DIR &= ~0x01; // P1_0输入
P1INP &= ~0x01; // P1_0设置为带上拉/下拉
P2INP &= ~0x40; // P1端口选择上拉模式
P1_1 = 0; // LED初始熄灭
}
/* 外部中断初始化 */
void initExtInt(void)
{
PICTL &= ~0x01; // P1_0下降沿触发
P1IEN |= 0x01; // 使能P1_0中断
P1IFG = 0x00; // 清除中断标志
IEN2 |= 0x10; // 使能P1端口中断
EA = 1; // 全局中断使能
}
/* P1端口中断服务函数 */
#pragma vector = P1INT_VECTOR
__interrupt void P1_ISR(void)
{
if (P1IFG & 0x01) // 判断是否为P1_0触发
{
P1_1 = ~P1_1; // 翻转LED状态
P1IFG = 0x00; // 清除P1_0中断标志
}
P1IF = 0; // 清除P1端口中断标志
}
void main(void)
{
initPort();
initExtInt();
while (1)
{
// 主循环空操作,等待中断
}
}
代码说明
initPort函数完成引脚方向与上下拉配置,P1INP和P2INP配合将P1_0设置为上拉输入,确保按键未按下时引脚为高电平。initExtInt函数配置中断触发方式为下降沿,使能P1_0中断和P1端口总中断。中断服务函数中先判断P1IFG的bit0是否为1,确认是按键触发后翻转LED,随后清除P1IFG和P1IF标志。主循环为空操作,程序运行后等待中断事件。
编译与烧录
使用IAR Embedded Workbench for 8051创建工程,新建main.c文件并粘贴上述代码。工程配置中选择芯片型号为CC2530F256,在编译器选项中加入__near_func关键字支持(若IAR版本需要)。编译通过后生成hex文件,通过CC Debugger和SmartRF Flash Programmer烧录到开发板。
验证方法
烧录完成后,开发板上电。观察LED1初始状态为熄灭。用手指按下按键S1并松开,每次按下时LED1状态应发生翻转(熄灭变点亮或点亮变熄灭)。连续快速按动按键,LED1应跟随每次按键动作同步切换,无延迟或漏触发现象。若LED状态正确翻转且无异常闪烁,则判定本案例验证通过。
中断标志清除要点
中断服务函数中必须同时清除P1IFG对应位和P1IF标志。P1IFG是端口中断标志寄存器,用于指示具体哪个引脚触发了中断;P1IF是P1端口中断汇总标志,位于IRCON寄存器中。若只清除P1IFG而不清除P1IF,CPU将反复进入中断导致程序卡死。清除操作应在判断完触发源之后执行,避免误清除其他引脚的中断请求。