在51单片机中,定时计数器是非常好用的定时工具,它可以以比较小的内存来完成任务,现在我们来看看定时计数器的基本运用。
我们以一题例题引入这个知识点
首先,我们先来理解一下定时计数器的基本使用,首先,我们先来理解一下TH0与TL0的概念,TH0指的是高八位,而TL0指的是低八位,定时计数器总共能包含65536个数值,也就是65.6ms,定时器的工作原理便是从初始化TH0,TL0的位置一直加,当数值溢出就会做出触发定时计数器。而计数器主要是检测外部引脚。
定时计数器的核心是TMOD模式控制寄存器,他只能字节操作,所以当我们需要使用计数器1,且需要用TR0和TR1来选择定时器,C/T = 0,然后M1M0需要选择16位定时计数器,所以最后我们需要的便是0x01(因为我们不需要定时计数器1,所以定时计数器1就是0 0 0 0)
接下来就是要打开TR0,ET0和EA,这并不麻烦,看原理图即课知。
接着我们需要定义TH0和TL0,因为我们想要的是0.5秒和5秒的延迟,所以我们的初始值便定为TH0 =(65535 - 50000)/ 256,TL0 = (65535 - 50000) % 256,为什么这么写呢?首先,其实我们最早要写的话,其实是需要写成16进制的形式的,但是我们通过这样子一写,电脑会自动帮我们计算出相应的16进制数字,可以大大减少计算的麻烦。
在接下来,就比较简单啦。首先我们需要写出中断服务函数,然后在中断服务函数里面写出我们所需要的亮灭灯功能,由于灯的状态只有亮(1)和灭(0),所以我们要完成这个工作,我们可以直接对L1进行取反。使用~符号。
那么,最后的代码就是这样啦!
#include "reg52.h"
sbit L1 = P0^0;
sbit L8 = P0^7;
void InitTO()
{
TMOD = 0x01;
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
unsigned int count = 0;
void ServeT0() interrupt 1
{
count++;
if(count % 10 == 0)
{
L1 = ~L1;
}
if(count == 100)
{
L8 = ~L8;
count = 1;
}
}
void main()
{
InitTO();
P2 = (P2 & 0x1f) | 0x80;
while(1)
{
}
}