目录
0.2例子1:基于AT89C51单片机的定时器控制数码管显示时间
[1.1 AT89C52的3个定时器](#1.1 AT89C52的3个定时器)
[1.2定时器在单片机里的 4 大作用](#1.2定时器在单片机里的 4 大作用)
[1.3 四种工作方式(T0/T1)](#1.3 四种工作方式(T0/T1))
[1.4使用步骤(以T0方式12 MHz 晶振产生 1 ms 中断为例)](#1.4使用步骤(以T0方式12 MHz 晶振产生 1 ms 中断为例))
[1.4.1 算初值计算](#1.4.1 算初值计算)
[1.4.2 寄存器配置](#1.4.2 寄存器配置)
3例子2:基于AT89C51单片机的定时器控制数码管显示时间
[4 硬件工程师笔试面试相关文章链接(部分链接)](#4 硬件工程师笔试面试相关文章链接(部分链接))
摘要:本文介绍了基于AT89C51单片机的定时器应用实例和基础知识。主要内容包括:1)AT89C52的3个定时器及其4大作用;2)定时器的4种工作方式及使用步骤;3)两个具体案例:案例1实现0-99999.9秒数码管计时显示,案例2实现8位数码管分时显示年月日和时分秒;4)详细电路原理图和控制程序设计。文章还补充了频率单位、机器周期等基础知识,并提供了硬件工程师笔试面试相关资源链接。这些内容为单片机定时器应用开发提供了实用参考。
0 案例视频效果展示
0.1 例子 1 :基于 AT89C51 单片机的定时器计数器
例子34:基于AT89C51单片机的定时器计数器
0.2例子1:基于AT89C51单片机的定时器控制数码管显示时间
例子35:基于AT89C51单片机的定时器控制数码管显示
1 基础知识补充
频率单位:赫兹 (Hz)
1 赫兹 (Hz) :每秒 1 次 周期: 1s
1 千赫兹 (Hz) :每秒 1000 次 周期: 1ms
1 兆赫兹 (Hz) :每秒 1000000 次 周期: 1us
1 吉兹 (Hz) :每秒 1000000000 次 周期: 1ns
机器周期(Machine Cycle)是 8051 单片机 执行一条指令的基本时间单位。理解它对于计算延时、定时器初值、波特率等都非常关键。
总结:
8051 的机器周期 = 12 × 时钟周期
12MHz 晶振下, 1 机器周期 = 1μs
1.1 AT89C52的3个定时器
3个16位可编程定时/计数器:T0、T1、T2
T0、T1:标准 8051 兼容(方式 0~3)
T2:8052 专有,功能更强(可 16 位自动重装、捕获、波特率发生等)
1.2定时器在单片机里的 4 大作用
产生精确定时(1 ms、10 ms、1 s......)
对外部脉冲计数(T0/T1 脚当计数输入)
生成波特率(UART 方式 1、3 时)
做PWM/脉冲测量/电机测速(配合 T2 捕获功能)
1.3 四种工作方式(T0/T1)
|--------|-------------|---------|---------------|
| 方式 | 位数 | 特点 | 典型用途 |
| 0 | 13 位 | 早期兼容,少用 | 特殊场合 |
| 1 | 16 位 | 一次溢出重装 | 1 ms、50 ms 基时 |
| 2 | 8 位自动重装 | 低字节自动回装 | 波特率、高频中断 |
| 3 | T0 分成两个 8 位 | T1 失去中断 | 特殊应用 |
1.4使用步骤(以T0方式12 MHz 晶振产生 1 ms 中断为例)
1.4.1 算初值计算
机器周期 = 1 µs(12 MHz/12)
1 ms 需计数 1000 次 → 初值 = 65536 − 1000 = 64536 = 0xFC18
定时器 T0 设置
objectivec
TMOD &= 0xF0; // 清零 T0 位
TMOD |= 0x01; // T0 方式 1
定时周期 (1ms)
objectivec
TH0 = 0xFC; // 高 8 位
TL0 = 0x18; // 低 8 位
1.4.2 寄存器配置
定时器 T0
objectivec
TMOD &= 0xF0; // 清零 T0 位
TMOD |= 0x01; // T0 方式 1
TH0 = 0xFC; // 高 8 位
TL0 = 0x18; // 低 8 位
TR0 = 1; // 启动 T0
ET0 = 1; // 允许中断
EA = 1; // 总中断
定时器 T0 中断服务函数
objectivec
void Timer0_ISR(void) interrupt 1
{
TH0 = 0xFC; // 重装初值
TL0 = 0x18;
/* 用户代码:计数、刷新显示、产生 PWM 等 */
}
2 例子 1 : 基于 AT89C51 单片机的定时器计数器
实现功能:使用定时器在6只数码管上完成0~99 999.9s计数。
本质:使用定时器精确计时,将计数值(0~99 999.9秒)动态扫描显示在6只数码管上。
2.1 电路原理图

2.1.1 电路组成及接线
|------------|----------------------------------------------------------------------------------|
| 名称 | 接线 |
| AT89C51单片机 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->总线收发器/排阻 P3.0-P3.5--->6位数码管 |
| 复位电路 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->总线收发器/排阻 P3.0-P3.5--->6位数码管 |
| 晶振电路 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->总线收发器/排阻 P3.0-P3.5--->6位数码管 |
| 排阻 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->总线收发器/排阻 P3.0-P3.5--->6位数码管 |
| 6位数码管 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->总线收发器/排阻 P3.0-P3.5--->6位数码管 |
| 总线收发器 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->总线收发器/排阻 P3.0-P3.5--->6位数码管 |
2.2 控制程序
2.2.1 控制程序步骤
库文件与引脚定义
16进制段码
延时函数
主程序(秒表计数)
T0中断函数
2.2.3 源代码
objectivec
//功能:使用定时器在6只数码管上完成0~99 999.9s计数。
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//段码
uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//6只数码管上显示的数字
uchar Digits_of_6DSY[]={0,0,0,0,0,0};
uchar Count;
sbit Dot=P0^7;
//延时
void DelayMS(uint ms)
{
uchar t;
while(ms--) for(t=0;t<120;t++);
}
//主程序
void main()
{
uchar i,j;
P0=0x00;
P3=0xff;
Count=0;
TMOD=0x01; //计数器T0方式1
TH0=(65536-50000)/256; //50ms定时
TL0=(65536-50000)%256;
IE=0x82;
TR0=1; //启动T0
while(1)
{
j=0x7f;
//显示Digits_of_6DSY[5]~Digits_of_6DSY[0]的内容
//前面高位,后面低位,循环中i!=-1亦可写成i!=0xff
for(i=5;i!=-1;i--)
{
j=_crol_(j,1);
P3=j;
P0=DSY_CODE[Digits_of_6DSY[i]];
if(i==1) Dot=1; //加小数点
DelayMS(2);
}
}
}
//T0中断函数
void Timer0() interrupt 1
{
uchar i;
TH0=(65536-50000)/256; //恢复初值
TL0=(65536-50000)%256;
if(++Count!=2) return;
Count=0;
Digits_of_6DSY[0]++; //0.1s位累加
for(i=0;i<=5;i++) //进位处理
{
if(Digits_of_6DSY[i]==10)
{
Digits_of_6DSY[i]=0;
if(i!=5) Digits_of_6DSY[i+1]++; //如果0~4位则分别向高一位进位
}
else break; //若某低位没有进位,怎循环提前结束
}
}
3 例子 2 :基于 AT89C51 单片机的定时器控制数码管显示时间
实现功能:8个数码管上分两组动态显示年月日与时分秒,显示延时用定时器实现。
本质:用定时器中断精确时序,驱动8位数码管高速交替扫描年月日与时分秒两组数据,利用人眼暂留实现无缝双显。
3.1 电路原理图

3.1.1 电路组成及接线
|------------|---------------------------------------------------------------------------------|
| 名称 | 接线 |
| AT89C51单片机 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->8位数码管 P2.0-P3.7--->三极管驱动电路 |
| 复位电路 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->8位数码管 P2.0-P3.7--->三极管驱动电路 |
| 晶振电路 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->8位数码管 P2.0-P3.7--->三极管驱动电路 |
| 8位数码管 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->8位数码管 P2.0-P3.7--->三极管驱动电路 |
| 三极管驱动电路 | XTAL1/XTAL2--->连接晶振电路 RST--->连接复位电路 P0.0-P0.7--->8位数码管 P2.0-P3.7--->三极管驱动电路 |
3.2 控制程序
3.2.1 控制程序步骤
库文件
16进制段码
主程序(秒表计数)
T0中断函数
3.2.3 源代码
objectivec
//功能:8个数码管上分两组动态显示年月日与时分秒,显示延时用定时器实现。
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//段码,最后一位是"-"的段码
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
//待显示的数据:09-12-25与23-59-58(分两组显示)
uchar code Table_of_Digits[][8]={{0,9,10,1,2,10,2,5},{2,3,10,5,9,10,5,8}};
uchar i,j=0;
uint t=0;
//主程序
void main()
{
P2=0x80; //位码初值
TMOD=0x00; //计数器T0方式0
TH0=(8192-4000)/32; //4ms定时
TL0=(8192-4000)%32;
IE=0x82;
TR0=1; //启动T0
while(1);
}
//T0中断函数控制数码管刷新显示
void DSY_Show() interrupt 1
{
TH0=(8192-4000)/32; //恢复初值
TL0=(8192-4000)%32;
P0=0xff; //输出位码和段码
P0=DSY_CODE[Table_of_Digits[i][j]];
P2=_crol_(P2,1);
j=(j+1)%8; //数组第i行的下一字节索引
if(++t!=350) return; //保持刷新一段时间
t=0;
i=(i+1)%2; //数组行i=0时显示年月日,i=1时显示时分秒
}
4 硬件工程师笔试面试相关文章链接(部分链接)
更多文章可前往主页观看
1、硬件工程师笔面试真题汇总(2025版本)_硬件工程师面试题-CSDN博客https://blog.csdn.net/XU157303764/article/details/140742900?spm=1011.2415.3001.5331硬件工程师笔试面试高频考点汇总------(2025版)_电容或者电感对锁存器的影响-CSDN博客
https://blog.csdn.net/XU157303764/article/details/1488349782、硬件工程师笔试面试汇总(2025版本)_硬件工程师面试题-CSDN博客
https://blog.csdn.net/XU157303764/article/details/1419048583、硬件工程师笔试面试学习汇总------器件篇目录(2025版本)_【【硬件工程师炼成之路】器件篇(更新中。。。)-CSDN博客
https://blog.csdn.net/XU157303764/article/details/142316204
硬件工程师笔记------电子器件汇总大全-CSDN博客https://blog.csdn.net/XU157303764/article/details/147342935?spm=1011.2415.3001.5331Multisim14使用教程详尽版--(2025最新版)-CSDN博客
https://blog.csdn.net/XU157303764/article/details/147197406?spm=1011.2415.3001.5331