当前位置: 首页 > news >正文

C51 中断

1.外部中断

外部中断由单片机外部引脚的电平或边沿变化触发,适用于按键、传感器等外部事件响应。


1. 外部中断资源(8051 内核)


INT0:对应引脚 P3.2,中断号 0
INT1:对应引脚 P3.3,中断号 2
触发方式:电平触发(低电平有效)或边沿触发(下降沿 / 上升沿)


2. 外部中断配置步骤


步骤 1:配置触发方式(TCON 寄存器)
IT0(INT0 触发方式):IT0=0→电平触发;IT0=1→边沿触发(下降沿)
IT1(INT1 触发方式):IT1=0→电平触发;IT1=1→边沿触发(下降沿)


步骤 2:使能中断(IE 寄存器)
EX0=1(允许 INT0 中断);EX1=1(允许 INT1 中断)
EA=1(允许总中断,必须开启)


步骤 3:编写中断服务函数
格式:void 函数名() interrupt 中断号 { ... }
INT0 中断号:0;INT1 中断号:2


3. 外部中断实战:按键控制 LED 翻转


硬件连接:按键接 P3.2(INT0),LED 接 P2.0。

#include "reg52.h"typedef unsigned int u16;
typedef unsigned char u8;sbit LED = P2^0;    // LED引脚
sbit KEY_INT0 = P3^2;  // INT0按键引脚// 延时函数(用于消抖)
void delay(u16 i) {while(i--);
}// INT0初始化函数
void Int0Init() {IT0 = 1;  // 边沿触发(下降沿)EX0 = 1;  // 允许INT0中断EA = 1;   // 允许总中断
}// INT0中断服务函数
void Int0Handler() interrupt 0 {delay(1000);  // 消抖(约10ms)if(KEY_INT0 == 0) {  // 确认按键按下LED = ~LED;  // LED状态翻转}
}void main() {Int0Init();  // 初始化中断while(1) {// 主程序可执行其他任务,中断自动响应}
}

2.定时器中断

定时器中断(以 T0 为例)
定时器中断由内部定时器计数溢出触发,适用于定时任务(如时钟、周期性采样)。


1. 定时器资源(8051 内核)


T0:定时器 0,中断号 1
T1:定时器 1,中断号 3
核心原理:通过计数内部机器周期,溢出时触发中断(可计算定时时间)


2. 定时器中断配置步骤


步骤 1:设置定时器模式(TMOD 寄存器)
选择工作模式(常用模式 1:16 位定时器,需手动重装初值)
TMOD &= 0xF0; TMOD |= 0x01;(配置 T0 为模式 1)


步骤 2:计算并装载初值
机器周期 = 12 / 晶振频率(如 11.0592MHz 晶振,机器周期≈1.085μs)
定时时间 =(65536 - 初值)× 机器周期 → 初值 = 65536 - 定时时间 / 机器周期
装载初值到 TH0(高 8 位)和 TL0(低 8 位)


步骤 3:使能中断(IE 寄存器)
ET0=1(允许 T0 中断);ET1=1(允许 T1 中断)
EA=1(允许总中断)


步骤 4:启动定时器并编写中断服务函数
TR0=1(启动 T0);TR1=1(启动 T1)
中断服务函数:T0 中断号 1;T1 中断号 3


3. 定时器中断实战:LED 周期性闪烁


需求:LED 每 1 秒翻转一次(晶振 11.0592MHz)。

#include "reg52.h"typedef unsigned int u16;
typedef unsigned char u8;sbit LED = P2^0;u16 cnt = 0;  // 计数变量(记录中断次数)// 定时器0初始化(定时10ms)
void Timer0Init() {TMOD &= 0xF0;  // 清除T0配置TMOD |= 0x01;  // T0模式1(16位定时器)// 初值计算:10ms = (65536 - 初值) × (12/11.0592MHz) → 初值≈55536TH0 = 0xFC;  // 高8位:55536 / 256 = 217 → 0xFCTL0 = 0x18;  // 低8位:55536 % 256 = 24 → 0x18ET0 = 1;  // 允许T0中断EA = 1;   // 允许总中断TR0 = 1;  // 启动T0
}// T0中断服务函数
void Timer0Handler() interrupt 1 {// 重新装载初值(模式1需手动重装)TH0 = 0xFC;TL0 = 0x18;cnt++;  // 每10ms计数+1if(cnt >= 100) {  // 10ms × 100 = 1000ms = 1scnt = 0;LED = ~LED;  // 每秒翻转LED}
}void main() {Timer0Init();  // 初始化定时器while(1) {// 主程序无需干预,定时器自动定时}
}

http://www.lryc.cn/news/603882.html

相关文章:

  • Python批量生成N天前的多word个文件,并根据excel统计数据,修改word模板,合并多个word文件
  • 理解“无界队列”与“有界队列”及其适用场景
  • git使用lfs解决大文件上传限制
  • 2411.按位或最大的最小子数组长度
  • gTest测试框架的安装与配置
  • 三、Linux用户与权限管理详解
  • 【目标检测】小样本度量学习
  • 量子计算革命:重新定义计算的边界与未来
  • DNS污染与劫持
  • Python爬虫02_Requests实战网页采集器
  • MoR vs MoE架构对比:更少参数、更快推理的大模型新选择
  • Ubuntu20.04子系统
  • Oracle发布MCP Server,自然语言交互说“人话”
  • AUTOSAR Mcal Gpt - 模块介绍
  • LeetCode|Day29|1009. 十进制整数的反码|Python刷题笔记
  • Jenkins 详解
  • Java 大视界 -- Java 大数据机器学习模型在金融信用评级模型优化与信用风险动态管理中的应用(371)
  • 当贝纯净版_海信ip811n海思mv320处理器安卓4.42及9.0主板优盘免拆刷机固件及教程
  • 符号计算与算法实践|使用Maple教授​​群论​​和​​图论​​课程
  • JSON解析(day20)
  • 【CF】Day114——杂题 (贪心 + 图论 | LCM + 贪心 | 最大最小子序列 + 图论)
  • 如何创建一个 Solana 钱包?
  • imx6ull-驱动开发篇3——字符设备驱动开发实验
  • C 语言第 12 天学习笔记:函数进阶应用与变量特性解析
  • 每日学习笔记记录(分享更新版-凌乱)
  • imx6ull-驱动开发篇2——字符设备驱动开发步骤
  • 网络通信基础(一)
  • Redis 跨主机连接超时分析:从网络波动到架构优化
  • 使用鼠标在Canvas上绘制矩形
  • 【C++算法】80.BFS解决FloodFill算法_岛屿数量