#includeREGX52.H//void Timer0Init(void) //1毫秒12.000MHz计时器T0//{// TMOD 0xF0; //设置定时器模式把TMOD的低4位清零高4位不变// TMOD | 0x01; //设置定时器模式将前4位置0不用T1计时器用T0给最低位置1高4位不变// TL0 0x18; //设置定时初值低位64535%256// TH0 0xFC; //设置定时初值高位64535/256// TF0 0; //清除TF0标志定时器标志0表示使用它// TR0 1; //定时器0开始计时// ET01;//分开关接通1// EA1;//总开关1接通// PT00;//优先级配置//}voidTimer0Init(void)//1毫秒11.0592MHz计时器T0{TMOD0xF0;//设置定时器模式把TMOD的低4位清零高4位不变TMOD|0x01;//设置定时器模式将前4位置0不用T1计时器用T0给最低位置1高4位不变TL00x66;//设置定时初值低位64535%256TH00xFC;//设置定时初值高位64535/256TF00;//清除TF0标志定时器标志0表示使用它TR01;//定时器0开始计时ET01;//分开关接通1EA1;//总开关1接通PT00;//优先级配置}////void Timer0Init(void) //1毫秒12.000MHz计时器T0////{//// TMOD 0x01; //设置定时器模式将前4位置0不用T1计时器用T0// TR0 1; //定时器0开始计时//// TL0 64535%256; //设置定时初值低位64535%256//// TH0 64535/256; //设置定时初值高位64535/256与65535相差1000溢出//// TF0 0; //清除TF0标志定时器标志0表示使用它//// ET01;//分开关接通1//// EA1;//总开关1接通//// PT00;//优先级配置//}/* TMODGATE C/T M1 M0//T1计时器 GATE C/T M1 M0//T0计时器 GATE 0-TR0 1-TL0-TH0-TF0 0-ET01-EA1-PT00(可省略) 设置模式-开始计时-设置范围-清除TF0标志-分开关接通1-总开关1接通-优先级配置 *//* 定时器中断函数模板 void Timer0Routine() interrupt 1//1是T0计时器的中断 { static unsigned int T0Count; TL0 0x18; //设置定时初值 TH0 0xFC; //设置定时初值 T0Count; if(T0Count1000) { T0Count0; } } *///void main()//{// Timer0_Init();// while(1)// {//// }//}//void Timer0Routine() interrupt 1//1是T0计时器的中断//{// static unsigned int T0Count;// TL0 0x18; //设置定时初值// TH0 0xFC; //设置定时初值// T0Count;// if(T0Count1000)//隔一秒执行一次// {// T0Count0;// P1_0~P1_0;//过1秒变一次// }//}#ifndef__TIMER0_H__#define__TIMER0_H__voidTimer0Init(void);#endif1. 引言在 51 单片机开发中定时器Timer是最常用也最基础的外设之一。无论是 LED 闪烁、数码管动态扫描、按键消抖还是产生精确的延时都离不开定时器。本文以STC89C52 / AT89C52系列单片机为例围绕Timer0 定时器从寄存器配置、初始化代码、中断服务函数到实际应用逐行讲解并配以可视化表格与流程图帮助你彻底吃透定时器的用法。2. 定时器核心概念2.1 什么是定时器定时器本质上是一个16 位加法计数器它由两个 8 位寄存器TH0高 8 位和TL0低 8 位拼接而成。当计数溢出从 65535 回到 0时硬件会自动将TF0标志位置 1并向 CPU 发出中断请求。2.2 定时器工作模式Timer0 有 4 种工作模式由TMOD寄存器的M1 M0两位决定模式M1 M0功能说明常见用途模式 00013 位定时器兼容旧 8048很少使用模式 10116 位定时器最常用精确延时、LED 闪烁模式 2108 位自动重装定时器波特率发生器模式 311两个独立 8 位定时器特殊场景本文代码采用模式 116 位定时器这也是初学者最应掌握的模式。2.3 定时器工作流程否是设置 TMOD 工作模式装载初值 TH0/TL0TR0 1 启动计时计数器逐 1 累加是否溢出 65535?TF0 置 1触发中断中断服务函数执行重装初值继续计时3. 寄存器逐位讲解3.1 TMOD 寄存器TMOD是一个 8 位寄存器高 4 位控制 Timer1低 4 位控制 Timer0位76543210名称GATEC/TM1M0GATEC/TM1M0所属Timer1Timer1Timer1Timer1Timer0Timer0Timer0Timer0代码中的两行配置TMOD0xF0;// 把低 4 位清零不影响 Timer1 的高 4 位TMOD|0x01;// 低 4 位 0001即 M10, M01 → 模式 13.2 初值计算定时器从初值开始累加直到 65535 溢出。若晶振为11.0592MHz机器周期为12 / 11.0592MHz ≈ 1.085μs定时 1ms 所需计数为计数个数 1000μs / 1.085μs ≈ 921.6 ≈ 922 初值 65536 - 922 64614 0xFC66因此TH00xFC;// 高 8 位TL00x66;// 低 8 位3.3 各寄存器作用一览寄存器/位作用代码示例TMOD配置工作模式TMOD 0xF0; TMODTH0/TL0装载定时初值TH0 0xFC; TL0 0x66;TF0溢出标志需清零TF0 0;TR0启动/停止计时TR0 1;ET0定时器 0 中断使能分开关ET0 1;EA总中断使能总开关EA 1;PT0中断优先级可省略PT0 0;4. 初始化代码逐行讲解以下为11.0592MHz 晶振、1ms 定时的完整初始化函数voidTimer0Init(void)//1毫秒11.0592MHz计时器T0{TMOD0xF0;//设置定时器模式把TMOD的低4位清零高4位不变TMOD|0x01;//设置定时器模式将前4位置0不用T1计时器用T0给最低位置1高4位不变TL00x66;//设置定时初值低位64535%256TH00xFC;//设置定时初值高位64535/256TF00;//清除TF0标志定时器标志0表示使用它TR01;//定时器0开始计时ET01;//分开关接通1EA1;//总开关1接通PT00;//优先级配置}4.1 逐行解释行号代码作用1TMOD 0xF0;清零低 4 位保留高 4 位不影响 Timer12TMOD 0x01;3TL0 0x66;装载初值低 8 位4TH0 0xFC;装载初值高 8 位5TF0 0;清除溢出标志防止误触发中断6TR0 1;启动定时器开始计时7ET0 1;打开定时器 0 中断分开关8EA 1;打开总中断总开关9PT0 0;设为低优先级可省略注意TMOD 0xF0与TMOD | 0x01的顺序不能颠倒否则会先清掉刚设置的位。5. 中断服务函数定时器溢出后CPU 自动跳转到中断服务函数。interrupt 1表示这是Timer0 的中断向量号voidTimer0Routine()interrupt1{staticunsignedintT0Count;TL00x66;//重装初值TH00xFC;//重装初值T0Count;if(T0Count1000)//累计 1000 次 1 秒{T0Count0;P1_0~P1_0;//LED 翻转}}5.1 为什么需要重装初值定时器溢出后自动归零若不重装初值下一次计时将从 0 开始导致定时不准。因此在中断函数开头必须重新写入TH0和TL0。5.2 中断流程否是1ms 定时溢出进入中断服务函数重装初值 TH0/TL0T0CountT0Count 1000?返回主程序T0Count 0P1_0 翻转6. 主函数与完整应用voidmain(){Timer0Init();//初始化定时器while(1){//主循环可做其他任务}}6.1 应用效果定时周期累计次数实际效果1ms1定时器中断触发1ms1000约 1 秒1ms1000LED 翻转一次通过修改T0Count的阈值可以灵活控制 LED 闪烁频率无需占用 CPU 主循环。7. 头文件封装将初始化函数封装到头文件便于多文件工程复用// Timer0.h#ifndef__TIMER0_H__#define__TIMER0_H__voidTimer0Init(void);#endif// main.c#includeREGX52.H#includeTimer0.hvoidmain(){Timer0Init();while(1);}8. 常见问题与调试技巧问题可能原因解决方案LED 不闪烁未开总中断EA检查EA 1;定时不准晶振频率与初值不匹配按实际晶振重算初值中断不触发ET0未置 1检查分开关程序跑飞初值未重装中断函数内重装TH0/TL09. 总结本文从寄存器、初值计算、初始化代码、中断服务函数到完整应用系统讲解了 51 单片机 Timer0 定时器的用法。核心要点模式选择TMOD | 0x01选择 16 位模式初值装载根据晶振频率计算TH0/TL0中断使能ET0 1分开关EA 1总开关初值重装中断函数内必须重新装载初值。掌握定时器后你可以进一步学习 PWM 输出、频率测量、数码管动态扫描等进阶应用。