不同的51单片机中断源可能有所不同。一样平常51单片机至少有 5个中断:外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断。
而STC89C51RC/RD+ 的系列单片机供应了8个中断要求源,分别是:

在 中颖的SH79F6442中,供应了27个中断源,个中有5个外部中断、3个定时器中断,其余还有4个PCA中断、4个EUART中断、系统时钟监控中断、1个SPI中断、ADC中断、3路PWM中断、LED中断、TWI中断、CRC中断、LPD中断。
2. 中断的优先级51单片机中,不同中断源之间存在优先级关系,当多个中断同时发生时,优先级高的中断会先得到相应。可以通过设置中断优先级和中断许可位来掌握不同中断源之间的优先级和许可状态。下图是来自《STC89Cxx中文参考手册.pdf》 里的中断解释:
3. 中断构造下图也是摘自《STC89Cxx中文参考手册》,其构造
上图的解读,整体因此列的办法从左往右看,数据从最左侧是中断源,经由中断许可掌握寄存器(开关),到中断优先级掌握寄存器,再流向处理程序。
靠上的中断优先级更高。
4. 外部中断解读INT0对应P3.2引脚INT1对应P3.3引脚中断旗子暗记通报流程:
INT0 中断旗子暗记通过IT0(TCON掌握寄存器第0位)引脚,来选择触发办法(0:低电平触发或 1:低落沿触发);触发中断后,将IE0(TCON寄存器第1位,中断标志)置1;判断EX0(IE中断许可寄存器第0位)如果是1,便是INT0使能,中断可以连续向后通报;如果全局总中断EA(IE中断许可寄存器第7位)打开,中断可以连续通报;中断优先级掌握寄存器IP判断哪个中断先触发;触发CPU的中断做事函数。从上面的流程可以看出,IE.EX0纵然失落能状态,也可以通过TCON.IE0读取中断旗子暗记。
外部中断INT1对应P3.3引脚,事情流程与INT0类似。
5. 定时器中断T0对应 P3.4引脚T1对应 P3.5 引脚有计数旗子暗记进入T0;计数溢出时,触发 TF0(TCON计数器寄存器,TF0溢出中断标志);如果ET0(IE中断第1位,T0的溢出中断许可位),连续通报;如果全局总中断EA(IE中断许可寄存器第7位)打开,连续通报;中断优先级掌握器IP判断优先级;触发CPU中断做事函数。6. 串口中断RX 对应 P3.0引脚TX 对应 P3.1 引脚当吸收到数据或发送完成时,串口硬件会设置RI/TI标志位,表示吸收到了数据;如果 ES(IE寄存器的第4位,串行口中断许可位)被设置,许可串口中断连续通报;如果全局总中断 EA(IE寄存器的第7位,全局中断许可位)被打开,则许可中断连续通报;中断优先级掌握器IP判断优先级;触发中断做事函数;三、中断干系寄存器1. IE 中断许可寄存器IE 地址为 A8H,格式如下:
位
编号
浸染
EA
7
全局中断许可位
–
6
无效位,保留
ET2
5
定时器/计数器2中断许可位
ES
4
串行口中断许可位
ET1
3
定时器/计数器1中断许可位
EX1
2
外部中断1许可位
ET0
1
定时器/计数器0中断许可位
EX0
0
外部中断0许可位
2. TCON 中断要求标志位
编号
浸染
TF1
7
定时器/计数器1溢出标志位
TR1
6
定时器/计数器1运行掌握位
TF0
5
定时器/计数器0溢出标志位
TR0
4
定时器/计数器0运行掌握位
IE1
3
外部中断1标志位
IT1
2
外部中断1触发办法选择位
IE0
1
外部中断0标志位
IT0
0
外部中断0触发办法选择位
3. IP 中断优先级位
编号
浸染
–
7
无效位,保留
PT2
6
定时器/计数器2中断优先级位
PS
5
串行口中断优先级位
PT1
4
定时器/计数器1中断优先级位
PX1
3
外部中断1优先级位
PT0
2
定时器/计数器0中断优先级位
PX0
1
外部中断0优先级位
–
0
无效位,保留
这里对寄存器大略先容,更详细地解释可以参考本文对应的开源代码里的《STC89Cxx中文参考手册》。
四、中断号下面是关于中断号的解释:
中断号
描述
0
外部中断0
1
定时器/计数器0 溢出中断
2
外部中断1
3
定时器/计数器1 溢出中断
4
串行口通信中断
5
定时器/计数器2 溢出中断
6-7
保留
五、代码实现硬件连接:
按键 :LED:
个中按键3是在P3.2引脚,中断0。
1. 按键事宜切换LED亮的状态key_utils.c#include "key_utils.h"#include <reg52.h>#include "common_utils.h"sbit KEY3 = P3^2;sbit LED1 = P2^0;/ @brief 按键中断初始化 /void key3_init(void){ IT0 = 1; // 低落沿触发 EX0 = 1; // 开启外部中断0 EA = 1; // 开启总中断 }void exti0() interrupt 0{ delay_10us(500); if(KEY3 == 0){ LED1 = !LED1; }}main.c
#include <reg52.h>#include "led_utils.h"#include "common_utils.h"#include "key_utils.h"#include "types.h"/ @brief 主函数/main(){// 关闭所有ledled_all_off();key3_init();while(1){}}六、定时/计数器构造
T0:P3.4T1:P3.5 引脚TMOD:定时器的事情模式TCON:低4位掌握外部中断,高4位用于定时器掌握位1. 寄存器先容TMOD
TMOD用于掌握定时器/计数器的事情模式和计数办法,寄存器各位功能:
Bit: 7 6 5 4 3 2 1 0 ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ GATE │ C/T │ M1 │ M0 │ GATE │ C/T │ M1 │ M0 │ └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘ T1 T1 T0 T0 T1 T1 T0 T0
TMOD 寄存器各位的功能:分成2组,高4位、低4位,分别掌握定时器1、定时器0的事情模式。
位7:GATE1(定时器1门控位):当 GATE1 为 1 时,定时器1的计数/定时事情由外部引脚掌握。当 GATE1 为 0 时,定时器1的计数/定时事情受到内部掌握。位6:C/T1(定时器1计数/定时选择位):当 C/T1 为 0 时,定时器1为定时器模式;当 C/T1 为 1 时,定时器1为计数器模式。位5-4:M11 和 M10(定时器1事情模式位):用于设置定时器1的事情模式,共有四种事情模式,分别为:00:13位定时器模式01:16位定时器模式10:8位自动重装载定时器模式11:两个8位定时器/计数器分开事情位3:GATE0(定时器0门控位):与位7相似,用于掌握定时器0的门控功能。位2:C/T0(定时器0计数/定时选择位):与位6相似,用于设置定时器0的事情模式。位1-0:M01 和 M00(定时器0事情模式位):与位5-4相似,用于设置定时器0的事情模式。TCONTCON 用于掌握定时器/计数器的事情状态和中断标志位,各位功能:
Bit: 7 6 5 4 3 2 1 0 ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ TF1 │ TR1 │ TF0 │ TR0 │ IE1 │ IT1 │ IE0 │ IT0 │ └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
TCON 寄存器各位的功能:
位7:TF1(定时器1溢出标志位):当定时器1溢出时,TF1 置1,表示定时器1计数达到最大值并溢出。如果不该用中断,也可以通过查询知道是否溢出。位6:TR1(定时器1运行掌握位):当 TR1 置1 时,定时器1开始事情;当 TR1 清0 时,定时器1停滞事情。位5:TF0(定时器0溢出标志位):当定时器0溢出时,TF0 置1,表示定时器0计数达到最大值并溢出。位4:TR0(定时器0运行掌握位):当 TR0 置1 时,定时器0开始事情;当 TR0 清0 时,定时器0停滞事情。位3:IE1(外部中断1标志位):外部中断1的中断标志位,当外部中断1触发时,IE1 置1。位2:IT1(外部中断1触发办法选择位):外部中断1的触发办法选择位,掌握外部中断1的触发办法。位1:IE0(外部中断0标志位):外部中断0的中断标志位,当外部中断0触发时,IE0 置1。位0:IT0(外部中断0触发办法选择位):外部中断0的触发办法选择位,掌握外部中断0的触发办法。2. 定时器/计数器事情办法0(1)事情特点也称为13位定时器模式,构造图如下:
其特点是:
定时器/计数器的计数范围为0到8191(2^13-1)。该模式下,定时器/计数器每计数一次,计数值加1,直到达到最大计数值(8191),然后溢出并重新从0开始计数。计数由TL0的低5位和TH0的高8位组成,低5位溢出时向TH0进位,TH0 溢出时,TCON.TF0 置位。
(2)门控位解释门控位GATE是0的时候,经由一个非门、或门、与门,定时器可以由 TR0掌握。当GATE是1的时候,定时器由INT0 引脚掌握。(3)C/T掌握计数还是定时模式,即开关:
3. 事情办法1事情办法1称为16位定时器模式:
定时器/计数器的计数范围为0到65535(2^16-1)。该模式下,定时器/计数器每计数一次,计数值加1,直到达到最大计数值(65535),然后溢出并重新从0开始计数。4. 事情办法2也称为8位自动重装载定时器模式,定时器/计数器的计数范围为0到255(2^8-1)。该模式下,定时器/计数器每计数一次,计数值加1,当计数值达到最大值(255)时,自动重新加载初始计数值。自动重新装载,是将TH0装载到TL0。5. 事情办法3
事情办法只适应用于T0,也称为两个8位定时器/计数器分开事情模式,其特点:
两个8位定时器/计数器分开事情,分别为定时器0和定时器1,每个定时器/计数器的计数范围为0到255(2^8-1)。可以独立掌握每个定时器/计数器的事情模式、计数办法和中断功能。七、定时器代码实现1. 定时器配置步骤选择定时器选择事情模式设置定时器初值选择时钟源中断使能TR0或TR1置位,启动定时器中断处理2. 计时器初值打算利用开源仓库里的51定时器打算工具打算,晶震频率根据开拓板实际频率填写。
3. 示例本示例每秒LED闪烁一次:
timer_utils.c#include "timer_utils.h"#include <reg51.h>#include "types.h"sbit LED1 = P2^0;/ @brief 定时器 0 初始化函数/void timer1_init(void){ // 选择为定时器 0 模式,事情办法 1 TMOD |= 0X01; // 给定时器赋初值,定时 1ms TH0 = 0XFC; TL0 = 0X66; // 打开定时器 0 中断许可 ET0 = 1; // 打开总中断 EA = 1; // 打开定时器 TR0 = 1;}// 定义静态变量 istatic u16 i;/ @brief 定时器 0 中断函数/void timer1() interrupt 1 {// 定时看重新赋初值,定时 1ms TH0 = 0XFC; TL0 = 0X66; i++; if(i == 1000) { i =0 ; LED1 = !LED1; }}main.c
#include <reg52.h>#include "led_utils.h"#include "common_utils.h"#include "types.h"#include "timer_utils.h"/ @brief 主函数/main(){// 关闭所有ledled_all_off();time0_init();while(1){}}
本文代码开源地址:https://gitee.com/xundh/learn51










