在写一篇定时器的文章

STC单片机STC89C52RC定时器延时时间的计算

延时时间要根据晶振频率计算,不同板子可能有所不同。

时钟周期:
1/时钟源,在我现在这块板子上,晶振频率是11.0592M,也就是时钟周期是 1/11059200秒

机器周期:
一般51单片机是12个时钟周期,我的板子也就是 12/11059200秒

单次定时最长时间:
如果是16位的计数器,16位最大值是65535,共可计数65536次。基本的常数一定要记住,还要记住8位最大值是255,共可计数256次,还要记住8位上每位代表的数值。
12 * 65536/11059200 = 0.0711 s,也就是,71 ms内的定时可以单次定时就完成。如果定时时间超过71 ms,就要循环了。

一次定时需要几次机器周期:
计算公式:定时秒数/机器周期
比如我要定时1秒, 1/(12/11059200)= 921600次,16位计数器最大可计数65536次,921600次早就益出了。我们可以每次定时10 ms,循环100次就可以定时1秒了,1 s缩小100百倍就是10 ms, 也就是每次需要计数9216次。

确实计数器初始值:
定时10 ms时,如果计数器从0开始计数,我们就不知道什么时候到了9216次。所以应该计数了9216次,16位计数器最多计数95536次,然后就溢出,一溢出TCON的TF位就会置1,我们只要经常检测TF位就可以知道什么时候完成10ms的定时了。
计算公式:计数器初始值=最大计数次数 - 需要计数次数
如果定时10 ms,计数器的初始值就是 65536 - 9216

计算计数器的高位和低位:
16位的计数器,也就是两个8位组成,8位的最大计数次数是256。所以:
计数器高位 = 初始值/256
计数器低位 = 初始值%256


STC89C52RC单片机定时器示例代码:

#include <reg52.h>

//如果你的单片机没用74hc138扩展IO口,下面代码可略
sbit enableG1 = P1^3;
sbit enableG2 = P1^4;
sbit selectC  = P1^2;
sbit selectB  = P1^1;
sbit selectA  = P1^0;
void hc138()
{
         enableG1 = 1;
         enableG2 = 0;
         selectC  = 1;
         selectB  = 1;
         selectA  = 0;
}


typedef unsigned char uint8;
typedef unsigned int uint16;
// byhttp://hi.baidu.com/tuenhai/
/**
    1ms需要的机器周期 = 0.001/(12/11059200) = 921.6    
    要让led灯以7.83hz闪动, 周期是 1000 / 7.83 = 127.713 ms, 也就是每64 ms改变亮灭状态
**/
void main(void)
{    
    uint16 counter;

    hc138();

    TMOD = 0X01;
    TH0  = (65536 - 922) / 256;
    TL0  = (65536 - 922) % 256;
    TR0  =1;

    while(1)
    {
         if(TF0 == 1)
        {
            TF0 = 0;
            TH0  = (65536 - 922) / 256;
            TL0  = (65536 - 922) % 256;
            counter++;
        }

        if(counter == 64)
        {
             counter = 0;
            P0 = ~P0;
        }
    }
}

你可能感兴趣的:(定时器)