定时器与计数器
STC89C52 内置 3 个 16 位定时器/计数器(T0、T1、T2),是单片机编程中最常用的外设之一。
基本概念
- 定时器模式:对内部机器周期(晶振分频后的时钟)计数,实现精确定时
- 计数器模式:对 P3.4/T0 或 P3.5/T1 引脚的外部脉冲计数
定时器 0 和定时器 1
相关 SFR
| 寄存器 | 地址 | 功能 |
|---|---|---|
| TMOD | 89H | 模式控制(T0 低 4 位,T1 高 4 位) |
| TCON | 88H | 运行控制和溢出标志(可位寻址) |
| TH0 | 8CH | 定时器 0 高 8 位 |
| TL0 | 8AH | 定时器 0 低 8 位 |
| TH1 | 8DH | 定时器 1 高 8 位 |
| TL1 | 8BH | 定时器 1 低 8 位 |
工作模式
模式 0 — 13 位定时器
- THx 8 位 + TLx 低 5 位 = 13 位
- 最大计数值:2^13 = 8192
- 已基本弃用,了解即可
模式 1 — 16 位定时器(最常用)
- THx 8 位 + TLx 8 位 = 16 位
- 最大计数值:2^16 = 65536
- 定时范围最灵活
模式 2 — 8 位自动重载(常用)
- TLx 8 位计数,THx 8 位存重载初值
- 溢出后 TLx 自动从 THx 重载
- 适合产生精确定时脉冲(如串口波特率)
模式 3(仅定时器 0)
- 定时器 0 拆分为两个独立的 8 位定时器:TL0 和 TH0
- 定时器 1 在此模式下停止运行
初值计算
以 12MHz 晶振、12T 模式为例: - 机器周期 = 12 / 12MHz = 1μs - 定时 1ms 需要的计数值 = 1000μs / 1μs = 1000 - 初值 = 65536 - 1000 = 64536 = 0xFC18
// 定时器 0 初始化,模式 1(16 位),定时 1ms
void Timer0_Init() {
TMOD &= 0xF0; // 清除 T0 配置位
TMOD |= 0x01; // T0: 模式 1(16 位定时器)
TH0 = 0xFC; // 高 8 位初值
TL0 = 0x18; // 低 8 位初值
ET0 = 1; // 使能定时器 0 中断
EA = 1; // 开总中断
TR0 = 1; // 启动定时器 0
}
// 定时器 0 中断服务函数
void Timer0_ISR() interrupt 1 {
TH0 = 0xFC; // 重载初值(模式 1 需手动重载)
TL0 = 0x18;
// 用户代码:每 1ms 执行一次
}
自动重载模式(模式 2)示例
// 定时器 1 模式 2,用于串口波特率发生器
void Timer1_Init() {
TMOD &= 0x0F; // 清除 T1 配置位
TMOD |= 0x20; // T1: 模式 2(8 位自动重载)
TH1 = 0xFD; // 重载值(11.0592MHz 下 9600bps)
TL1 = 0xFD; // 当前计数值
TR1 = 1; // 启动定时器 1
}
定时器 2
相关 SFR
| 寄存器 | 地址 | 功能 |
|---|---|---|
| T2CON | C8H | 控制寄存器(可位寻址) |
| T2MOD | C9H | 模式寄存器 |
| TH2 | CDH | 高 8 位 |
| TL2 | CCH | 低 8 位 |
| RCAP2H | CBH | 捕获/重载高字节 |
| RCAP2L | CAH | 捕获/重载低字节 |
工作模式
| 模式 | 功能 |
|---|---|
| 16 位自动重载 | 与 T0/T1 模式 2 类似,但为 16 位 |
| 16 位捕获 | 检测外部信号跳变时捕获当前计数值 |
| 波特率发生器 | 串口模式 1 和 3 的波特率可选由 T2 产生 |
| 可编程时钟输出 | 从 P1.0 输出可编程频率的方波 |
自动重载模式初值计算
// 定时器 2,16 位自动重载,定时 50ms(12MHz,12T)
// 计数值 = 50000μs / 1μs = 50000
// 初值 = 65536 - 50000 = 15536 = 0x3CB0
void Timer2_Init() {
T2CON = 0x00; // 停止定时器 2
RCAP2H = 0x3C; // 高 8 位重载初值
RCAP2L = 0xB0; // 低 8 位重载初值
TH2 = 0x3C; // 当前计数值高 8 位
TL2 = 0xB0; // 当前计数值低 8 位
ET2 = 1; // 使能定时器 2 中断
EA = 1; // 开总中断
TR2 = 1; // 启动定时器 2(T2CON.2)
}
void Timer2_ISR() interrupt 5 {
TF2 = 0; // 清除溢出标志(需软件清零)
// 用户代码:每 50ms 执行一次
}
1T/12T 速度模式
STC89C52 可通过 AUXR 寄存器的 T0x12/T1x12 位选择定时器速度: - 12T 模式(默认):传统兼容,机器周期 = 12 时钟 - 1T 模式:加速模式,机器周期 = 1 时钟(速度快 12 倍)
⚠️ 切换 1T 模式时初值需重新计算(计数值 ×12)
定时器用作计数器
只需将 TMOD 中的 C/T 位置 1: - T0 计数输入:P3.4 引脚 - T1 计数输入:P3.5 引脚 - 外部脉冲下降沿触发计数