3. 中断系统与外部中断

任务目标

在ADI SHARC处理器上配置一个外部中断引脚,连接按键输入。当按键按下时触发中断服务程序(ISR),在ISR中翻转LED的亮灭状态,实现按键中断控制LED的完整闭环。

硬件连接与原理

  • 按键接至处理器的外部中断引脚(本例使用IRQ2/PF2,具体引脚号以目标板原理图为准),按下时产生下降沿;
  • LED接至通用IO引脚(本例使用PF10),输出高电平点亮;
  • 外部中断配置为边沿触发(下降沿),使能中断控制器中的对应中断源;
  • ISR中仅执行LED翻转操作,中断返回后主程序继续运行。

完整代码实现

/* 外部中断按键控制LED - SHARC处理器 */
#include <def21369.h>      /* 处理器寄存器定义 */
#include <intdef.h>         /* 中断向量宏定义 */

/* LED与按键引脚定义 */
#define LED_PIN     10      /* PF10 - LED输出 */
#define KEY_PIN     2       /* PF2  - 按键输入(外部中断) */

/* 全局LED状态标志 */
volatile int led_state = 0;

/* 中断服务程序:翻转LED状态 */
EX_INTERRUPT_HANDLER(Key_ISR)
{
    led_state = !led_state;
    if (led_state) {
        *pIOFLAG_SET = (1 << LED_PIN);   /* 置位PF10 */
    } else {
        *pIOFLAG_CLR = (1 << LED_PIN);   /* 清零PF10 */
    }
}

void main(void)
{
    /* 1. 配置LED引脚为输出 */
    *pIOFLAG_DIR = (1 << LED_PIN);        /* PF10设为输出 */
    *pIOFLAG_CLR = (1 << LED_PIN);        /* 初始LED灭 */

    /* 2. 配置按键引脚为输入,并使能内部上拉 */
    *pIOFLAG_DIR &= ~(1 << KEY_PIN);      /* PF2设为输入 */
    *pIOFLAG_EDGE = (1 << KEY_PIN);       /* 边沿敏感 */
    *pIOFLAG_POL = 0;                      /* 下降沿触发 */

    /* 3. 注册中断服务程序 */
    register_handler(IRQ2, Key_ISR);

    /* 4. 使能外部中断 */
    *pINTCTL |= (1 << IRQ2_ENABLE);        /* 使能IRQ2中断源 */

    /* 5. 使能全局中断 */
    asm("bit set mode1 0x0020");           /* IRPTEN置1 */

    while (1) {
        /* 主循环空转,等待按键中断 */
        asm("nop;");
    }
}

编译与运行

  1. 在VisualDSP++或CCES中新建SHARC工程,将上述代码保存为ext_int.c并加入工程;
  2. 根据实际处理器型号选择芯片(如ADSP-21369),编译生成.dxe可执行文件;
  3. 通过仿真器(ICE或JTAG)下载程序到目标板,或加载到模拟器中运行。

验证方法与通过条件

  • 初始状态:程序运行后LED处于熄灭状态;
  • 按键触发:按下按键并释放,每次按下应产生一次下降沿中断,LED状态翻转一次(灭→亮→灭→亮…);
  • 防抖说明:本示例未做软件防抖,若实际按键存在机械抖动导致一次按下多次翻转,可在ISR中加入约10ms延时或使用定时器消抖(非本案例核心,不展开);
  • 判定标准:每按一次按键,LED亮灭状态切换一次,且主循环空转不受影响,即判定中断配置与ISR执行正确。

关键寄存器说明

寄存器作用
IOFLAG_DIRIO方向配置,1=输出,0=输入
IOFLAG_EDGE边沿/电平敏感选择
IOFLAG_POL触发极性:0=下降沿,1=上升沿
INTCTL中断控制器使能寄存器
IOFLAG_SET/CLR置位/清零IO输出

注意:不同SHARC型号的寄存器名称和中断号可能略有差异,请以目标芯片的def头文件为准。若使用ADSP-214xx系列,外部中断引脚和寄存器映射需相应调整。