最近在看51单片机的定时器与中断,作为51单片机比较重点的内容,很多人也花费了很长时间在这上面,有些问题网上的资料方法各不相同,也看得云里雾里,比如定时器的初值计算问题,在此我想以此篇作为学习笔记,希望可以对大家有所帮助。
方法一
定时器内部一寄存器,每隔一个机器周期就会自动加1,直到加到65535就会溢出。比如假设51单片机的晶振频率为11.05926MHz,那么时钟周期为1/11059260,51单片机的机器周期为12个时钟周期,(周期单位为s)计算一下这个机器周期长度为12*(1/11059260),即每隔12*(1/11059260)(s)加1,我们可以发现从0开始加到65535所需的时间一共是12*(1/11059260)*65535 = 0.07110964s = 71.10964ms.
如果我们定义10ms,那么需要计算从哪一个初值加到65535所需时间正好为10ms,我们设初值为x,(65535-x)*机器周期 = 0.01s.可以计算出x = 56319,假设定时器工作在模式1,此时TH0 和 TL0 组成一个 16 位的定时器,TH0是定时器 1 高八字节,TL0是定时器 1 低八字节,如何计算高八字节与低八字节呢?
我们给出一个数42,怎么计算十位数和各位数呢?其实在C语言中,十位数 = 42/10,个位数为42%10.同理,我们可以类似得出高八字节、低八字节的计算方法,2的8次方为256,那么高八字节TH0 = 56319/256,低八字节TL0 = 56319%256。然后设置好定时器控制寄存器便可以写出C51程序。
代码如下所示:
#include<reg52.h>
sbit LED = P2^0;
unsigned char cnt = 0;
void main()
{
LED = 0;
TMOD = 0x01;
TH0 = 56319/256;
TL0 = 56319%256;
TR0 = 1;
while(1)
{
if(TF0 == 1)
{
TF0 = 0;
cnt++;
TH0 = 56319/256;
TL0 = 56319%256;
if(cnt == 100)
{
cnt = 0;
LED = ~LED;
}
}
}
}
此程序为时隔1sLED闪烁程序
方法二
大家是否注意到STC官方手册上定时器的使用方法呢,下图为STC89C52RC官方手册定时器部分截图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200308134234228.png)
这是STC官网文档上给出的计算定时器初值的方法。
第一行是定义晶振频率,后面的L表示长整型数据,重点来看第二行,
我们已经知道:51单片机中,机器周期等于12个时钟周期(所有单片机不一定都是12),机器周期 = 12*(1/FOSC);机器周期还等于计数次数,因为经过一个机器周期加1;
机器周期 = 计数次数= 12*(1/FOSC);
1s中有多少机器周期 = 1s中有多少计数次数 = FOSC /12;
1ms中有多少机器周期 = 1ms中有多少计数次数 = FOSC /12/1000;
那么如果我们定义1ms,此时定时器初值 = 65535 - FOSC /12/1000;
根据TH0、TL0分别为高八位与低八位,
TH0 = (65535 - FOSC /12/1000)/256;
TL0 = (65535 - FOSC /12/1000)%256;
或者
令T1MS = 65535 - FOSC /12/1000;
TL0 = T1MS;
TH0 = T1MS>>8;
代码如下图(下图定义的为10ms):
#include<reg52.h>
sbit LED = P2^0;
#define FOSC 11059200L
#define T1MS (65535-FOSC/12/100)
unsigned char cnt = 0;
void main()
{
LED = 0;
TMOD = 0x01;
TL0 = T1MS;
TH0 = T1MS>>8;
TR0 = 1;
while(1)
{
if(TF0 == 1)
{
TF0 = 0;
cnt++;
TL0 = T1MS;
TH0 = T1MS>>8;
if(cnt == 100)
{
cnt = 0;
LED = ~LED;
}
}
}
}
此程序为时隔1sLED闪烁程序
此篇只作为学习笔记,如有错误,敬请批评指正!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)