期末客观题总结
1、寄存器总结
1.1 常用 SFR 汇总表格

1.2、TCON(定时器控制寄存器)


1.3、TMOD(定时器方式控制寄存器)
1.4 IE(中断允许寄存器)
1.5 IP(中断优先级寄存器)
1.6 SCON(串口行控制寄存器)

2、中断总结
下面是8051单片机中断处理流程的Mermaid流程图:
CPU 正在执行主程序时,外部 / 内部突发事件向 CPU 发送请求,CPU 暂停当前主程序,跳转去执行专门的中断服务子程序,处理完事件后,自动回到断点继续执行原主程序。
作用:分时处理多任务、实时响应外部信号、定时控制、串口收发数据,避免 CPU 空循环等待。
2.1 外部中断
1)触发来源
单片机外部引脚电平 / 跳变信号触发:
INT0:P3.2 引脚,外部中断 0
INT1:P3.3 引脚,外部中断 1
2)两种触发方式(TCON 寄存器配置)
电平触发:引脚持续低电平就触发中断;
缺点:低电平一直存在会反复进中断,按键易卡死。
下降沿触发:引脚从高电平跳变到低电平的一瞬间触发一次,常用在按键、外部传感器触发。
3)典型应用
独立按键触发功能切换、外部传感器(红外、限位开关)信号检测、紧急停机触发。
4)关键寄存器
IT0/IT1:触发方式选择位,1 = 下降沿,0 = 低电平
EX0/EX1:外部中断允许开关
EA:总中断开关(所有中断必须打开 EA=1 才生效)
2.2 定时器中断
1)触发来源
单片机内部硬件定时器计数溢出,自动触发中断,不需要外部接线。
51 有 T0(定时器 0)、T1(定时器 1)两个独立定时器。
计数脉冲来源二选一:
定时模式:对系统机器周期计数,用来精准定时(ms/s 延时、秒表、时钟)
计数模式:对 T0/T1 外部引脚脉冲计数(统计脉冲个数、测速)
2)工作原理
给定时器 THx、TLx 赋初值,硬件自动累加计数;加满溢出后,硬件自动置中断标志位,申请定时器中断,进入中断服务函数重新装载初值,实现循环精准定时。
3)典型应用
LED 流水灯定时切换、数码管动态扫描、电子时钟秒分时计时、电机定时启停、按键消抖定时检测。
4)核心优势
不用软件循环空等延时,CPU 定时期间可以正常跑主程序,定时时间到自动进中断,不占用主程序运行资源。
5)关键寄存器
TMOD:设置 T0/T1 工作模式(定时 / 计数、16 位 / 8 位自动重装)
TH0、TL0、TH1、TL1:计数初值寄存器
ET0、ET1:定时器中断允许位
TR0、TR1:定时器启停控制位
6)定时器中断配置示例代码
以下是一个使用定时器0(T0)实现1ms定时中断的完整示例代码:
#include <reg51.h>
// 定义LED控制引脚
sbit LED = P1^0;
// 定义1ms计数值(假设晶振为12MHz)
// 机器周期 = 12 / 12MHz = 1μs
// 1ms需要计数次数 = 1000μs / 1μs = 1000次
// 定时器初值 = 65536 - 1000 = 64536 = 0xFC18
#define TIMER0_HIGH 0xFC // 高8位
#define TIMER0_LOW 0x18 // 低8位
// 全局变量:中断计数
unsigned int timer0_count = 0;
/**
* 定时器0中断服务函数
* 中断号:1
*/
void timer0_isr() interrupt 1
{
// 重新装载初值
TH0 = TIMER0_HIGH;
TL0 = TIMER0_LOW;
// 中断计数
timer0_count++;
// 每1000次中断(1秒)翻转LED
if (timer0_count >= 1000)
{
timer0_count = 0;
LED = ~LED; // LED状态翻转
}
}
/**
* 定时器0初始化函数
* 模式1:16位定时器模式
* 定时模式:对系统时钟计数
*/
void timer0_init()
{
// 1. 设置TMOD寄存器:T0工作在模式1(16位定时器),定时模式
// TMOD = 0000 0001 (GATE=0, C/T=0, M1=0, M0=1)
TMOD &= 0xF0; // 清零T0相关位
TMOD |= 0x01; // 设置T0为模式1
// 2. 设置定时器初值
TH0 = TIMER0_HIGH;
TL0 = TIMER0_LOW;
// 3. 开启定时器0中断
ET0 = 1; // 允许T0中断
// 4. 开启总中断
EA = 1; // 总中断允许
// 5. 启动定时器0
TR0 = 1; // 启动T0
}
/**
* 主函数
*/
void main()
{
// 初始化LED引脚
LED = 0;
// 初始化定时器0
timer0_init();
// 主循环
while (1)
{
// 主程序可以执行其他任务
// 定时器中断在后台自动运行
// 这里可以添加其他功能代码
}
}
7)代码说明
- 定时器模式选择:使用TMOD寄存器设置T0为模式1(16位定时器),这是最常用的定时器模式。
- 初值计算:根据晶振频率计算定时器初值,实现精确的定时时间。
- 中断服务函数:使用
interrupt 1关键字声明定时器0中断服务函数,中断号1对应T0中断。 - 中断处理流程:
- 定时器溢出触发中断
- 硬件自动跳转到中断服务函数
- 重新装载初值(保持定时精度)
- 更新中断计数器
- 根据计数结果执行相应操作
- 主程序优势:主循环可以执行其他任务,定时功能由中断自动处理,实现多任务并行。
8)定时器中断配置步骤总结
- 选择定时器:T0或T1
- 设置工作模式:通过TMOD寄存器设置(模式0/1/2/3)
- 计算并设置初值:THx/TLx寄存器
- 开启中断允许:ETx = 1
- 开启总中断:EA = 1
- 启动定时器:TRx = 1
- 编写中断服务函数:使用
interrupt关键字
9)常见定时器模式对比
| 模式 | 位数 | 自动重装 | 适用场景 |
|---|---|---|---|
| 模式0 | 13位 | 否 | 早期兼容,现已少用 |
| 模式1 | 16位 | 否 | 最常用,定时范围大 |
| 模式2 | 8位 | 是 | 需要精确重复定时 |
| 模式3 | 两个8位 | 否 | T0分成两个独立8位定时器 |
2.3 串口中断
串口中断是51单片机中用于处理串行通信数据收发的重要中断类型。当串口完成一帧数据的发送或接收时,会触发串口中断,通知CPU进行相应处理。
串口中断相关寄存器
-
SCON(串行控制寄存器)
- RI(接收中断标志位):当串口接收到一帧完整数据时,硬件自动置1,需要软件清零
- TI(发送中断标志位):当串口发送完一帧数据时,硬件自动置1,需要软件清零
-
IE(中断允许寄存器)
- ES(串口中断允许位):置1允许串口中断,置0禁止串口中断
-
IP(中断优先级寄存器)
- PS(串口中断优先级控制位):置1为高优先级,置0为低优先级
串口中断工作流程
-
初始化配置:
- 设置串口工作模式(模式1最常用)
- 设置波特率(通过定时器1或定时器2)
- 开启串口中断允许位(ES=1)
- 开启总中断允许位(EA=1)
-
中断触发条件:
- 接收中断:当RI=1时触发,表示接收到一帧数据
- 发送中断:当TI=1时触发,表示发送完成一帧数据
-
中断服务程序处理:
- 判断是RI还是TI触发的中断
- 读取接收到的数据或准备下一帧发送数据
- 清除中断标志位(RI=0或TI=0)
串口中断配置示例代码
#include <reg51.h>
// 串口初始化函数
void UART_Init() {
// 设置串口工作模式1(8位UART,波特率可变)
SCON = 0x50; // 0101 0000:模式1,允许接收
// 设置定时器1为波特率发生器,模式2
TMOD &= 0x0F; // 清除定时器1模式位
TMOD |= 0x20; // 设置定时器1为模式2
// 设置波特率为9600(12MHz晶振)
TH1 = 0xFD; // 波特率重装值
TL1 = 0xFD;
// 启动定时器1
TR1 = 1;
// 允许串口中断
ES = 1;
// 允许总中断
EA = 1;
}
// 串口发送一个字节
void UART_SendByte(unsigned char dat) {
SBUF = dat; // 将数据写入发送缓冲区
while(!TI); // 等待发送完成
TI = 0; // 清除发送中断标志
}
// 串口中断服务程序
void UART_ISR() interrupt 4 {
if (RI == 1) { // 接收中断
RI = 0; // 清除接收中断标志
// 处理接收到的数据:SBUF中为接收到的数据
unsigned char received_data = SBUF;
// 这里可以添加数据处理代码
}
if (TI == 1) { // 发送中断
TI = 0; // 清除发送中断标志
// 发送完成处理
}
}
// 主函数
void main() {
UART_Init(); // 初始化串口
// 发送测试数据
UART_SendByte('H');
UART_SendByte('e');
UART_SendByte('l');
UART_SendByte('l');
UART_SendByte('o');
while(1) {
// 主循环
}
}
串口中断的注意事项
- 中断标志位清除:RI和TI标志位必须由软件清零,硬件不会自动清除
- 数据缓冲区:发送和接收共用SBUF寄存器,但物理上是两个独立的寄存器
- 中断优先级:串口中断默认是低优先级,可通过PS位设置为高优先级
- 波特率匹配:发送和接收双方的波特率必须一致,否则会导致数据错误
- 中断嵌套:如果串口中断设置为高优先级,可以打断低优先级中断的执行
常见问题与解决方法
-
接收不到数据:
- 检查波特率设置是否正确
- 确认ES和EA是否已置1
- 检查硬件连接是否正常
-
数据发送不完整:
- 确保TI标志位在发送前已清零
- 检查发送缓冲区是否被意外修改
-
中断响应不及时:
- 优化中断服务程序,减少执行时间
- 考虑使用中断优先级设置
串口中断在51单片机串行通信中起着关键作用,合理使用串口中断可以实现高效的数据传输,同时释放CPU资源处理其他任务。
3、IO端口总结
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)