Dotcpp  >  编程教程  >  定时器  >  定时器工作模式2

定时器工作模式2

点击打开在线编译器,边学边练

1.工作模式2的使用

这里我们顺便讲解一下定时器0的工作模式2,也就是使用“小试管”的方式,TMOD的初始化就为“TMOD=0x02;”。

我们知道工作模式2的最长溢出时间仅为256*(12/11059200)=0.000277秒=277微秒。

我们想实现间隔51ms的流水灯实验该怎么做,首先我们定义一个变量cnt用来记录每次的溢出次数,然后我们的定时时间为51微秒(因为最大定时只有278微秒),cnt记录的值等于1000的时候,证明时间已经过去了51ms,于是再去执行流水灯的任务。

我们已经知道工作模式2是不需要在溢出之后再填充初始值的,比如我们定时的时间为51微秒,那么计算出“距离溢出的刻度”就为47(实际计算出的是47.0016,所以定时为51微秒误差就不大)。

所以给TL0赋初值为256-47=209=0xD1。那么TH0也是给初值为0xD1,这是保证每次TL0溢出之后新的初始值是等于TH0的值的,所以定时器工作模式2又叫做8位自动重装载模式。相关概念还需读者再去另外学习这些理论知识。

 

2.工作模式2的代码

#include <reg52.h> 
#include <function.h>//详见第六章第8讲

void main()
{
    u8 i;
    u16 cnt;
    LED_Init();   //初始化LED硬件模块 
    TMOD = 0x02;  //设置定时器0为工作模式2
    TH0  = 0xD1;  
    TL0  = 0xD1;  //定时51us
    TR0  = 1;     //启动定时器0
    
    while(1)
    {
        if (TF0 == 1)    //每隔51us就可以进入一次这个if语句
        {
            TF0 = 0;     //定时器0溢出后,清零中断标志
            cnt++;       //记录溢出次数
        }   
        if(cnt>=1000)    //时间过去了51ms
        {
            cnt=0;   
            P0=~(0x01<<i);
            i++;
        }      
        if(i>=8)i=0;
    }
}

大家对照上一讲的工作模式1的代码会发现,工作模式2在while循环中不再出现TH0和TL0的身影,TL0每次溢出之后,初值又变为TH0初始时候的值了,所以定时时间在while循环之前就已经决定好了。

大家可以尝试着把“if(cnt>1000)”里的1000改为10000就是间隔510ms的流水灯了。

往后我们做的题目定时时间一般最少都是要定时1毫秒以上,所以用工作模式1的机会会很多,而工作模式2在我们前期教程里会很少运用,等学到串口通信相关知识时我们再重拾这个知识点。


本文固定URL:https://www.dotcpp.com/course/376

单片机教程
第一章 单片机入门
第二章 LED及入门
第三章 蜂鸣器
第四章 数码管
第五章 独立按键
第六章 多文件编程
第七章 外部中断
第八章 定时器
第九章 舵机与超声波模块
第十章 串口通信
第十一章 1602液晶屏
第十二章 IIC通信
第十三章 红外遥控与温度传感器
第十四章 AD与DA
第十五章 混合例程
第十六章 完结
Dotcpp在线编译      (登录可减少运行等待时间)