51单片机定时器详细全解.下

2022-06-27 14:27:21 浏览数 (1)

上篇文章太长了,快上4K字了,我要新开一篇继续写。

继续写这个定时器,注意的是,崽每个机器周期完成的时候计数。S5P2的时候如果采样到高变低的情况,认为是个脉冲。在下一个机器周期的S3P1进行计数。

除12,计数频率就是1Mhz,也就是微妙的级别

反过来就是装载值

结构框图

TH,TL X2 TMOD TCON,就这点东西。

TH 高8位,TL 低8位。,合起来就是16位的寄存器。

用来放T1计数器的初值,T1可以当作波特率的生成器

是一个单独的器件

8位的寄存器,44分开,高走1,低走0,M1M0搭配选功能

CT这里就是选择定时器的作用,GATE是外部引脚的干预

还有的就是TCON,TF是溢出标志位,可以用软件查这位,满的时候为1,查完写0 ,中断的时候为中断标志位,自动清0.

TR是启动位置,ET是中断控制。

方式0

此时为13位的定时器,低5高8,低5溢出的时候向高8进位,高8满的时候,触发TF位。

CT是决定工作模式

0的位置是,12分频后的计数信号。1是计时器。

还有门

GATE恒为0,A的点位恒为1,B点就取决于TR1这个位置。

计数脉冲加到T1的时候,允许T1计数,TRX为0,B为低电位,电子开关断开,禁止T1计数。

其实就是开关,前面不管多乱,后面就在安安静静的数数,一个俩个

方式1的话,就是TL,TH都启用了,全16位。剩下都一样了。

方式2 ,感觉很高级的一种

0,1方式在溢出后,计数器为0,在循环定时的时候需要重新装载这个计数器的初值。这个动作要耗费时间,而且你看,编程也麻烦。

那就有了这第二种做法,自动的装载初值。

TH高位做常数缓存器,低位溢出的时候,在把这个溢出的信号(TF=1)送出的时候,自动把TH中的常数送给TL,TL现在就有开始工作了。

好好记住是TL位置溢出的时候,TH装载

最后一种我就不说了,感觉现在说了没有意义。

。。。还是说了吧,0,1,2其实都是一个定时器搭配的使用。

这个模式就对T0生效,TL0和TH0就相当于2个八位的定时器。

现在有三个定时器了

此时T1做波特率发生器,同时把TF1的溢出位也占用了。

由于确定一次负跳变,需要两个机器周期,因此外部的脉冲频率最高位为1/24,12Mhz的晶体,可以输入的脉冲是500KHz,占空比没有限制,不过为了在给点电平变化前采样一次,这一电平至少也得保持一个机器周期。

Tcy是一个机器周期

如何输出一个方波,使用定时器。周期使用定时器T0来确定,使用中断。

在T0里面设置一个时间的常数(初值),没1ms中断一次,CPU响应以后,在ISR里面给IO取反。

初值的计算,机器周期=12/频率。

公式:(216– X)× 12 ÷ 晶振频率 = 定时时间(默认单位us) ——————————————————————————————— X是未知量 ——————————————————————————————— 216是根据方式选择的,可以自行选择,方式1为16位 方式0 :213 (少用) 方式1 :216 (最常用) 方式2 :28 (常用)

1s=1000ms,1ms=1000us

定时器T0工作在方式一,晶振频率为11.0592MHZ,需要定时时间0.5s怎么做?

1. 1s=1000ms,1ms=1000us。

2. 此时计算最大的计数间隔(216-0)× 12 ÷ 11.0592=71ms,定时时间最大只能算到71ms,而0.5s=500ms,距离需要的时间还差429ms

3. 所以算5ms再循环个100次,这样就可以得到5ms*100=500ms(0.5s)

500ms先换算成us单位就是5000us公式:(216-X)× 12 ÷ 11.0592=5000(us)

X=60928把十进制60928转换为16进制=0xee00,分配高8位TH=0xee,低8位TL=0x00

代码语言:javascript复制
char i=100;    //用来循环100次,5ms*100=500ms,500ms=0.5s
代码语言:javascript复制
void T0_timer0() interrupt 1 //定时器0 进入中断程序
{
    TH0 = 0xEE; //这里需要重新赋初始值,保证每次进入中断函数都是5ms
    TL0 = 0x00;
    i--;        // i=100开始循环自减
    if (i <= 0) //判断(i从100减到0的时候就执行下面程序)
    {
        i = 100;  //进来就重置循环次数,保证出去可以重新开始计算
        P2 = ~P2; //取反,i从100减到0刚好是0.5s,取反亮一次
    }             //亮完后i已经等于100,不满足if判断条件,重新开始定时
}

开始使用自减结构,减完做判断,在100次完成后,重新装载i值。

剩下就是具体应用的细节,我当然还会继续写。

接下来可能会写ESP32的定时器或是ESP8266的,不管怎么说,有了51的基础,剩下的都是So easy。

明显就是一个现代的MCU的定时器配置了

0 人点赞