微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机之寄存器-3.1单片机定时器

51单片机之寄存器-3.1单片机定时器

时间:11-21 来源:互联网 点击:

前面讲了定时时间是通过TH0和TL0来控制的,那么使用TH0和TL0之前先要设定工作模式,用16bit还是8bit或者其他。这里我们选择16bit。怎么选呢?表1中给出了定时器0和1工作模式的控制寄存器,8个位的初始化值都是0,绿色部分用来控制定时器1,黄色部分用来控制定时器0,现在我们只看黄色部分。一共4个控制位,Gate,C/T,M1,M0. 很容易看到,Gate,C/T都要设置0,现在要选中16bit的工作模式,那么M1M0=01. 因此TMOD=00000001=0X01 假设在图2中,TL0,TH0初始值为0,那么16bit最多可以装下65535,考虑到溢出,因此这里取65536,每装一个数需要(12/11.0592)Us,那么装65536需要,UnitT=65536×(12/11.0592)约等于71000Us,也就是71ms. 现在我要定时1s,很明显,TH0和TL0不够用,那是不是要多增加几个TH0和TL0,没有必要。我们可以通过软件来解决硬件上的不足,最简单的方式就是使用循环多次。比如我让UnitT为10ms,那么循环100次就是1秒了。那么怎么设置UnitT=10000Us, UnitT=(65536-X) × (12/11.0592)=10000Us, 其中X为TH0和TL0组成的16bit的初始值。将这个等式改进一下:

UnitT=(65536-X) / 0.9216, 在该式中UnitT×0.9216要小于65536,并且要保证UnitT×0.9216为正整数,因此UnitT的取值范围为:

10000

因此简单来看,UnitT可以取10ms, 20ms, 30ms, 40ms, 50ms, 60ms, 70ms,

再根据我们最终要定时的时间为1000ms, 因此UnitT只能取10ms, 20ms, 50ms,这样根据UnitT=(65536-X) / 0.9216就能计算出初始值X,

这里我们取UnitT=50ms, X=19456,16进制表示为: 4C00H, 因此TH0= 0X4C, THL0=0X00.

因此这样我们就确定了定时时间用的初始值,TH0和TL0,并且需要重复20次

(2) 启动定时器

如何启动定时器,查看表2定时器控制寄存器TCON,只要设置TR0=1即可。表2中涉及到中断的问题我们暂时不管,这里我们只讨论定时器,下一讲谈中断。这里为什么能直接设置TR0,为什么在设置定时器工作模式时不能直接设置M1M0,而要通过TMOD来设置。这个涉及到寻址方式的问题,我们暂时不讨论。

(3) 响铃通知

那么闹钟响铃对应定时器的哪个部分。前面我们设置了TH0和TL0,初始值为19456,然后不停的增大直到65535,再增大一个变成65536此时TH0和TL0装不下了,因此溢出,此时单片机通过硬件将TF0从0变为1来通知CPU,查看表2中TF0的说明可知。因此TF0的值对应着响铃。

(4) 点亮LED

我们要让LED延时1s后点亮或者熄灭,因此这里需要一个参数来对定时器TF0的溢出次数计数,当溢出20次时,表示定时到了1s。

这样我们很容易的得出程序的框架图,

参考代码如下:

#include "reg52.h"

sbit LED=P1^0;

void main(void)

{

unsigned char CYC = 0;

TMOD=0X01;

TH0=0X4C;

TL0=0X00;

TR0=1;

while(1)

{

if (TF0==1)

{

TF0=0;

TH0=0X4C;

TL0=0X00;

CYC++;

if(CYC==20)

{

CYC=0;

if(LED==0)

{

P1=0XFF ;

LED=1;

}

else

{

LED=0;

P1=0X00;

}

}

}

}

}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top