51单片机晶振12MHz,要求T0方式0定时2ms,TH、TL初值计算。写出初始化程序
时间: 2024-12-04 11:26:51 浏览: 80
51单片机(如8051系列)的T0定时器用于计数脉冲信号,以实现周期性的定时任务。当晶振频率设置为12MHz时,即每秒有1200万个时钟周期。T0定时2ms,需要将时钟周期转换为微秒,因为2ms等于2000μs。
T0定时器在方式0下工作,此时它是16位计数器,每次从TH0加载高8位,TL0加载低8位数据后自动加一,溢出标志TF0置1。为了定时2ms,我们需要找到对应的计数值使得T0溢出两次,也就是计数到2^16 - 1(因为16位计数满后会从0开始)。
首先,我们计算总的计数次数:
总计数 = (2^16 - 1) / 每次计数次数
由于12MHz的时钟频率,每个机器周期是1us,所以每次计数需要1us。因此:
每次计数次数 = 1us / 每次计数时间 = 1us / 1us = 1
现在我们可以计算总的计数次数:
总计数 = 2^16 - 1 = 65535
既然每次计数是1,那么2ms就是65535次。但是T0的计数是从0开始的,所以我们需要减去一次:
实际计数次数 = 总计数 - 1 = 65535 - 1 = 65534
接下来,我们将这个计数值分配给TH0和TL0。对于16位计数,最高位是TH0,最低位是TL0。由于是连续计数,我们可以简单地除以2得到两个寄存器的初始值。由于16位补码运算规则,TH0通常存储高位(最高有效位),TL0存储低位(最低有效位):
TH0 = 实际计数次数 / 2 = 65534 / 2 = 32767
TL0 = 实际计数次数 % 2 = 65534 % 2 = 0
下面是初始化程序的大致步骤(以AT89S51为例,假设已经打开了中断并设置了T0的工作方式0):
```c
#include <reg51.h>
void T0Init() {
// 设置T0工作于方式0
TMOD &= ~0x0F; // 清除TMOD的模式控制位
TMOD |= 0x01; // 设置为定时器0,16位计数
// 设置外部晶振12MHz
SFRPAGE = 0x80; // 进入特殊功能寄存器页2
TH0 = 0x3FFF; // 初始化TH0为32767
TL0 = 0x00; // 初始化TL0为0
// 开启T0计数
TR0 = 1;
// 关闭CPU内部时钟分频
EA = 1; // 开启全局中断
}
```
注意,这个程序只是一个基本示例,实际应用中可能还需要考虑其他因素,比如复位后是否需要清零计数器、以及如何处理溢出中断等。
阅读全文