1、C51单片机中有T0,T1两个定时器,C52单片机中有T0,T1,T3三个定时器。这里T是timer(定时器)的简写。
2、看懂定时器工作原理图。这里以T0计时器为例展开介绍。如下图所示:
图中可以分为三部分
(1)、晶振产生电脉冲部分,此部分晶振会持续不断的振动产生电脉冲,会被后面储存部分记录
(2)、控制部分,此部分用于控制开关,实现对计时器的打开或关闭。下图中使用到了非门和与非门,或非门共同控制开关,使用到了数电的知识,有兴趣可以了解一下。
(3)、电脉冲存储部分,此部分用于存储晶振产生的电脉冲。共有16个比特位,它用来对电脉冲计数,晶振部分每产生一次电脉冲,存储部分的计数器就会加1,直至16个 比特位存满,即电脉冲次数达65535次。如果再接收到电脉冲,内存便会溢出,内存溢出会作为后续中断部分的中断源。对于12MHZ的晶振来说,一个电脉冲对应1微秒。
注:16个比特位分为TL0(Timer Low0)低位,TH0(Timer High 0)高位。方便后续初始化。
3、定时器有很多模式,那么我们怎么选择用哪种定时器呢?还有怎么控制开关呢?定时器里面的寄存器就能实现这一功能,每个寄存器后面都连接着一根地址线,每根地址线都能读取该寄存器的数值,用来控制定时器内部的线路连接,进而实现模式的选择。
GATE:用来选择:定时器内开关控制部分是否需要单片机引脚控制。GATE=0时,定时器仅由计 时器自身的TR0控制,GATE=1时,定时器由TR0和单片机INT0引脚输出的电平类型共同控制。
C/T: 用来选择接收电脉冲来源(计算机 / 晶振)。C/T=0时,接收来自晶振的电脉冲;C/T=1 时, 接收来自计算机的电脉冲。
M1和M0: 用来选择计时器。如下图所示:
4、定时器的控制还需另一组寄存器控制。
TF1 / TF0:计数器的溢出标志。当计数器内存部分内存溢出时,TF1(TF0)置1,向CPU请求中断
TR1 / TR0:控制计数器1或2是否可以进行计数。当TR1(TR0)=1时,计数器开始计数。当 TR1(TR0)=0时,计数器停止计数。
IE1 /IE0:外部中断请求源标志。
IT1 /IT0:外部中断触发方式控制位。
5、初始化一个定时器。我们可以直接对电脉冲存储的高低位赋值来实现一次中断对应一微秒。直接对赋值64536 (65536-1000),一毫秒就能内存溢出发生中断。代码实现如下:
void Timer0_Init()
{
TMOD=0x01;//选择定时器Timer0
TF0=0;
TR0=1; //开启定时器
TH0 = 64536/256; //对存储高位赋值
TL0 = 64536%256; //对存储低位赋值
ET0=1; //打开中断开关1
EA=1; //打开中断开关2
PT0=0; //选择中断优先级
}
6、使用定时器。用定时器制作一个呼吸灯,亮灭的周期都为1s,代码实现如下:
void main()
{
Timer0_Init();//初始化定时器
while(1)
{
}
}
void Timer0_Rountine() interrupt 1
{
static unsigned int T0count;//定义一个定时器计数,每运行一次是1ms
TH0 = 64536/256; //对每次溢出的高位重新赋值
TL0 = 64536%256; //对每次溢出的低位重新赋值
T0count++;
if(T0count==1000) //定时器刚好溢出1000次,即1s
{
P2_0=~P2_0; //对LED的电平取反,实现亮灭转换
}
}