STC15系列MCU —— IAP15W4K58S4 外部中断 编程笔记
假如需要检测一个按键是否按下,如果用查询方式在主循环中检测按键所在IO口的状态会消耗很多CPU的资源,而且当程序很大的时候可能会丢失持续时间短的事件,因此就有了中断,CPU不用时刻去查询引脚的电平状态,只有当引脚电平发生跳变的时候才会触发中断,此时CPU跳转到中断服务函数,去执行特定的业务代码。
下面分享STC15系列 MCU —— IAP15W4K58S4 外部中断的代码编写笔记
1.外部中断初始化
这个型号的单片机有 5 路外部中断,前 2 路—— INT0 ~ INT1 可以选择中断源类型,可以设置中断优先级,还有中断请求标志位,比较“高级”,后 3 路—— INT2 ~ INT4 则没有这 3 个功能,比较“低级”。
1.1 对于“高级外部中断”的初始化 —— INT0 和 INT1
配置“高级外部中断”需要操作的寄存器都可位寻址,所以可以直接对某个位操作,编程时不需要查询各 bit 的定义
清除中断请求标志位(IE —— Interrupt Enquiry ——位于 定时器&计数器中断控制寄存器(TCON))
程序运行过程中不需要用户管理:该位在有中断请求时会硬件置 1,中断响应完成后会硬件清 0
初始化时让 IE0 = 0 / IE1 = 0 (稳妥起见手动赋值,不进行该操作也不会有啥问题——上电复位默认为0)
选择中断源类型(IT —— Interrupt Type ——位于定时器&计数器中断控制寄存器(TCON))
IT0 = 1 / IT1 = 1 时,外部中断引脚检测到 下降沿电平 触发外部中断
IT0 = 0 / IT1 = 0 时,外部中断引脚检测到 上升沿电平或者下降沿电平 都能触发外部中断
设置中断优先级(PX —— Priority Of External Interrupt ——位于中断优先级控制寄存器(IP))
PX0 = 0 / PX1 = 0,配置 INT0 / INT1 为最低优先级
PX0 = 1 / PX1 = 1,配置 INT0 / INT1 为最高优先级
使能外部中断(EX —— External ——位于中断允许寄存器(IE))
让 EX0 = 1 / EX1 = 1 以使能 外部中断0(EXINT0)/ 外部中断1(EXINT1)
使能总中断(EA —— Enable All ——位于中断允许寄存器(IE))
让 EA = 1 以开启总中断
总中断相当于中断的总开关
1.2 对于“低级的外部中断”—— INT2 和 INT3 和 INT4
由于“低级的外部中断”的寄存器有的不支持位寻址,因此编程时要查询寄存器各 bit 的定义
没有中断请求标志位,不能选择中断类型,不能配置中断优先级(datasheet上这么说,但 EXINT4 有点特殊)
使能外部中断(EX——External——位于外部中断允许和时钟输出寄存器(INT_CLKO)(AUXR2))
该寄存器不可位寻址,需要对整个寄存器进行操作
让 EX2 = 1 / EX3 = 1 / EX4 = 1 以使能 外部中断2(EXINT2)/外部中断3(EXINT3)/ 外部中断4(EXINT4)
使能总中断(EA —— Enable All ——位于中断允许寄存器(IE))
让 EA = 1 以开启总中断(该步骤与操作“高级的外部中断”时一致)

2. 中断服务函数的编写
格式:void (函数名)(void) interrupt (中断服务号定义)
函数名可以任写
中断服务号参考 STC15 各中断服务号定义,从中选择对应的中断,中断服务号可以在头文件中找到
头文件中的中断服务号宏定义
3.对于 EXINT4 优先级的碎碎念
datasheet中提到 EXINT4 的优先级固定为最低,但是 IP2 寄存器中存在控制 EXINT4 中断优先级的位,两者矛盾。

进行了实验得出了如下结果
EXINT0 设置为最低优先级, EXINT4 设置为最高优先级时:双方都无法打断对方的中断服务函数
两个都设置为最高优先级时:双方都无法打断对方中断服务函数
EXINT0 设置为最高优先级,EXINT4 设置为最低优先级时:EXINT0 的中断服务函数可以打断 EXINT4的中断服务函数,但是 EXINT4 的中断服务函数无法打断 EXINT0 的中断服务函数
结论:
EXINT4 配置为最低优先级时,与其他“低级外部中断”的效果一致
EXINT4 配置为最高优先级时,可以不被任何外部中断打断,但是也无法打断 EXINT0 和 EXINT1 的中断服务函数,