在单片机中,存在两个定时器/计数器,他们分别为T0和T1
在单片机中,定时器/计数器是实现精准定时、用于测量脉冲等应用
基本的定时器/计数器原理如图所示
在了解定时器/计数器之前,我们需要了解几个基本概念:
1)时钟周期:时钟周期 T 是时序中最小的时间单位,具体计算的方法就是1/ 时钟源频率【也就是晶振电路的振动频率】(一般单片机采用的是11.0592MHz)
2)机器周期:单片机完成一个操作的最短时间,一个机器周期等于12个时钟周期
定时器/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成(TH和TL)。TMOD是定时器/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。
定时器:加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t ,通过设定TH和TL的初值,我们就可以合理设置定时器的定时时间
计数器:计数器主要用来计输入脉冲的值。每来一个脉冲计数器加1,当加到计数器为全1(即FFFFH)时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向CPU发出中断请求(定时器/计数器中断允许时),单片机对外部脉冲有基本要求:脉冲的高低电平持续时间都必须大于1个机器周期。所以T0或者T1 输入的可计数外部脉冲的最高频率为当前单片机工作频率/24。
在单片机中,存在两个定时器/计数器,他们分别为T0和T1
在单片机中,存在4个特殊功能寄存器,主要用来实现定时器/计数器,他们分别是
名称 | 描述 | SFR地址 | 复位值 |
---|---|---|---|
TH0 | 定时器/计数器 | 0x8C | 0x00 |
TL0 | 定时器/计数器 | 0x8A | 0x00 |
TH1 | 定时器/计数器 | 0x8D | 0x00 |
TL1 | 定时器/计数器 | 0x8B | 0x00 |
通过设置TH与TL的初值,我们可以实现我们想要的定时功能、延时功能和计数功能
例如:如果我们想要实现0.02s的定时,我们可以先计数实现0.02s所需要的机器周期,假设需要的机器周期为x
x*12/11059200=0.02
–> x=18432
由于单片机存在的是16位定时器/计数器,最大能表示65535,因此当初值y=65536-18432=47104时,定时器可实现0.02s的定时,对应的16进制为0xB800,因此当我们给TH0=0xB8,TL0=0x00时,我们可实现定时器0.02s的精确定时
TMOD是定时器、计数器模式控制寄存器(TIMER/COUNTER MODE CONTROL REGISTER),它是一个逐位定义的8位寄存器,但只能使用字节寻址,其字节地址为89H
主要用来控制定时器/计数器的工作模式
1)GATE——门控制位
GATE=0,以运行控制位TRx启动定时器;GATE=1,以外中断请求信号(INT1或INT0)启动定时器,即仅当INT0(P3.2)【INT1(P3.3)】引脚为高且TR0控制位被置1时可使定时器开始计时,常用来测量外部信号脉冲宽度
2)C/T——功能选择位
定时器或计数器选择位,该位被清零时用作定时器功能(内部系统时钟),置1时用作计数器功能
3)M0、M1——方式选择功能
MCS-51的定时器T0有4种工作方式:方式0,方式1,方式2,方式3。
MCS-51的定时器T1有3种工作方式:方式0,方式1,方式2
TCON(Timer Control Register)定时器/计数器控制寄存器,TCON在特殊功能寄存器中,字节地址为88H,位地址(由低位到高位)为88H一8FH,可进行位寻址
TCON的作用是控制定时器的启、停,标志定时器溢出和中断情况
1)TF位
溢出中断请求标志位,T1计数/定时溢出时由硬件自动置TF1为1,CPU响应中断后TF1由硬件自动清0,也可软件清零,可用来判别定时器/计数器的状态
2)TR位
定时器/计数器运行控制位,TR置0时定时器/计数器停止工作,置1时开始工作
对于定时器的设置,我们只需要遵循以下几个步骤:
第一:设置特殊功能寄存器TMOD,配置好工作模式
第二:设置存储器TH0与TL0的初值
第三:设置TCON,通过TR0置1来让定时器开始计时
第四:判断TCON寄存器的TF0,监测定时器溢出情况
下面,我们基于C语言来进行程序编写:以实现LED灯闪烁(周期为2s)
#include
//定时器0初始化
void Timer0Init()
{
TMOD = 0x01;//定时器模式,使用工作方式1
TH0 = 0xB8;//定时器定时0.02s
TL0 = 0x00;
TR0 = 1//启动定时器
}
//定时器0溢出后进行初始化
void TimerOutInit()
{
TF0 = 0;//软件清零
TH0 = 0xB8;
TL0 = 0x00;
}
void main()
{
Timer0Init();//定时器0初始化
P0 = 0x00;//打开LED灯
if(TF0 == 1)//判断定时器0是否溢出
{
Timer0OutInit();//初始化
for(i=0;i<50;i++)//定时1s
{
P0 = ~P0;//实现LED闪烁
}
}
}
上述程序没有运行调试,有问题可以即时反馈
--------------------------------------以上内容由作者原创,欢迎转载,部分从网络整理,如侵权清联系删除----------------------------------------------