51单片机中断系统详解
目录
中断的基本概念
什么是中断
CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理(中断发生),那么CPU就会暂停当前的工作(A事件),去执行B事件(中断响应和中断服务),然后B事件做完之后,再回到原来的事件(A事件)中继续工作。(中断的返回)。
中断的作用与优势
随着计算机技术的应用,人们发现中断技术不仅解决了快速主机与I/O设备的数据传送问题,而且还有具有如下的优点:
- 分时操作:CPU可以分时为多个I/O设备服务,提高了计算机的利用率。
- 实时操作:CPU能够及时处理应用系统的随机事件,系统的实时性大大增强。
- 可靠性高:CPU具有处理设备故障及掉电等突发性事件能力,从而使系统可靠性更高。
51单片机的中断源
- 外部中断0 (INT0)
- 外部中断1 (INT1)
- 定时器/计数器0溢出中断
- 定时器/计数器1溢出中断
- 串行口中断
中断优先级
51单片机的中断优先级机制
51单片机支持多个中断源,每个中断源都有其特定的功能和用途。以下是常见的51单片机中断源及其对应的中断向量地址:
中断源 | 描述 | 中断向量地址 | 特殊功能寄存器 (SFR) |
---|---|---|---|
外部中断0 (INT0) | 外部硬件引脚P3.2上的下降沿或低电平触发 | 0003H | IE (Interrupt Enable) 寄存器, TCON (Timer/Counter Control) 寄存器 |
定时器0溢出中断 (TF0) | 定时器0计数溢出时触发 | 000BH | IE 寄存器, TCON 寄存器 |
外部中断1 (INT1) | 外部硬件引脚P3.3上的下降沿或低电平触发 | 0013H | IE 寄存器, TCON 寄存器 |
定时器1溢出中断 (TF1) | 定时器1计数溢出时触发 | 001BH | IE 寄存器, TCON 寄存器 |
串行口中断 (RI/TI) | 串行口接收或发送完成时触发 | 0023H | IE 寄存器, SCON (Serial Control) 寄存器 |
中断源的配置
每个中断源都需要通过特殊功能寄存器(SFR)进行配置,以启用或禁用相应的中断。主要的SFR包括:
- IE (Interrupt Enable) 寄存器:用于全局使能和个别中断源的使能。
- TCON (Timer/Counter Control) 寄存器:用于控制定时器和外部中断的状态。
- SCON (Serial Control) 寄存器:用于控制串行通信的状态。
例如,要启用外部中断0 (INT0),可以在程序中添加以下代码:
// 全局中断使能
EA = 1;
// 使能外部中断0
EX0 = 1;
设置和修改中断优先级的方法
中断优先寄存器 IP
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | / | / | / | PS | PT1 | PX1 | PT0 | PX0 |
IP寄存器用于设置每个中断源的优先级。IP寄存器的地址是B8H
,其各位定义如下:
位 | 描述 | 默认值 | 功能 |
---|---|---|---|
PS | 串行口中断 (RI/TI) 的优先级 | 0 | 0=低优先级, 1=高优先级 |
PT1 | 定时器1 (TF1) 的优先级 | 0 | 0=低优先级, 1=高优先级 |
PX1 | 外部中断1 (INT1) 的优先级 | 0 | 0=低优先级, 1=高优先级 |
PT0 | 定时器0 (TF0) 的优先级 | 0 | 0=低优先级, 1=高优先级 |
PX0 | 外部中断0 (INT0) 的优先级 | 0 | 0=低优先级, 1=高优先级 |
示例代码
以下是如何在程序中配置IP寄存器的示例代码:
#include <reg51.h>
void main() {
// 将外部中断0 (INT0) 设置为高优先级
IP |= 0x01; // 设置 PX0 位为 1
// 将定时器0 (TF0) 设置为高优先级
IP |= 0x04; // 设置 PT0 位为 1
// 将外部中断1 (INT1) 设置为低优先级
IP &= ~0x02; // 清除 PX1 位
// 将定时器1 (TF1) 设置为低优先级
IP &= ~0x08; // 清除 PT1 位
// 将串行口中断 (RI/TI) 设置为低优先级
IP &= ~0x10; // 清除 PS 位
// 其他初始化代码...
}
高优先级中断抢占低优先级中断
- 高优先级中断可以抢占低优先级中断:如果当前正在处理一个低优先级中断,而此时发生了高优先级中断,CPU会暂停当前的低优先级中断服务程序(ISR),转而处理高优先级中断。
- 同级中断不能相互抢占:如果两个中断源具有相同的优先级,那么先发生的中断会被优先处理,后发生的中断需要等待前一个中断处理完毕后才能被响应。
- 嵌套中断:在某些情况下,可以允许中断嵌套,即在一个中断服务程序中再次进入另一个中断。这通常需要手动管理中断标志位和返回状态。
中断使能与禁止
中断允许寄存器 IE
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | EA | / | / | ES | ET1 | EX1 | ET0 | EX0 |
位 | 描述 | 默认值 | 功能 |
---|---|---|---|
EA | 全局中断使能 | 0 | 0=禁止所有中断, 1=允许所有已使能的中断 |
ES | 串行口中断 (RI/TI) 使能 | 0 | 0=禁止串行口中断, 1=允许串行口中断 |
ET1 | 定时器1 (TF1) 中断使能 | 0 | 0=禁止定时器1中断, 1=允许定时器1中断 |
EX1 | 外部中断1 (INT1) 使能 | 0 | 0=禁止外部中断1, 1=允许外部中断1 |
ET0 | 定时器0 (TF0) 中断使能 | 0 | 0=禁止定时器0中断, 1=允许定时器0中断 |
EX0 | 外部中断0 (INT0) 使能 | 0 | 0=禁止外部中断0, 1=允许外部中断0 |
示例代码
#include <reg51.h>
void main() {
// 启用全局中断
EA = 1;
// 启用外部中断0 (INT0)
EX0 = 1;
// 启用定时器0 (TF0) 中断
ET0 = 1;
// 禁用外部中断1 (INT1)
EX1 = 0;
// 禁用定时器1 (TF1) 中断
ET1 = 0;
// 禁用串行口中断 (RI/TI)
ES = 0;
// 其他初始化代码...
}
定时器中断
定时器/计数器的工作原理
STC89C5X 单片机内有两个可编程的定时/计数器 T0、T1 和一个特殊功能定
时器 T2。定时/计数器的实质是加 1 计数器(16 位),由高 8 位和低 8 位两
个寄存器 THx 和 TLx 组成。它随着计数器的输入脉冲进行自加 1,也就是每来一
个脉冲,计数器就自动加 1,当加到计数器为全 1 时,再输入一个脉冲就使计数
器回零,且计数器的溢出使相应的中断标志位置 1,向 CPU 发出中断请求(定时
/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;
如果工作于计数模式,则表示计数值已满。可见,由溢出时计数器的值减去计数
初值才是加 1 计数器的计数值。
上图中的 T0 和 T1 引脚对应的是单片机 P3.4 和 P3.5 管脚。51 单片机定时/
计数器的工作由两个特殊功能寄存器控制。
- TMOD 是定时/计数器的工作方式寄存器,确定工作方式和功能;
- TCON 是控制寄存器,控制 T0、 T1 的启动和停止及设置溢出标志。
工作方式寄存器TMOD
TMOD寄存器用于配置定时器/计数器的工作模式。TMOD寄存器的地址是89H
,其各位定义如下:
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
TMOD 寄存器功能表
位 | 定时器0 | 定时器1 |
---|---|---|
GATE | 门控位(定时器0) | 门控位(定时器1) |
C/T | 定时/计数选择位(定时器0) | 定时/计数选择位(定时器1) |
M1 | 工作模式选择位(定时器0) | 工作模式选择位(定时器1) |
M0 | 工作模式选择位(定时器0) | 工作模式选择位(定时器1) |
工作模式说明
模式 | M1 M0 | 描述 | 定时器0 | 定时器1 |
---|---|---|---|---|
模式0 | 00 | 13位定时器/计数器。定时器使用THx的高5位和TLx的低8位,共13位。 | 支持 | 支持 |
模式1 | 01 | 16位定时器/计数器。定时器使用THx和TLx的全部16位。 | 支持 | 支持 |
模式2 | 10 | 8位自动重装载定时器/计数器。定时器使用TLx的8位,THx作为重装载值。 | 支持 | 支持 |
模式3 | 11 | 分裂模式(仅适用于定时器0)。定时器0被拆分为两个独立的8位定时器。 | 支持 | 不支持 |
详细解释
-
GATE (门控位):
- 0:定时器仅由
TRx
位控制。 - 1:定时器由
INTx
引脚和TRx
位共同控制。只有当INTx
引脚为高电平且TRx
为1时,定时器才开始计数。
- 0:定时器仅由
-
C/T (定时/计数选择位):
- 0:定时器模式,定时器通过内部时钟源进行计数。
- 1:计数器模式,定时器通过外部引脚(T0或T1)上的电平变化进行计数。
-
M1, M0 (工作模式选择位):
- 00:模式0,13位定时器/计数器。
- 01:模式1,16位定时器/计数器。
- 10:模式2,8位自动重装载定时器/计数器。
- 11:模式3,分裂模式(仅适用于定时器0)。
控制寄存器 TCON
TCON 的低 4 位用于控制外部中断。TCON 的高 4 位用于控制定
时/计数器的启动和中断申请。其格式如下:
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | TF1 | TR1 | TF0 | TR0 |
-
TF1 (定时器1溢出标志):
- 0:定时器1未溢出。
- 1:定时器1已溢出,需要在中断服务程序中手动清除该标志位。
-
TR1 (定时器1运行控制位):
- 0:定时器1停止计数。
- 1:定时器1开始计数。
-
TF0 (定时器0溢出标志):
- 0:定时器0未溢出。
- 1:定时器0已溢出,需要在中断服务程序中手动清除该标志位。
-
TR0 (定时器0运行控制位):
- 0:定时器0停止计数。
- 1:定时器0开始计数。
示例代码
#include <REGX52.H>
#include <INTRINS.H>
unsigned char keyNum;
void Timer0Init(void){
//为了不干扰定时器1
//TMOD &= 0xF0; //设置定时器模式
//TMOD |= 0x01; //设置定时器模式
TMOD = 0x01;
//TL0低8位,TH0高8位
TL0=64535%256+1;
TH0=64535/256;
//距离65535差1000,一次1us,1000次就是1ms
//TCON配置
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//中断配置
ET0=1; //enable time0 interrupt
EA=1; //enable global interrupt switch
PT0=0;//低优先级
}
void main()
{
P2=0xFE;
Timer0Init();
while(1)
{
}
}
void Timer0_Routine() interrupt 1{
static unsigned int c = 0;
TL0=64535%256+1;
TH0=64535/256;
c++;
//500ms
if(c>=500){
c=0;
//循环左移
P2=_crol_(P2,1); //LED输出
}
}
外部中断
外部中断的工作模式
51单片机支持两个外部中断源:外部中断0 (INT0) 和外部中断1 (INT1)。外部中断可以通过外部引脚(P3.2和P3.3)上的电平变化或边沿信号来触发。
通过配置TCON (Timer/Counter Control) 寄存器中的IT0
和IT1
位,可以选择外部中断的触发方式。
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
位 | 描述 | 默认值 | 功能 |
---|---|---|---|
IE1 | 外部中断1触发标志 | 0 | 0=未触发, 1=已触发(需手动清除) |
IT1 | 外部中断1触发方式选择 | 0 | 0=电平触发, 1=边沿触发 |
IE0 | 外部中断0触发标志 | 0 | 0=未触发, 1=已触发(需手动清除) |
IT0 | 外部中断0触发方式选择 | 0 | 0=电平触发, 1=边沿触发 |
- IE0 和 IE1:外部中断触发标志位,由硬件自动设置,需要在中断服务程序中手动清除。
- IT0 和 IT1:外部中断触发方式选择位,用于选择电平触发或边沿触发。
边沿触发与电平触发的区别
特性 | 边沿触发 | 电平触发 |
---|---|---|
触发条件 | 下降沿(高到低) | 低电平 |
触发次数 | 一次边沿变化触发一次中断 | 只要引脚保持低电平,中断会持续触发 |
抗干扰能力 | 较强,适合快速脉冲信号 | 较弱,容易受到噪声影响 |
应用场景 | 按键检测、脉冲计数 | 长时间低电平信号检测 |
优点与缺点
-
边沿触发:
- 优点:抗干扰能力强,适合检测快速变化的信号,如按键按下或释放。
- 缺点:对边沿信号的精确度要求较高,可能会错过短脉冲。
-
电平触发:
- 优点:适用于长时间低电平信号的检测,如传感器输出。
- 缺点:容易受到噪声干扰,可能导致多次触发。
实例:按键检测与去抖动
#include <reg51.h>
// 定义延时函数
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 1275; j++);
}
}
// 按键状态变量
volatile bit key_pressed = 0;
// 外部中断0中断服务程序
void ExternalInterrupt0_ISR(void) interrupt 0 {
// 去抖动处理
delay_ms(10); // 延时10ms
if (P3_2 == 0) { // 再次检查按键是否仍然处于低电平
key_pressed = 1; // 设置按键按下标志
}
// 清除外部中断0触发标志
IE0 = 0;
}
void main() {
// 配置外部中断0为边沿触发方式
IT0 = 1;
// 启用外部中断0中断
EX0 = 1;
// 启用全局中断
EA = 1;
// 主循环
while (1) {
if (key_pressed) {
// 处理按键按下事件
key_pressed = 0; // 清除按键按下标志
// 执行按键按下后的操作
// 例如:点亮LED、发送数据等
P1_0 = ~P1_0; // 切换P1.0引脚电平(模拟LED闪烁)
// 延时一段时间,防止按键被多次检测
delay_ms(200);
}
}
}
串行通信中断
串行通信的基本概念
STC89C51RC/RD+系列单片机内部集成有一个功能很强的全双工串行通信口,与传统8051
单片机的串口完全兼容。设有2个互相独立的接收、发送缓冲器,可以同时发送和接收数据�。
发送缓冲器只能写入而不能读出,接收缓冲器只能读出而不能写入,,因而两个缓冲器可以共
用一个地址码(99H)。两个缓冲器统称串行通信特殊功能寄存器SBUF。
串行通信设有4种工作方式,其中两种方式的波特率是可变的,另两种是固定的,以供不
同应用场合选用。波特率由内部定时器/计数器产生,用软件设置不同的波特率和选择不同的
工作方式。主机可通过查询或中断方式对接收/发送进行程序处理,使用十分灵活。
STC89C51RC/RD+系列单片机串行口对应的硬件部分对应的管脚是P3.0/RxD和P3.1/TxD。
STC89C51RC/RD+系列单片机的串行通信口,除用于数据通信外,还可方便地构成一个或
多个并行I/O口,或作串—并转换,或用于扩展串行外设等
串行口相关寄存器
串行口控制寄存器SCON和PCON
STC89C51RC/RD+系列单片机的串行口设有两个控制寄存器:串行控制寄存器SCON和波
特率选择特殊功能寄存器PCON。
串行控制寄存器SCON用于选择串行通信的工作方式和某些控制功能。
其格式如下:
SCON : 串行控制寄存器 (可位寻址)
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | SM0/FE | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
位 | 描述 | 默认值 | 功能 |
---|---|---|---|
SM0 | 串行口工作模式选择(高) | 0 | 与SM1一起选择串行口的工作模式 |
SM1 | 串行口工作模式选择(低) | 0 | 与SM0一起选择串行口的工作模式 |
SM2 | 多机通信控制位 | 1 | 仅在模式2和模式3中有效,用于多机通信 |
REN | 接收允许位 | 0 | 0=禁止接收, 1=允许接收 |
TB8 | 第9位发送数据 | 0 | 仅在模式2和模式3中有效,表示第9位发送数据 |
RB8 | 第9位接收数据 | 0 | 仅在模式2和模式3中有效,表示第9位接收数据 |
TI | 发送中断标志 | 0 | 0=未完成, 1=已完成(需手动清除) |
RI | 接收中断标志 | 0 | 0=未完成, 1=已完成(需手动清除) |
模式 | SM0 SM1 | 描述 | 波特率 | 应用场景 |
---|---|---|---|---|
模式0 | 0 0 | 同步移位寄存器模式 | 固定波特率 | 适用于简单的并行到串行转换 |
模式1 | 0 1 | 8位UART模式 | 可变波特率 | 适用于标准异步串行通信 |
模式2 | 1 0 | 9位UART模式,固定波特率 | 固定波特率 | 适用于多机通信 |
模式3 | 1 1 | 9位UART模式,可变波特率 | 可变波特率 | 适用于多机通信和复杂通信协议 |
PCON : 电源控制寄存器 (不可位寻址)
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | SMOD | SMOD0 | POF | GF1 | GF0 | PD | IDL |
SMOD:波特率选择位。当用软件置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波
特率加倍;SMOD=0,则各工作方式的波特率加倍。复位时SMOD=0。
SMOD0:帧错误检测有效控制位。当SMOD0=1,SCON寄存器中的SM0/FE位用于FE(帧错误
检测)功能;当SMOD0=0,SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指
定串行口的工作方式。复位时SMOD0=0
与串行口中断相关的寄存器IE和IPH、IP
串行口中断允许位ES位于中断允许寄存器IE中,中断允许寄存器的格式如下:
IE : 中断允许寄存器 (可位寻址)
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | EA | / | ET2 | ES | ET1 | EX1 | ET0 | EX0 |
-
EA : CPU的总中断允许控制位,EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断申请。
EA的作用是使中断允许形成多级控制。即各中断源首先受EA控制;其次还受各中断源自
己的中断允许控制位控制。 -
ES : 串行口中断允许位,ES=1,允许串行口中断,ES=0,禁止串行口中断。
串行口中断优先级控制位PS/PSH位于中断优先级控制寄存器IP/IPH中,中断优先级控制寄
存器的格式如下:
IPH: 中断优先级控制寄存器高(不可位寻址)
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | PX3H | PX2H | PT2H | PSH | PT1H | PX1H | PT0H | PX0H |
IP : 中断优先级控制寄存器低 (可位寻址)
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
功能 | PT2 | PS | PT1 | PX1 | PT0 | PX0 |
PSH, PS: 串口1中断优先级控制位。
当PSH=0且PS=0时,串口1中断为最低优先级中断(优先级0)
当PSH=0且PS=1时,串口1中断为较低优先级中断(优先级1)
当PSH=1且PS=0时,串口1中断为较高优先级中断(优先级2)
当PSH=1且PS=1时,串口1中断为最高优先级中断(优先级3)
发送与接收
初始化串口
void UartInit() //9600bps@11.0592MHz
{
PCON &= 0x7F; //设置波特率不倍速
SCON = 0x50; //设置为8位数据,可变波特率
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFD; //设定定时初值
TH1 = 0xFD; //设定定时器重装值
TR1 = 1; //启动定时器1
ET1 = 0; //禁止定时器1中断
EA=1; //开启总中断
ES=1; //开启串口中断
}
发送
我们可以通过把数据给SBUF寄存器,他就会给我们发送出去,我们可以通过他来实现发送函数
发送函数代码如下:
void Uartsend(unsigned char byte) //定义一个函数,用于发送一个字节的数据
{
SBUF = byte; //将要发送的数据(byte)写入到发送缓冲区(SBUF)
while(TI == 0); //等待数据发送完成,发送完成后,硬件会将TI置1
TI = 0; //数据发送完成后,通过软件将TI清零
}
接收
接收,我们使用中断来接收,接收到的数据存储在SBUF寄存器里面
串口的接收在函数后面加interrupt 4即可,表示这个接收中断使用他
void UART_ISR() interrupt 4 //定义一个中断服务程序,用于处理串口中断,中断号为4
{
if(RI==1) //如果接收中断标志位RI为1,表示接收到数据
{
Uartsend(SBUF); //调用Uartsend函数,将接收到的数据(存储在SBUF中)发送出去
RI=0; //数据发送完成后,通过软件将接收中断标志位RI清零
}
}
标签:触发,定时器,优先级,中断,51,串行口,单片机,寄存器
From: https://www.cnblogs.com/Violetfan/p/18604995