跳转至

中断系统

中断是单片机处理异步事件的机制,STC89C52 支持 8 个中断源4 级中断优先级

中断源列表

编号 中断源 标志位 向量地址 自然优先级
0 INT0(外部中断 0) IE0 0003H 1(最高)
1 T0(定时器 0) TF0 000BH 2
2 INT1(外部中断 1) IE1 0013H 3
3 T1(定时器 1) TF1 001BH 4
4 UART(串行口) RI/TI 0023H 5
5 T2(定时器 2) TF2 002BH 6
6 INT2(外部中断 2) 0033H 7
7 INT3(外部中断 3) 003BH 8(最低)

STC89C52 比传统 8051 多了 INT2、INT3 等额外中断源

中断优先级

默认优先级(自然优先级)

按上表编号从 0(最高)到 7(最低)。

优先级控制(IP 寄存器 — B8H)

每位置 1 表示对应中断为高优先级。STC89C52 的 4 级优先级由 IP 和 AUXR 共同控制。

中断嵌套规则

  1. 低优先级中断可以被高优先级中断打断
  2. 高优先级中断不会被低优先级中断打断
  3. 同优先级中断不能互相打断(按自然优先级排队)

中断使能控制

IE 寄存器(A8H)

位:   EA     —     ET2    ES    ET1    EX1    ET0    EX0
地址:  D7    D6     D5    D4     D3     D2     D1     D0
功能
EA 总中断使能(1=开,0=关全部)
ET2 定时器 2 中断使能
ES 串行口中断使能
ET1 定时器 1 中断使能
EX1 外部中断 1 使能
ET0 定时器 0 中断使能
EX0 外部中断 0 使能

外部中断配置

STC89C52 提供 4 个外部中断(INT0~INT3),其中 INT0 和 INT1 使用标准引脚,INT2 和 INT3 为 STC 增强功能。

INT0 / INT1

引脚:P3.2 (INT0)、P3.3 (INT1)

触发方式(由 TCON 的 IT0/IT1 位控制): - ITx = 0:低电平触发 - ITx = 1:下降沿触发(推荐,避免抖动误触发)

// 配置 INT0 为下降沿触发
void INT0_Init() {
    IT0 = 1;         // 下降沿触发
    EX0 = 1;         // 使能外部中断 0
    EA  = 1;         // 开总中断
}

// INT0 中断服务函数
void INT0_ISR() interrupt 0 {
    // 按键按下时执行
    // 注意:需要软件消抖
}

外部中断应用:按键检测

volatile bit key_pressed = 0;

void INT0_ISR() interrupt 0 {
    // 简单的硬件消抖延时
    unsigned int i;
    for (i = 0; i < 100; i++);

    // 再次检测引脚状态确认确实有按键按下
    if (INT0_pin == 0) {  // P3.2 为低电平
        key_pressed = 1;
    }
}

中断服务函数编写要点

C51 中的中断函数声明

// 格式:void 函数名() interrupt 中断编号
void Timer0_ISR() interrupt 1 {
    // 定时器 0 中断处理
}

// 使用不同寄存器组(避免中断中与主程序冲突)
void HighPriority_ISR() interrupt 0 using 1 {
    // 使用寄存器组 1(08H~0FH)
}

// 中断 4 需要判断是 RI 还是 TI
void UART_ISR() interrupt 4 {
    if (RI) {
        RI = 0;
        // 接收处理
    }
    if (TI) {
        TI = 0;
        // 发送处理
    }
}

中断函数注意事项

  1. 尽量简短 — 中断中执行耗时操作会阻塞其他中断
  2. 使用 volatile — 中断和主循环共享的变量必须加 volatile
  3. 保护共享变量 — 必要时在中断中禁中断
  4. 定时器中断中手动重载(非自动重载模式)
  5. 串口中断要判断 RI 和 TI
  6. 定时器 2 中断需软件清零 TF2
// 中断安全共享变量
volatile unsigned int system_tick = 0;
volatile bit data_ready = 0;

void Timer0_ISR() interrupt 1 {
    TH0 = 0xFC;      // 重载
    TL0 = 0x18;
    system_tick++;   // 每 1ms 递增
}

中断响应时间

  • 最快响应:3 个机器周期
  • 最慢响应:8 个机器周期(遇到正在执行的 RETI 或访问 IE/IP 的指令时)
  • 12MHz 晶振下,3~8μs 的响应延迟

中断应用场景

外设 中断用途 优先级建议
定时器 精确定时、PWM、系统时基
外部中断 按键、传感器触发信号 中~高
串口 数据接收通知
看门狗 系统异常复位 极高(硬件级)