mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3
776 字
2 分钟
51单片机定时器原理与应用详解
2026-06-18

51单片机定时器原理与应用详解#

51单片机内置两个16位定时器/计数器——T0和T1,是嵌入式开发中最基础也最重要的外设之一。无论是LED闪烁、串口波特率生成,还是PWM输出,都离不开定时器。

定时器基础知识#

什么是定时器?#

定时器本质上是一个加1计数器。每个机器周期(12个时钟周期),计数器自动加1。当计数器从最大值溢出回到0时,触发中断标志。

以12MHz晶振为例:

机器周期 = 12 / 12MHz = 1μs

也就是说,计数器每1μs加1。

相关寄存器#

寄存器地址功能
TMOD0x89定时器工作模式控制
TCON0x88定时器控制与中断标志
TH0/TL00x8C/0x8A定时器0高/低字节
TH1/TL10x8D/0x8B定时器1高/低字节

TMOD寄存器详解#

TMOD是一个8位寄存器,高4位控制T1,低4位控制T0:

位7: GATE1 - 门控位
位6: C/T1 - 定时/计数选择 (0=定时, 1=计数)
位5-4: M1M01 - T1模式选择
位3: GATE0 - 门控位
位2: C/T0 - 定时/计数选择
位1-0: M1M00 - T0模式选择

四种工作模式#

模式0:13位定时器#

THx 8位 + TLx 低5位 = 13位计数器

最大计数值:2^13 = 8192

这是为了兼容老款8048单片机,实际开发中很少使用。

模式1:16位定时器(最常用)#

THx 8位 + TLx 8位 = 16位计数器

最大计数值:2^16 = 65536

定时时间计算公式:

定时时间 = (65536 - 初值) × 机器周期

例如12MHz晶振下定时50ms:

初值 = 65536 - 50000 = 15536
TH0 = 15536 / 256 = 60 = 0x3C
TL0 = 15536 % 256 = 176 = 0xB0

模式2:8位自动重装#

THx存储重装值,TLx为计数器

TLx溢出后,THx的值自动装入TLx,无需手动重装。适合精确的周期性定时,如串口波特率生成。

模式3:双8位定时器(仅T0)#

将T0拆分为两个独立的8位定时器,此时T1停止工作。

实战代码#

示例1:LED每500ms闪烁#

#include <reg52.h>
sbit LED = P1^0;
void Timer0_Init() {
TMOD |= 0x01; // T0模式1(16位定时器)
TH0 = 0x3C; // 50ms初值高字节
TL0 = 0xB0; // 50ms初值低字节
EA = 1; // 开总中断
ET0 = 1; // 开T0中断
TR0 = 1; // 启动T0
}
unsigned int count = 0;
void Timer0_ISR() interrupt 1 {
TH0 = 0x3C; // 重装初值
TL0 = 0xB0;
count++;
if (count >= 10) { // 50ms × 10 = 500ms
count = 0;
LED = ~LED; // 翻转LED
}
}
void main() {
Timer0_Init();
while (1) {
// 主循环可做其他事
}
}

示例2:产生1kHz方波(P1.0)#

#include <reg52.h>
sbit WAVE = P1^0;
void Timer0_Init() {
TMOD |= 0x02; // T0模式2(8位自动重装)
TH0 = 256 - 500; // 12MHz下500μs
TL0 = TH0;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void Timer0_ISR() interrupt 1 {
WAVE = ~WAVE; // 每500μs翻转,周期1ms = 1kHz
}
void main() {
Timer0_Init();
while (1);
}

定时器初值速查表#

12MHz晶振,模式1下的常用初值:

定时时间TH0TL0计算过程
1ms0xFC0x1865536-1000=64536
10ms0xD80xF065536-10000=55536
20ms0xB10xE065536-20000=45536
50ms0x3C0xB065536-50000=15536
100ms0x780x6065536-100000(需多次)

注意: 16位定时器单次最大定时约65.536ms(12MHz),超过需要软件计数。

常见问题#

为什么定时不准?#

  1. 晶振频率不对 — 确认实际晶振频率
  2. 中断服务程序太长 — ISR执行时间会影响定时精度
  3. 没有重装初值 — 模式1必须手动重装

如何提高精度?#

  • 使用11.0592MHz晶振(串口通信友好)
  • 在ISR开头立即重装初值
  • 避免在中断中执行耗时操作

总结#

模式位数自动重装适用场景
模式013位基本不用
模式116位通用定时
模式28位波特率生成
模式3双8位特殊需求

定时器是51单片机的核心外设,掌握它对后续学习中断、串口、PWM都至关重要。建议从模式1开始练习,理解初值计算后再尝试其他模式。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

51单片机定时器原理与应用详解
https://mizuki.mysqil.com/posts/51-mcu-timer/
作者
まつざか ゆき
发布于
2026-06-18
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时