实现目标
1、掌握定时器的配置流程;
2、掌握定时器初值的计算方法;
3、具体实现:(1)1mS中断1次,计数1000次中断,实现定时1S功能;(2)LED1每隔1S状态取反。
一、定时器概述
1.1 生活中哪些场景会用到定时器?
许多家用电器都配备了定时器功能,如电饭煲、热水器、空调等。通过设定开始和结束时间,用户可以确保在需要的时候这些设备能够自动开启或关闭。
1.2 周期是什么?
在 51单片机的最小系统板上有一个12MHz或11.0592MHz的晶振,那为什么是12MHZ呢?在此之前就需要了解三个概念:时钟周期、指令周期和机器周期。
1.2.1 时钟周期
时钟周期也称为振荡周期,定义为时钟频率的倒数。时钟周期是计算机中最基本的、最小的时间单位。在一个时钟周期内,CPU仅完成一个最基本的动作。时钟周期是一个时间的量。时钟周期表示了SDRAM所能运行的最高频率。更小的时钟周期就意味着更高的工作频率。
1.2.2 机器周期
机器周期也称为CPU周期。在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段(如取指、译码、执行等),每一阶段完成一个基本操作。完成一个基本操作所需要的时间称为机器周期。一般情况下,一个机器周期由若干个时钟周期组成。AT89S51单片机每12个时钟周期为1个机器周期。
1.2.3指令周期
指令周期是取出一条指令并执行这条指令的时间。一般由若干个机器周期组成,是从取指令、分析指令到执行完所需的全部时间。单片机的指令按字节可分为单字节(1个机器周期)、双字节(2个机器周期)、三字节指令(3个机器周期),乘法、除法指令需要(4个机器周期),因此执行一条指令的时间也不相同。
因此,晶振可以理解为单片机的 “心脏” ,它为单片机提供了时钟周期,晶振频率会直接影响时钟周期的大小,二者的关系为:时钟周期 = 1 / 晶振频率 。无论你的晶振频率是多少,对于单片机来说,它内部都是固定的关系 ,在设计之初,由于51单片机性能和制程工艺等因素,出厂时把51单片机的机器周期严格的控制在12个时钟周期,指令周期一般是由1\ 2 \4 个机器周期组成。
那么为什么晶振是12MHz?通过计算:时钟周期 = 1 / (12M) (s) = 1/12000000 (s) = 1/12 (us),51单片机一个机器周期是12个时钟周期,即机器周期=12*1/12 (us) = 1 (us) ,这样执行1条指令的时间就控制在了1(us)、2(us)、4(us)。
如果晶振的频率是11.0592MHz,那么时钟周期就是 1 / (11.0592x10^6) 秒 (1MHz = 10^6Hz)。那么,无论是定时器,还是计数器,每隔1个机器周期 ,加法存储器就+1,代表时间经过了 12 x 1 / (11.0592x10^6) 秒。
1.3 与定时器有关的寄存器
1.3.1 定时器/计数器T0、T1的控制寄存器TCON
TCON:定时器/计数器中断控制寄存器(可位寻址)
- TF1(Timer 1 Overflow Flag):当定时器1计数溢出时,TF1位被硬件自动置1。软件需要手动清除该标志位。
- TR1(Timer 1 Run Control Bit):控制定时器1的启动和停止。TR1 = 1时,定时器1运行;TR1 = 0时,定时器1停止。
- TF0(Timer 0 Overflow Flag):当定时器0计数溢出时,TF0位被硬件自动置1。软件需要手动清除该标志位。
- TR0(Timer 0 Run Control Bit):控制定时器0的启动和停止。TR0 = 1时,定时器0运行;TR0 = 0时,定时器0停止。
- IE1(External Interrupt 1 Edge Flag):当外部中断1(INT1)检测到边沿变化时,IE1位被置1。软件需要手动清除该标志位。
- IT1(Interrupt 1 Type Control Bit):控制外部中断1的触发方式。IT1 = 1时,INT1为边沿触发;IT1 = 0时,INT1为电平触发。
- IE0(External Interrupt 0 Edge Flag):当外部中断0(INT0)检测到边沿变化时,IE0位被置1。软件需要手动清除该标志位。
- IT0(Interrupt 0 Type Control Bit):控制外部中断0的触发方式。IT0 = 1时,INT0为边沿触发;IT0 = 0时,INT0为电平触发。
1.3.2 定时器/计数器工作模式寄存器TMOD
定时和计数功能由特殊功能寄存器TMOD的控制位 CT 进行选择,TMOD寄存器的各位信息如下表所列。可以看出,2个定时/计数器有4种操作模式,通过TMOD的M1和M0选择。2个定时/计数器的模式0、1和2都相同,模式3不同,各式下的功能如下所述。
1.4 定时器模式
通过对寄存器TMOD中的M1(TMOD.1)、M0(TMOD.0)的设置,定时器/计数器有4种不同的工作模式,见下表:
定时器各种模式的最大定时:
例:对12MHz 1个机器周期 1us 12/fosc = 1us
方式0 13位定时器最大时间间隔 = 2^13 = 8.192ms
方式1 16位定时器最大时间间隔 = 2^16 = 65.536ms (常用)
方式2 8位定时器最大时间间隔 = 2^8 = 0.256ms =256 us
方式3 仅适用于T0,此时T0分成两个8位计数器,T1停止计数
1.5 定时器计算(以T0,方式1为例)
方式1为一个16位的定时器,其高八位为TH0,低八位为TL0。定时器 和 计数器 都是单片机中同一个模块。他们的实质都是: 加法存储计数器。
对于计数器,每来一个信号(信号从P3.4 或者P3.5输入),就加1,以此达到计数的目的。
对于定时器,每隔1个机器周期 加 1,假如一个机器周期为 1uS , 当加到1000时,我们就认为经过了1mS,这就是定时器的原理。
定时器0方式1框架图:
②处 C/T = 0 表示为定时器模式,触发信号为①处的单片机内部时钟信号。(若②处CT = 1,则触发信号为Tn脚,信号从P3.4 或者P3.5输入单片机)
③处表明,信号能触发使加法计数器加1,还得受④处控制。不然时钟信号是不能让加法计数器累加的。 ④处这个是与门,TRn必须为1,表明我们要开启定时器。同时GATE为0,通过非门后为1,再通过或门,也是1,那么就让③处控制起来了。
(若GATE为1,那么,定时器的启动停止受 TRx和 INTx 共同控制。 )
于是我们需要:
TRn 为 1
GATE 为 0
INTn 为 X(X表示任意的意思,do not care)
为THx和TLx赋初始值
若TH0 和 TL0 以 16位 模式1工作,那它的计数范围为 [0 , 65535 ] , 也就是累加 65536次发生溢出。 每累加一次是 12 / (11.0592x10^6) 秒(晶振为11.0592MHz)。那么从 0 累加到溢出 历时 ≈ 0.071s = 71ms 。对12MHz 晶振,从 0 累加到溢出 历时65.536ms。
1、机器周期 = 具体晶振频率 / 分频数 的倒数
2、初值 = 溢出值 - 机器周期 * 定时时间
假设T0初值为5000,则应该这么设置:
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
得到TH0 和 TL0值的方法:
二、原理图设计
三、程序设计
#include <REGX52.H>sbit LED1 = P2^0;unsigned int g_Count; //全局变量默认初始化为0void Timer0_Init(void)
{TMOD = 0x01; //设置定时器0 工作模式1 0000 0001TR0 = 1; //开启定时器0TH0 = (65536-1000)/256; //设置定时初值,高8位TL0 = (65536-1000)%256; //设置定时初值,低8位ET0 = 1; //开启定时器0 中断EA = 1; //开启总中断
}void main(void)
{Timer0_Init(); //定时器0初始化while(1){}
}void Timer0_Rountine(void) interrupt 1 //1ms进一次中断
{TH0 = (65536-1000)/256; //TL0 = (65536-1000)%256; //重新赋初值才能保证下一次还是1msg_Count++;if(g_Count>=1000) // 1S 计时{g_Count = 0; //计数清零LED1 = !LED1; //LED1状态取反}
}