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++;
//记录溢出次数
}
(cnt>=1000)
//时间过去了51ms
cnt=0;
P0=~(0x01<<i);
i++;
(i>=8)i=0;
大家对照上一讲的工作模式1的代码会发现,工作模式2在while循环中不再出现TH0和TL0的身影,TL0每次溢出之后,初值又变为TH0初始时候的值了,所以定时时间在while循环之前就已经决定好了。
大家可以尝试着把“if(cnt>1000)”里的1000改为10000就是间隔510ms的流水灯了。
往后我们做的题目定时时间一般最少都是要定时1毫秒以上,所以用工作模式1的机会会很多,而工作模式2在我们前期教程里会很少运用,等学到串口通信相关知识时我们再重拾这个知识点。