搜索文档
定时/计数器
- 51 单片机中有两个 16 位的定时计数器。
- 每个 16 位的定时计数器最大计算能力位:65536(2^16)
- 分类
- 加计数器:计数初值 = 最大计数值 - 计数值。
- 减计数器:计数初值 = 计数值。
- 工作模式
- 定时模式
- 计数模式
- 工作方式:方式 0 ~ 方式 3
- 方式 0:13 位
- 方式 1:16 位
- 方式 2:8 位,自动载入初值
- 方式 3:8 位
操作步骤
设置工作模式
TMOD 寄存器结构图

- GATE:门控信号。0-软件开启 1-硬件开启
- C/~T:0-定时模式 1-计数模式
- M1:M0:00、01、10、11 设置 4 种工作方式。
- TMOD 不支持位寻址。
TMOD 寄存器设置 T0 为软件开启,工作在计时模式,工作方式是方式1。
写入计数初值
计数初值较大,需要用两个 8 位寄存器存储。
借助 TH0、TL0、TH1、TL1 寄存器完成初值的存储。

开启
通过 TCON 寄存器的高 4 位完成软开启工作。
TCON 寄存器结构图

- TR0:T0 的软开关。0-关闭 1-开启
- TF0:T0 的溢出标识位。0-正常 1-计数结束。
- TR1/TF1 同上。
查询法
设计并开启一个软开启的计数器 T0,工作方式为方式1,计数值为 3000。
c#include <STC12C5A60S2.H> void init(void) { TMOD = 0x05; TH0 = (65536 - 3000) / 256; TL0 = (65536 - 3000) % 256; TR0 = 1; } void main(void) { init(); }设计并开启一个软开启的计数器 T0,工作方式为方式1,计数值为 3。用计数器控制 LED 的亮灭。
c#include <STC12C5A60S2.H> sbit LED = P1 ^ 0; void init(void) { LED = 1; TMOD = 0x05; TH0 = (65536 - 3) / 256; TL0 = (65536 - 3) % 256; TR0 = 1; } void main(void) { init(); while (1) { if (TF0) { TR0 = TF0 = 0; TH0 = (65536 - 3) / 256; TL0 = (65536 - 3) % 256; LED = ~LED; TR0 = 1; } } }
定时计数器中断
触发条件:当定时计数器完成工作后回出发定时计数器中断。
中断处理子函数执行完后,CPU 自动将 TF0/TF1 自动清零。
开启中断 —— IE 寄存器

- EA:中断总开关
- ES:串型中断
- ET1:定时计数器 1 中断开关
- EX1:外部中断 1 开关
- ET0:定时计数器 0 中断开关
- EX0:外部中断 0 开关
中断处理子函数:文档
cvoid timer0(void) interrupt 1 { …… }例:通过定时计数器中断控制 LED 的亮灭。
c#include <STC12C5A60S2.H> typedef unsigned int UI; typedef unsigned char UC; sbit LED = P1 ^ 0; void storageInitValue() { TR0 = 0; TH0 = (65536 - 50000) / 256; TL0 = (65536 - 50000) % 256; TR0 = 1; } // 初始化 void init() { LED = 1; EA = 1; ET0 = 1; TMOD = 0x01; storageInitValue(); } void main() { init(); while(1); } // 定时计数器 0 中断处理子函数 void testTime0() interrupt 1 { static UC count = 0; count = ++count % 10; if (count) storageInitValue(); else LED = ~LED; }
时基
- 时基:时间基础。
- 时基值取决于时钟晶振的频率。
- 一个时基大小就是一个机器周期
总结
外部中断
- 开中断。IE 寄存器
- 设置中断请求信号类型。TCON 寄存器
- 中断处理子函数。关键字:interrupt
定时/计数器
- 设置工作模式。TMOD 寄存器
- 写入计数初值。TH0、TL0、TH1、TL1
- 启动。TCON 寄存器的高 4 位
定时/计数器中断
- 开中断。IE 寄存器
- 中断处理子函数。
