STC8G 8051内核单片机开发 (中断)
⚙️ 一、STC8G中断源列表(共22个)
中断源 | 中断号 | 向量地址 | 触发方式 | 优先级限制 | 标志清除方式 |
---|---|---|---|---|---|
外部中断0 (INT0) | 0 | 0x0003 | 下降沿/低电平 | 可配置 (0-3) | IE0 = 0; (手动清零) |
定时器0中断 (T0) | 1 | 0x000B | 计数器溢出 | 可配置 (0-3) | TF0 = 0; (手动清零) |
外部中断1 (INT1) | 2 | 0x0013 | 下降沿/低电平 | 可配置 (0-3) | IE1 = 0; (手动清零) |
定时器1中断 (T1) | 3 | 0x001B | 计数器溢出 | 可配置 (0-3) | TF1 = 0; (手动清零) |
串口1中断 (UART1) | 4 | 0x0023 | 数据发送/接收完成 | 可配置 (0-3) | RI = 0; TI = 0; (手动清零) |
ADC转换完成中断 | 5 | 0x002B | ADC转换结束 | 可配置 (0-3) | ADC_CONTR &= ~0x20; (写1清除) |
低电压检测中断 (LVD) | 6 | 0x0033 | 电压低于阈值 | 可配置 (0-3) | `PCON |
PCA/CCP/PWM中断 | 7 | 0x003B | 捕获/比较/溢出 | 可配置 (0-3) | CCF0 = 0; (手动清零) |
串口2中断 (UART2) | 8 | 0x0043 | 数据发送/接收完成 | 可配置 (0-3) | RI2 = 0; TI2 = 0; (手动清零) |
SPI中断 | 9 | 0x004B | 数据传输完成 | 可配置 (0-3) | SPSTAT = 0xC0; (写1清除) |
外部中断2 (INT2) | 10 | 0x0053 | 仅下降沿 | 固定优先级0(最低) | 硬件自动清除 |
外部中断3 (INT3) | 11 | 0x005B | 仅下降沿 | 固定优先级0(最低) | 硬件自动清除 |
定时器2中断 (T2) | 12 | 0x0063 | 计数器溢出 | 固定优先级0(最低) | TF2 = 0; (手动清零) |
外部中断4 (INT4) | 13 | 0x0083 | 仅下降沿 | 可配置 (0-3) | 硬件自动清除 |
串口3中断 (UART3) | 14 | 0x008B | 数据发送/接收完成 | 固定优先级0(最低) | RI3 = 0; TI3 = 0; (手动清零) |
串口4中断 (UART4) | 15 | 0x0093 | 数据发送/接收完成 | 固定优先级0(最低) | RI4 = 0; TI4 = 0; (手动清零) |
定时器3中断 (T3) | 16 | 0x009B | 计数器溢出 | 固定优先级0(最低) | TF3 = 0; (手动清零) |
定时器4中断 (T4) | 17 | 0x00A3 | 计数器溢出 | 固定优先级0(最低) | TF4 = 0; (手动清零) |
I²C中断 | 18 | 0x00C3 | 传输完成/地址匹配 | 可配置 (0-3) | I2CMSST = 0; (手动清零) |
💡注:
- 固定优先级0的中断(如INT2/INT3/T2/UART3等)不可被其他中断打断,且自身无法嵌套。
- 电平触发外部中断(INT0/INT1)需确保信号恢复高电平后再清除标志,否则可能重复触发。
🔧 二、中断优先级与嵌套机制
1. 四级优先级配置
STC8G支持4级优先级(0最低,3最高),通过组合 IP(地址 0xB8
)和 IPH(地址 0xB7
)实现:
组合值 | 优先级 |
---|---|
IP.X=0, IPH.X=0 | 0(最低) |
IP.X=1, IPH.X=0 | 1 |
IP.X=0, IPH.X=1 | 2 |
IP.X=1, IPH.X=1 | 3(最高) |
// 设置外部中断0(INT0)为优先级3(最高)
PX0 = 1; // IP.0 = 1
PX0H = 1; // IPH.0 = 1 → 二进制11 = 优先级3// 设置定时器0(T0)为优先级2
PT0 = 0; // IP.2 = 0
PT0H = 1; // IPH.2 = 1 → 二进制10 = 优先级2// 串口1设为优先级1: IP.4=1, IPH.4=0
PS = 1; // IP.4 = 1
PSH = 0; // IPH.4 = 0 → 二进制01 = 优先级1// ADC设为优先级0: IP.5=0, IPH.5=0
PADC = 0; // IP.5 = 0
PADCH = 0; // IPH.5 = 0 → 二进制00 = 优先级0
2. 使能中断
EA = 1; // 总中断使能(必须开启!)
EX0 = 1; // 允许外部中断0
ET0 = 1; // 允许定时器0中断
3. 配置中断触发方式
IT0 = 1; // 设置INT0为下降沿触发(0=低电平触发)
4. 中断嵌套规则
- 高优先级可打断低优先级:若T0(优先级2)正在执行,INT0(优先级3)可中断其流程。
- 同级中断按查询顺序执行:同级中断同时发生时,按中断号从小到大执行(如INT0早于T0)。
- 最低级中断不可嵌套:INT2/INT3/INT4执行时不可被任何中断打断。
⚡ 三、中断服务程序(ISR)编写规范
1. 核心要求
- 短小精悍:ISR中只做关键操作(如设标志、清中断),复杂逻辑交由主循环处理。
- 无返回值/参数:函数声明为
void func() interrupt n [using m]
。 - 避免阻塞操作:禁止使用
printf
、长延时等函数
void ISR_Name() interrupt n [using m]
-
n
:中断号(0~21),不可省略 -
m
:寄存器组编号(0~3),用于避免寄存器冲突(可选) - 执行原则:无参数/返回值,使用
volatile
保护全局变量
2. 关键步骤
以定时器0中断为例:
volatile uint8_t timer_flag = 0; // 全局标志位,用volatile修饰防优化void Timer0_ISR() interrupt 1 {TF0 = 0; // 必须手动清除中断标志TH0 = 0xFC; TL0 = 0x66; // 重装初值(1ms@11.0592MHz)timer_flag = 1; // 通知主循环处理任务
}
3.各中断源标志位清除方法
中断源 | 标志位 | 清除方式 | 注意事项 | C语言示例 |
---|---|---|---|---|
定时器0/1/2/3/4 | TF0 /TF1 /TF2 /TF3 /TF4 | 写0清除 | 定时器溢出中断需立即清除,否则持续触发 | TF0 = 0; |
外部中断0/1 | IE0 /IE1 | 写0清除(部分型号需检测下降沿后清除) | 电平触发时需确保信号已恢复高电平 | IE0 = 0; |
外部中断2/3/4 | IE2 /IE3 /IE4 | 自动清除(响应后硬件清零) | 仅支持下降沿触发,优先级固定为0 | 无需手动清除 |
串口1/2/3/4 | RI /TI | 写0清除 | 接收/发送中断需分别清除 | RI = 0; TI = 0; |
ADC转换完成 | ADC_FLAG | 写1清除(ADC_CONTR &= ~0x20; ) | 需先读取结果再清除标志 | ADC_CONTR &= ~0x20; |
SPI传输完成 | SPIF | 读SPI状态寄存器后写1清除 | 清除前需读取数据寄存器 | SPSTAT = 0xC0; (清SPIF和WCOL) |
I²C中断 | SI | 写0清除(I2CMSST = 0; ) | 需处理状态码后清除 | I2CMSST = 0; |
PWM/CCP中断 | CCF0 /CCF1 | 写0清除 | PCA模块捕获/比较中断 | CCF0 = 0; |
低电压检测(LVD) | LVDF | 写1清除(`PCON | = 0x20;`) | 需在ISR中清除,否则持续唤醒 |
🛠️ 四、常用中断应用实例
1. 外部中断(按键控制电机)
sbit K1 = P3^2; // 按键接INT0(P3.2)
void INT0_ISR() interrupt 0 {EX0 = 0; // 关闭中断防抖动delay_ms(10); // 消抖if(K1 == 0) motor_run(FORWARD); // 执行正转EX0 = 1; // 重启中断
}
2. 定时器中断(5秒自动停电机)
volatile uint16_t count = 0;
void Timer1_ISR() interrupt 3 {TF1 = 0;if(++count >= 5000) { // 5s(中断周期1ms)motor_stop();count = 0;TR1 = 0; // 关闭定时器}
}
// 主循环中按键触发:TR1=1, count=0;
3. ADC中断(实时采集光照)
uint16_t adc_value = 0;
void ADC_ISR() interrupt 5 {ADC_CONTR &= ~0x10; // 清中断标志adc_value = ADC_RES; // 读取结果
}
⚠️ 五、开发注意事项
- 中断初始化流程:
- 配置中断触发方式(如IT0=1:下降沿触发)。
- 使能中断(EX0=1)。
- 设置优先级(可选)。
- 开启总中断(EA=1)。
- 共享变量保护:
- 跨ISR与主循环的全局变量需加
volatile
并关中断操作:EA = 0; // 关中断 temp = sensor_data; // 安全读取 EA = 1; // 开中断
- 跨ISR与主循环的全局变量需加
- 低功耗设计:
- 休眠前启用中断唤醒:
PCON |= 0x01; // 进入空闲模式 while(!timer_flag); // 等待中断唤醒
- 休眠前启用中断唤醒:
📊 六、中断优化技巧
场景 | 优化策略 |
---|---|
高频中断 | ISR内仅设标志,主循环处理逻辑 |
实时性要求高 | 使用最高优先级 + 快速硬件操作(如位操作) |
多中断冲突 | 合理分配优先级,避免同级中断阻塞 |
低功耗应用 | 在ISR中唤醒系统,减少主循环轮询 |
通过合理配置中断系统,STC8G可胜任电机控制、环境监测、多机通信等复杂场景。建议结合STC-ISP工具的 代码生成功能 初始化寄存器,避免手动配置错误。