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

51单片机基础-定时器中断

第十六章 定时器中断

1. 导入

在前面章节中,我们使用软件延时函数(如delay_ms)控制LED闪烁、数码管扫描等。但软件延时会阻塞CPU,无法同时执行其他任务。为实现精确、非阻塞的时间控制,本章学习51单片机的定时器/计数器模块,并通过定时器中断实现周期性任务调度。

51单片机内置两个16位定时器:T0T1,可配置为定时器(计时)或计数器(计外部脉冲)。本章重点使用定时器模式,结合中断机制,实现:

  • 精确毫秒级延时;
  • 非阻塞LED闪烁;
  • 动态数码管扫描;
  • 实时时钟基础;
  • 为多任务系统打下基础。

2. 硬件设计

2.1 定时器工作原理

定时器通过对机器周期进行计数实现定时。
51单片机一个机器周期 = 12个时钟周期。
若晶振为 11.0592MHz,则:

机器周期=11.0592×10612​≈1.085μs

定时器从初值开始递增,当计满(溢出)时触发中断。

2.2 相关寄存器

寄存器功能说明
TMOD模式控制寄存器,设置T0/T1工作方式
TH0/TL0定时器0高8位/低8位
TH1/TL1定时器1高8位/低8位
TCON控制寄存器,含TR0、TF0等
IE中断使能寄存器
TMOD格式(高4位为T1,低4位为T0):
GATEC/TM1M0功能
0010定时器模式,方式2(8位自动重装)
0011方式1(16位定时器,常用)

本章使用方式1:16位定时器,最大计数值65536。


3. 软件设计

3.1 定时器初始化(以T0为例)

目标:每50ms中断一次(常用于数码管扫描或实时时钟)。

计数值=1.085×10−650×10−3​≈46082

初值 = 65536−46082=19454=0x4BE6

#include <reg52.h>void timer0_init() {TMOD = 0x01;        // T0工作方式1(16位定时器)TH0  = 0x4B;        // 高8位TL0  = 0xE6;        // 低8位ET0  = 1;           // 使能T0中断EA   = 1;           // 开启总中断TR0  = 1;           // 启动定时器
}

3.2 定时器中断服务函数

unsigned char timer_count = 0;  // 记录中断次数void timer0_isr() interrupt 1 {TH0 = 0x4B;         // 重新加载初值TL0 = 0xE6;timer_count++;if (timer_count >= 20) {  // 50ms × 20 = 1sP1 = ~P1;             // 每秒翻转P1口(LED闪烁)timer_count = 0;}
}

interrupt 1 表示T0中断的中断号。


3.3 完整示例:非阻塞LED闪烁

void main() {timer0_init();while(1) {// 主程序可执行其他任务// 如:按键扫描、电机控制、数据处理等}
}

此时LED每秒闪烁一次,但主程序无需延时,可并行处理其他任务。


3.4 应用1:动态数码管扫描(非阻塞)

将数码管扫描放入定时器中断,每1ms执行一次:

unsigned char display_pos = 0;
unsigned char show_num[4] = {1, 2, 3, 4}; // 显示内容
unsigned char code seg_code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};void timer0_init_1ms() {TMOD = 0x01;// 1ms = 1000μs → 计数 ≈ 922// 初值 = 65536 - 922 = 64614 = 0xFC66TH0 = 0xFC;TL0 = 0x66;ET0 = 1;EA  = 1;TR0 = 1;
}void timer0_isr() interrupt 1 {TH0 = 0xFC;TL0 = 0x66;P0 = 0x00;P2 = (P2 & 0xF0) | 0x0F;  // 关闭所有位选P0 = seg_code[show_num[display_pos]];P2 = (P2 & 0xF0) | (0x0F & ~(1 << display_pos));display_pos++;if (display_pos > 3) display_pos = 0;
}

数码管自动扫描,主程序无需干预。


3.5 应用2:实时时钟(秒计时)

unsigned char sec = 0, min = 0, hour = 0;void timer0_isr() interrupt 1 {static unsigned int count = 0;TH0 = 0x4B;TL0 = 0xE6;count++;if (count >= 20) {  // 1秒count = 0;sec++;if (sec >= 60) {sec = 0;min++;if (min >= 60) {min = 0;hour++;if (hour >= 24) hour = 0;}}}
}

可结合数码管显示时间。


3.6 定时器1的使用(扩展)

定时器1配置方式与T0类似,中断号为 interrupt 3

void timer1_init() {TMOD |= 0x10;  // T1方式1TH1 = 0x4B;TL1 = 0xE6;ET1 = 1;EA  = 1;TR1 = 1;
}void timer1_isr() interrupt 3 {TH1 = 0x4B;TL1 = 0xE6;// 执行T1任务
}

可用于串口波特率发生器或第二路定时任务。


3.7 编译与下载

  • Keil中创建工程;
  • 确保定时器初值计算正确;
  • 编译生成HEX;
  • 下载至单片机;
  • 观察LED是否定时闪烁,数码管是否稳定显示。

若中断不触发:

  • 检查EAET0是否开启;
  • 确认TR0=1已启动;
  • 检查初值是否正确(可使用工具自动计算)。

4. 小结

本章通过学习定时器中断,掌握了非阻塞时间控制技术,主要内容包括:

  • 定时原理:理解机器周期与计数关系;
  • 寄存器配置:掌握TMOD、TH0/TL0、TCON、IE等设置;
  • 中断服务:编写定时器中断函数,实现周期性任务;
  • 应用实践:实现LED闪烁、数码管扫描、实时时钟;
  • 系统优化:解放主程序,提升系统响应能力与稳定性。

4.1 常见问题与解决

问题原因解决方法
中断不执行EA或ET0未开启检查中断使能
定时不准确初值计算错误重新计算或使用定时器计算器
程序跑飞中断函数过长或嵌套保持中断函数简洁
溢出错误未重装初值在中断中重新赋值TH0/TL0

4.2 下一步学习建议

  • 使用定时器实现PWM输出;
  • 结合外部中断实现多事件响应;
  • 设计多任务调度器
  • 应用于电子钟数据采集系统等项目。

本章标志着你已掌握精准时间控制能力,下一章将进入串口通信(UART) 的学习,实现单片机与PC之间的数据交互。


http://www.dtcms.com/a/512587.html

相关文章:

  • xtuoj 两个数
  • Android Studio新手开发第二十六天
  • 中国平安网站建设成都网站建设易维达好
  • 继保:对于线路两侧的电流互感器型号系数选取
  • Redis分布式集群:从分区算法到扩容实战
  • AI大模型:(二)1.6 DeepSeek-OCR部署尝鲜
  • 在昇腾NPU上跑Llama大模型:从零开始的真实测试之旅
  • 直播类网站开发wordpress 图片自动分页
  • JADX下载和安装图解教程(附安装包)
  • 矽塔 SA8203 2.5A可调过流保护 输入耐压36V 过压/过流保护芯片
  • 网站开发饼图样式wordpress 如何登陆地址
  • 工业相机 “即插即用” vs 采集卡依赖
  • wordpress手机视频播放器免费seo营销软件
  • 【系统分析师】预测试卷一:论文及写作要点(包括对应素材和论文案例)
  • 私有云不私有?Nextcloud+cpolar让文件随身走
  • 诺基亚官方网站wordpress站点进入时弹窗
  • 网站建设运营合作合同外链代发工具
  • 重庆江北网站建设18款app软件免费下载百度
  • wordpress 多语言 站点动态ip做网站影响seo吗
  • 河南建设网站官网怎么用微信官方网站做二维码
  • JSTS ,JSXTSX的区别与联系(前端react第一篇)
  • 电子商务网站建设以什么为核心公司网站能自己做吗
  • 股指期货与股票的区别是什么?
  • 天津网站建设学习温州建站模板搭建
  • 兰州网站优化服务个性化网站建设费用
  • Nginx负载均衡:高性能流量调度指南
  • [人工智能-大模型-35]:模型层技术 - Transformer神经网络结构与其他类型的神经网络结构(CNN、RNN)的对比
  • Blender微细节纹理材质模型资产包 Micro-Details Premium Asset Pack
  • 解释Linux 系统中ls -l命令的输出
  • 重庆丰都建设局网站中国建设银行网站企业