解码STC89C52RC单片机中断与通信
8位单片机中断系统
中断系统是单片机实现实时处理外部/内部事件的核心机制,让CPU可暂停当前主程序,优先处理紧急事件,处理完成后返回原断点继续执行,大幅提升CPU的事件响应效率。

核心基本概念
| 概念 | 定义 |
|---|---|
| 中断源 | 向CPU发出中断请求的设备/信号,STC89C52RC共8个中断源 |
| 中断优先级 | 中断源的响应先后次序,STC89C52RC支持4级优先级(0~3),可软件配置 |
| 中断嵌套 | 高优先级中断可打断低优先级中断的服务程序,处理完高优先级后返回继续执行低优先级;同级/低优先级不可嵌套高优先级 |
| 自然优先级 | 多个同级中断同时请求时,CPU按固定次序响应,由中断号从小到大决定 |
| 中断服务函数(ISR) | 响应中断时执行的专用函数,执行完毕后通过RETI指令返回主程序 |
| 中断向量地址 | CPU跳转到对应ISR的固定存储地址,每个中断源对应唯一地址 |
STC89C52RC中断请求源
共8个中断源,包含外部中断、定时器中断、串口中断三类,各中断源的核心参数为硬件固定+软件可配结合,所有中断均依赖总中断允许位EA,需同时开启总中断和对应中断允许位才会响应。

中断结构图

注:每个中断源都有独立的开关
中断触发方式
按中断源类型分为三类触发方式,外部中断支持电平/边沿触发,定时器中断为溢出触发,串口中断为收发完成触发:
- 电平触发:引脚持续为指定电平(低电平)时触发,需保证中断处理完成后电平恢复,否则会重复触发;
- 边沿触发:引脚电平发生指定跳变(上升沿/下降沿)时触发,仅在跳变瞬间有效,抗干扰性更强;
- 溢出触发:定时器计数器从初值累加到0xFFFF后溢出,硬件置位溢出标志位触发中断。
| 中断源名称 | 中断向量地址 | 中断号 | 触发方式/条件 | 自然优先级(从高到低) |
|---|---|---|---|---|
| 外部中断0(INT0) | 0003H | 0 | 低电平触发(IT0=0)或下降沿触发(IT0=1) | 1(最高) |
| 定时器0中断(T0) | 000BH | 1 | 定时器0计数溢出(TF0=1) | 2 |
| 外部中断1(INT1) | 0013H | 2 | 低电平触发(IT1=0)或下降沿触发(IT1=1) | 3 |
| 定时器1中断(T1) | 001BH | 3 | 定时器1计数溢出(TF1=1) | 4 |
| 串口中断(UART) | 0023H | 4 | 串口接收完成(RI=1)或发送完成(TI=1) | 5 |
| 定时器2中断(T2) | 002BH | 5 | 定时器2溢出(TF2=1)或捕获/重装(EXF2=1) | 6 |
| 外部中断2(INT2) | 0033H | 6 | 上升沿触发(IT2=0)或下降沿触发(IT2=1) | 7 |
| 外部中断3(INT3) | 003BH | 7 | 上升沿触发(IT3=0)或下降沿触发(IT3=1) | 8(最低) |
中断核心控制寄存器
STC89C52RC通过中断允许寄存器和中断优先级寄存器实现中断的开启/关闭、优先级配置,寄存器支持位操作,可独立配置每个中断源。

中断允许寄存器IE(地址A8H,复位值0x00)
总中断开关+各中断源独立开关,EA=0时屏蔽所有中断,EA=1时仅开启配置了对应允许位的中断。
| 位号 | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
|---|---|---|---|---|---|---|---|---|
| 位名称 | EA | 保留 | ET2 | ES | ET1 | EX1 | ET0 | EX0 |
| 功能 | 总中断允许位(1=开,0=关) | 无 | T2中断允许 | 串口中断允许 | T1中断允许 | INT1中断允许 | T0中断允许 | INT0中断允许 |
中断优先级寄存器IP(B8H)+IPH(B7H)
配合使用实现4级优先级配置,仅配置IP时为2级优先级(与传统8051兼容),IP为低字节,IPH为高字节,组合决定最终优先级。
| IP位号 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
|---|---|---|---|---|---|---|
| 位名称 | PT2 | PS | PT1 | PX1 | PT0 | PX0 |
| 功能 | T2优先级低字节 | 串口优先级低字节 | T1优先级低字节 | INT1优先级低字节 | T0优先级低字节 | INT0优先级低字节 |
| IPH位号 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
| 位名称 | PT2H | PSH | PT1H | PX1H | PT0H | PX0H |
| 功能 | T2优先级高字节 | 串口优先级高字节 | T1优先级高字节 | INT1优先级高字节 | T0优先级高字节 | INT0优先级高字节 |
注:高位保留位固定为0
中断服务函数(ISR)格式
C51编译器通过interrupt关键字声明ISR,中断号必须与中断源一一对应,否则CPU无法识别,函数无返回值、无参数,需手动清除部分中断标志位。
通用格式
/**
* @brief 中断服务函数通用格式
* @param 无参数,C51规定中断服务函数不可传参
* @return 无返回值,C51规定中断服务函数返回值为void
* @note 1. interrupt后为中断号,必须与中断源对应;2. 部分中断标志位需软件清零(如TI/RI);3. 函数体尽量精简,避免耗时
*/
void 函数名(void) interrupt 中断号
{
// 中断处理逻辑
// 清除中断请求标志位(按需)
}
示例(INT0中断)
void Int0_ISR(void) interrupt 0 // 中断号0对应INT0
{
// 处理INT0中断事件
}
中断处理完整流程
当中断被触发且CPU允许响应时,执行以下固定步骤,保证主程序与中断程序的无缝切换:
- 执行完当前正在运行的指令,保证指令完整性;
- 将当前程序计数器PC值压入栈中,保存断点地址;
- 保护现场(寄存器数据入栈,由编译器自动完成);
- 屏蔽同级别其他中断,防止嵌套混乱;
- 将中断向量地址装载到PC,跳转到对应ISR;
- 执行ISR,处理中断事件;
- 执行RETI指令,恢复现场+从栈中取回PC值,返回主程序断点继续执行。
外部中断的原理与应用
外部中断是单片机响应外部硬件事件(如按键、传感器、外部设备信号)的机制,通过检测外部引脚的电平/边沿变化触发,相比轮询检测,大幅提升外部事件的实时响应效率。
核心参数
STC89C52RC共4个外部中断源,对应P3口的4个专用引脚,INT0/INT1支持低电平/下降沿配置,INT2/INT3支持下降沿配置,需通过TCON/XICON寄存器配置触发方式。
| 中断源 | 对应引脚 | 中断号 | 触发方式配置 | 配置寄存器 |
|---|---|---|---|---|
| 外部中断0(INT0) | P3.2 | 0 | IT0=0:低电平;IT0=1:下降沿 | TCON |
| 外部中断1(INT1) | P3.3 | 2 | IT1=0:低电平;IT1=1:下降沿 | TCON |
| 外部中断2(INT2) | P3.4 | 6 | IT2=1:下降沿 | XICON |
| 外部中断3(INT3) | P3.5 | 7 | IT3=1:下降沿 | XICON |
实战案例代码(INT0下降沿触发)
实现INT0下降沿触发时,P0口输出值自增,需同时开启总中断EA和INT0中断允许位EX0。
#include "reg51.h"
/**
* @brief 外部中断0服务函数
* @param 无
* @return 无
* @note 中断号0对应INT0,下降沿触发时无需手动清除IEO,硬件自动清零
*/
void Int0_ISR(void) interrupt 0
{
P0++; // P0口输出值自增
}
/**
* @brief 主函数:配置INT0触发方式+开启中断,进入死循环等待中断
* @param 无
* @return 无
*/
void main(void)
{
IT0 = 1; // 配置INT0为下降沿触发
EX0 = 1; // 开启外部中断0允许位
EA = 1; // 开启总中断,所有中断的前提
while(1) // 死循环等待中断触发
{
;
}
}
定时器中断的原理与应用
STC89C52RC内置3个16位定时器/计数器(T0、T1、T2),T0/T1与传统8051兼容,T2为增强型,支持定时模式和计数模式:
- 定时模式:对单片机内部机器周期计数,实现精确定时,触发定时中断;
- 计数模式:对外部引脚的脉冲信号计数,实现外部脉冲统计。
定时器资源
| 定时器 | 位数 | 工作模式(定时模式下) | 核心特点 |
|---|---|---|---|
| T0 | 16位 | 模式0(13位)、模式1(16位)、模式2(8位自动重装载)、模式3(双8位) | 基础定时器,模式1(16位)需手动重装载初值,模式2(8位)自动重装载 |
| T1 | 16位 | 模式0(13位)、模式1(16位)、模式2(8位自动重装载) | 功能与T0类似,常作为串口波特率发生器 |
| T2 | 16位 | 自动重装载模式、捕获模式等 | 增强型定时器,支持16位自动重装载(无需手动赋初值),可配置外部触发 |
寄存器组

定时器模式寄存器TMOD(地址89H,不可位寻址,复位值0x00)
用于配置T0/T1的工作模式和定时/计数模式,高4位配置T1,低4位配置T0,需整体赋值。

定时器控制寄存器TCON(地址88H,可位寻址,复位值0x00)
用于配置外部中断触发方式、控制定时器启动/停止、标识定时器溢出/外部中断请求。
| 位号 | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
|---|---|---|---|---|---|---|---|---|
| 位名称 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
| 功能 | T1溢出标志(1=溢出,需软件清零) | T1启动位(1=启动,0=停止) | T0溢出标志(1=溢出,需软件清零) | T0启动位(1=启动,0=停止) | INT1请求标志 | INT1触发方式 | INT0请求标志 | INT0触发方式 |
定时器工作模式(重点:模式1)

T0/T1的模式1(16位定时/计数) 为最常用模式,将T0/T1作为16位计数器,由高8位THx和低8位TLx组成,计数范围0~65535,溢出后硬件置位TFx,触发定时器中断,无自动重装功能,需在ISR中手动重新赋值初值。
定时时间计算
计数器每12个时钟(12T模式)或者每6个时钟(6T模式)得到一个计数脉冲,计数值加1,定时模式下,定时器对机器周期计数,机器周期 = 12/晶振频率,为行业通用配置。

- 含义:计算单片机 1 个机器周期的时长(也就是计数器每加 1 所消耗的时间);
- 通俗解释:晶振是单片机的 “心跳”,比如 12MHz 晶振 = 每秒跳 1200 万次;12T 模式下,计数器每加 1,需要等晶振跳 12 次,所以机器周期 = 12÷ 晶振频率;
- 示例:12MHz 晶振,T = 12/12000000 = 1us(微秒)→ 计数器每加 1,耗时 1 微秒。

- 含义:要实现目标定时时间,计数器需要累加的次数;
- 通俗解释:比如想定时 1ms(1000μs),计数器每加 1 耗时 1μs,那就要累加 1000 次才能到 1ms;
- 示例:定时 1ms,N=1000μs/1μs=1000次。
计数初值:X=65536−N(16 位模式)
- 含义:16 位计数器最多数到 65535 就溢出,所以要从 “65536 - 需要计数的次数” 开始数,才能刚好数 N 次就溢出;
- 通俗解释:比如计数器最多数到 65535,想数 1000 次就溢出,那就要从 65536-1000=64536 开始数(64536→64537→…→65535,刚好 1000 次);
- 示例:X=65536−1000=64536,转 16 进制是 0xFC18(十进制转 16 进制:64536÷256=252→0xFC,余数 24→0x18)。
初值拆分:高 8 位写入 THx,低 8 位写入 TLx
- 含义:8051 的定时器初值寄存器是 8 位的(TH0/TL0 对应定时器 0,TH1/TL1 对应定时器 1),所以 16 位初值要拆成高 8 位、低 8 位分别写入;
- 示例:0xFC18 的高 8 位是 0xFC(写进 TH0),低 8 位是 0x18(写进 TL0)。
AiCube代码生成(延时1ms)

串口通信的原理与应用
串口通信基本概念
处理器与外部设备 / 处理器之间的通信分为串行通信和并行通信,串口通信属于串行通信,是将数据位逐位按顺序传输的通信方式,其核心优势为传输距离远、抗干扰能力强、硬件接线简单,是单片机与外设 / 上位机交互的常用方式。STC89C52RC 内置全双工异步串行通信口,与传统 8051 串口完全兼容,拥有独立的发送 / 接收缓冲器,支持同时发送和接收数据,对应的硬件管脚为 P3 口的两个引脚,是单片机实现串口通信的硬件基础。
串行与并行通信核心区别:
表格
| 对比项 | 串行通信 | 并行通信 |
|---|---|---|
| 传输方式 | 数据位逐位按顺序传输 | 多个数据位同时并行传输 |
| 传输距离 | 适合远距离,可达数十米以上 | 适合短距离,通常数米内 |
| 抗干扰能力 | 强,线少电磁干扰小、信号衰减低 | 弱,线多易产生线间串扰、信号衰减快 |
| 硬件复杂度 | 简单,接线少 | 复杂,接线多 |
串行通信的分类
按数据传输方向划分
根据数据能否双向传输及同时传输,分为单工、半双工、全双工三种,STC89C52RC 串口为全双工通信模式。
- 单工:数据仅能从一方传向另一方,单向不可逆,硬件仅需一条传输线;
- 半双工:数据可双向传输,但同一时间仅能单向传输,如对讲机,硬件需一条传输线;
- 全双工:数据可同时在两个方向传输,相当于两个单工的结合,发送端和接收端独立工作,STC89C52RC 串口的 TXD(发送)和 RXD(接收)引脚独立,支持该模式。
按数据同步方式划分
根据发送端和接收端的同步机制,分为同步通信和异步通信,STC89C52RC 串口为异步通信模式。
| 对比项 | 同步通信 | 异步通信 |
|---|---|---|
| 传输单位 | 以帧(数据块)为单位连续传输 | 以字符(字节)为单位独立传输,字符间可无间隙 |
| 同步机制 | 通过共享时钟 / 帧头同步码实现全局同步,时钟严格一致 | 通过字符前后的起始位、停止位实现字符级局部同步,无需全局时钟 |
| 时钟要求 | 频率、相位需严格同步,仅允许微小偏差 | 仅字符传输期间时钟大致同步,偏差允许范围大 |
| 传输效率 | 高,无额外同步开销,适合高速大数据传输 | 低,含起始 / 停止位开销,适合小数据量传输 |
| 硬件复杂度 | 复杂,需时钟同步电路 | 简单,成本低,无需同步时钟 |
| 典型应用 | SPI、I2C 总线 | 单片机 UART 串口、PC 端串口 |
串口通信核心参数
串口为异步全双工通信,无需时钟同步,但通信双方必须提前约定字符格式和通信速率(波特率),参数不一致会导致数据传输错误。
字符格式

串口通信的数据流以字符帧为基本单位,字符帧由起始位、数据位、校验位、停止位四部分组成,通信双方需统一帧格式,最常用格式:1bit 起始位 + 8bit 数据位 + 无校验位 + 1bit 停止位(一帧共 10bit)。
- 起始位:固定为低电平,占 1bit,用于通知接收端开始接收数据;
- 数据位:承载有效数据,常用 8bit,低位在先传输;
- 校验位:可选(0/1bit),用于检错(奇 / 偶校验),无校验位时省略;
- 停止位:固定为高电平,占 1/2bit,用于通知接收端字符帧传输结束。
波特率与比特率
两者均为衡量串口传输速度的指标,单位不同,需区分:
- 波特率:单位bps(bit per second),指单位时间内传输的码元数量,串口通信中码元为二进制位,波特率即每秒传输的二进制位数;
- 比特率:单位bits/s,指单位时间内传输的有效二进制数据位数量;
- 常用波特率:9600bps、38400bps、57600bps、115200bps(9600bps 为最常用)。
计算示例:采用 10bit 字符帧(1 起始 + 8 数据 + 1 停止)、9600bps 波特率,每秒可传输的有效数据帧为:9600bps ÷ 10bit / 帧 = 960 帧 / 秒,每秒传输有效数据为 960×8bit=7680bits/s。
STC89C52RC 串口外设特性
硬件管脚

STC89C52RC 串口通信的硬件管脚为 P3 口的两个专用引脚,不可随意更改,需与外设 / PC 端对应连接(交叉连接:单片机 TXD 接 PC RXD,单片机 RXD 接 PC TXD):
- P3.0/RxD:串口接收引脚,输入型,用于接收外部传输的数据;
- P3.1/TxD:串口发送引脚,输出型,用于向外发送单片机的数据。
工作模式
STC89C52RC 串口有4 种工作模式,由 SCON 寄存器的SM0、SM1 位组合配置,其中模式 0 为同步移位寄存器,模式 1/2/3 为异步通信,模式 1 为最常用的通用串口通信模式。
| 模式 | SM0 | SM1 | 功能描述 | 波特率特性 | 应用场景 |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 8 位同步移位寄存器 | 固定为 fosc/12(fosc 为晶振频率) | 扩展单片机 I/O 口 |
| 1 | 0 | 1 | 8 位 UART(1 起始 + 8 数据 + 1 停止) | 可变,由定时器 T1/T2 溢出率生成 | 通用串口通信(与 PC、传感器交互) |
| 2 | 1 | 0 | 9 位 UART(带第 9 位校验 / 地址位) | 固定为 fosc/32 或 fosc/64 | 多机通信 |
| 3 | 1 | 1 | 9 位 UART(带第 9 位校验 / 地址位) | 可变,由定时器 T1/T2 溢出率生成 | 多机通信(波特率可变) |
波特率生成原理
串口模式 1/3 的波特率为可变,由定时器 T1(首选)或 T2 的溢出率决定,单片机默认工作在12T 模式(可配置 6T),波特率计算公式:
串口波特率 = 2^SMOD × 定时器 T1 溢出率 / 32

常用波特率配置:晶振为11.0592MHz(串口通信专用晶振,无波特率误差)、12T 模式、SMOD=0、T1 模式 2,9600bps 波特率对应的 TH1 初值为0xFD,是工程中最常用的配置组合。

内部结构

串口通信寄存器

STC89C52RC 串口通信的配置、控制、状态检测依赖专用寄存器,核心为 SCON、PCON,波特率生成依赖定时器 T1 的 TMOD/TCON 寄存器,中断控制依赖 IE/IP 寄存器。
SCON(串口控制寄存器)
地址98H,可位寻址,复位值0000 0000B,是串口通信的核心控制寄存器,用于配置串口工作模式、控制数据接收、标识发送 / 接收中断状态,逐位功能:
| 位序号 | 位名称 | 位地址 | 核心功能 |
|---|---|---|---|
| B7 | SM0/FE | 9FH | 双重功能:传统模式为工作模式选择位;增强模式为帧错误检测位(FE) |
| B6 | SM1 | 9EH | 工作模式选择位,与 SM0 组合配置 4 种工作模式 |
| B5 | SM2 | 9DH | 多机通信控制位:模式 2/3 时控制 RI 置 1 条件;模式 1 时校验停止位,通用通信置 0 |
| B4 | REN | 9CH | 接收允许控制位:REN=1 允许接收,REN=0 禁止接收,复位默认 0 |
| B3 | TB8 | 9BH | 发送第 9 位数据:模式 2/3 下用于奇偶校验 / 多机通信地址标识,模式 1 无意义 |
| B2 | RB8 | 9AH | 接收第 9 位数据:模式 2/3 下对应发送方 TB8;模式 1 下为停止位(SM2=0 时) |
| B1 | TI | 99H | 发送中断标志位:发送完成由硬件置 1,必须软件清零,用于判断发送状态 |
| B0 | RI | 98H | 接收中断标志位:接收完成由硬件置 1,必须软件清零,用于判断接收状态 |
通用配置(模式 1):SCON = 0x50(即 0101 0000B),对应 SM0=0、SM1=1(模式 1)、REN=1(允许接收),其余位置 0。
//串口初始化(9600波特率,模式1,允许接收)
void UART_Init()
{
SCON = 0x50; // 模式1(01),允许接收(REN=1)
PCON = 0x00; // SMOD=0,波特率不加倍
TMOD = 0x20; // T1模式2(8位自动重装载)
TL1 = 0xFD; // 可以把TL1寄存器的值重载到TH1中
TH1 = 0xFD; // 9600波特率初值(11.0592MHz晶振)
TR1 = 1; // 启动定时器T1
}
PCON(电源控制寄存器)
地址87H,不可位寻址,复位值00x1 0000B,仅SMOD 位与串口通信相关,其余位为电源管理位,功能:
- SMOD(B7 位):波特率加倍控制位,SMOD=0 时波特率不加倍(默认),SMOD=1 时波特率加倍;
- 通用配置:PCON = 0x00(SMOD=0,不加倍)。
STC89C52RC 串口配置流程
串口通用通信采用模式 1、查询方式(简单易实现)、定时器 T1 作为波特率发生器,晶振为 11.0592MHz,核心配置流程为6 步,通信双方需严格一致:
- 配置 SCON 寄存器,设置串口为模式 1,并允许接收(REN=1);
- 配置 PCON 寄存器,设置SMOD=0(波特率不加倍);
- 配置 TMOD 寄存器,将定时器 T1 设置为模式 2(8 位自动重装载);
- 给定时器 T1 的 TH1/TL1 写入波特率对应初值(9600bps 对应 0xFD);
- 启动定时器 T1(置 TR1=1),T1 开始计数生成波特率;
- (可选)若采用中断方式,配置 IE/IP 寄存器,允许串口中断并设置优先级。
串口数据收发原理
STC89C52RC 的SBUF(串口缓冲寄存器) 是实现数据收发的核心,地址99H,实际为两个独立的 8 位寄存器(物理地址相同,功能不同):
- 发送缓冲器:只写,将需要发送的数据写入 SBUF,硬件会自动将数据逐位从 TxD 引脚发送,发送完成后硬件置 TI=1;
- 接收缓冲器:只读,硬件自动将 RxD 引脚接收到的数据逐位存入该寄存器,接收完成后硬件置 RI=1,读取 SBUF 可获得接收数据。
注意:
- SBUF 的写操作对应发送,读操作对应接收,互不干扰;
- 发送 / 接收完成后,TI 和 RI 标志位由硬件置 1,需通过软件清零;
- 查询方式下,通过判断 TI/RI 的状态实现收发同步(等待 TI=1 表示发送完成,等待 RI=1 表示接收完成)。
串口单字节发送函数
/**
* @brief 串口单字节发送函数,向串口发送一个8位无符号字符数据
* @param dat:unsigned char类型,需要发送的单字节数据,范围0x00~0xFF
* @return 无返回值
* @note 查询TI标志位实现发送同步,发送完成后软件清零TI,确保下次发送
* 仅能发送8位数据,符合串口模式1的8位数据位要求
*/
void UART_SendByte(unsigned char dat)
{
SBUF = dat; // 将数据写入发送缓冲器,硬件自动启动发送
while (!TI); // 等待发送完成:TI=0时循环等待,TI=1表示发送完成
TI = 0; // 软件清零发送中断标志位,准备下一次发送
}
串口单字节接收函数
/**
* @brief 串口单字节接收函数,从串口接收一个8位无符号字符数据
* @param 无参数,通过RxD引脚接收外部数据
* @return unsigned char类型,接收到的8位数据,范围0x00~0xFF
* @note 查询RI标志位实现接收同步,接收完成后软件清零RI,确保下次接收
* 调用前需确保串口已初始化且REN=1(允许接收)
*/
unsigned char UART_ReceiveByte(void)
{
while (!RI); // 等待接收完成:RI=0时循环等待,RI=1表示接收完成
RI = 0; // 软件清零接收中断标志位,准备下一次接收
return SBUF; // 读取接收缓冲器,返回接收到的单字节数据
}

浙公网安备 33010602011771号