Proteus 仿真 STC89C52 定时器时钟计时
很多同学在学单片机时,看到“定时器”“中断”就头疼,觉得代码复杂难记,单片机自学困难。其实做一个定时器时钟,核心原理特别简单——就像给单片机装了个“电子秒表”,咱们只要搞懂这个秒表怎么用,不用死记函数也能上手。当 count 记到1000时,就说明“1秒过去了”,这时让秒数( sec )加1,再把 count 清零重新记。定时器“满了”之后,里面的水会清空,必须在中断里重新装回初值,不然下次要等6
很多同学在学单片机时,看到“定时器”“中断”就头疼,觉得代码复杂难记,单片机自学困难。其实做一个定时器时钟,核心原理特别简单——就像给单片机装了个“电子秒表”,咱们只要搞懂这个秒表怎么用,不用死记函数也能上手。
一、为什么非要用定时器做时钟?
先想个简单问题:怎么让单片机知道“1秒过去了”?
如果用 delay(1000) 这样的延时函数,看似能实现,但有两个大问题:
- 延时的时候,单片机啥也干不了(比如数码管会一直黑着,没法实时显示);
- 延时时间特别不准,程序多一行少一行,1秒可能变成1.5秒,一天下来能差好几分钟。
而定时器就不一样了:
它像一个独立的“后台秒表”,自己默默计时,不耽误单片机做其他事(比如刷新数码管);而且时间由硬件控制,误差特别小,走一天可能也就差几秒钟。
二、定时器的核心逻辑:就像给杯子装水
用一个生活例子就能讲明白定时器的工作原理:
假设我们有一个杯子(定时器),杯子最多能装65535滴水(16位定时器的最大计数)。现在想让杯子每1毫秒就“满一次”(触发一次中断),该怎么做?
很简单:先往杯子里装一部分水,剩下的空间刚好能装922滴水(11.0592MHz晶振下,1毫秒需要的计数次数)。这样每加922滴水,杯子就满了,我们就知道“1毫秒过去了”。
这里的“装一部分水”,就是代码里的“装初值”;“杯子满了”就是“定时器溢出”,会触发中断告诉单片机“时间到了”。
三、从1毫秒到1秒:定时器怎么“数时间”?
1. 让定时器每1毫秒“提醒”一次
单片机的晶振(比如11.0592MHz)会不断产生脉冲,就像“水滴”。12个脉冲相当于1滴,定时器每接1滴就“数1次”。
要让它1毫秒后提醒,就需要算好“提前装多少水”:
- 1毫秒 = 1000微秒,1滴水下落的时间约1.085微秒(12÷11.0592MHz);
- 1毫秒需要的水滴数:1000÷1.085≈922滴;
- 所以提前装的水 = 65535 - 922 + 1 = 64614(+1是因为最后1滴会让杯子刚好满)。
代码中使用官方例程直接由单片机自行计算得出


PS:平时可使用STC-ISP烧录软件精准生成定时函数

2. 累计1000个“1毫秒”就是1秒
定时器每1毫秒“提醒”一次(触发中断),我们就记一个数(比如用 count这个变量)。当 count 记到1000时,就说明“1秒过去了”,这时让秒数( sec )加1,再把 count 清零重新记。
3. 时、分、秒的进位逻辑
这和普通时钟一样:
- 秒数到60,就清零,让分钟( min )加1;
- 分钟到60,就清零,让小时( hour )加1;
- 小时到24,就清零(24小时制)。
四、代码不用死记,理解原理即可
不用纠结函数怎么写,记住定时器工作的3个关键步骤:
1. “启动秒表”——初始化定时器
告诉单片机:用哪个定时器(比如定时器0)、工作模式(选16位模式最常用)、提前装多少水(初值)、允许它“提醒”(开中断)。

2. “秒表响了”——中断服务函数
定时器每1毫秒“响一次”,这里就做两件事:
- 重新装水(不然下次要等满杯65535滴,时间就错了);
- 让 cnt 加1,满1000就给秒数加1,再处理进位。

3.进制转换逻辑

4. “显示时间”——主循环
将时分秒写入缓存区域,在主程序不用管计时,只要不停刷新数码管,把当前的 hour 、 min 、 sec 显示出来就行。

五、Proteus仿真验证功能
仿真图可直接使用上期8位数码管动态显示图,具体绘制流程不在重复,直接展示结果!

8位共阳数码管动态显示链接
六、新手最容易踩的3个坑
1. 计时不准?可能初值算错了
晶振频率不一样,1毫秒需要的“水滴数”也不一样。如果用12MHz晶振,初值就不是0xFC18了,得重新算。建议使用软件直接生成。
2. 秒数跳得快?没重新装初值
定时器“满了”之后,里面的水会清空,必须在中断里重新装回初值,不然下次要等65535滴才会响,时间就变长了。(STC89系列单片机无法自动重装初值,STC15,STC8等其他系列可自动重装)
3. 显示乱闪?中断里别写太多代码
中断服务函数要尽量简单,只做计数和进位。如果在里面写复杂的显示代码,会耽误下一次计时,导致时间不准。
其实核心就两句话:
- 给定时器装个初值,让它每1毫秒“提醒”一次;
- 累计1000次提醒就是1秒,再处理时、分、秒的进位。
如需完整工程链接,请在评论区留言或者VX公众号内回复 VX搜索"从0起单片机"
FZ_STC89C52_003#
收到后自动发送本工程链接
欢迎关注(VX公众号定时分享单片机实例,助力大家实现从0到1的成长)
更多推荐



所有评论(0)