Bootstrap

定时器专题——从理论到运用

定时器专题目录

  • 一、为什么要有定时器
    1.为什么需要定时器?
    2.定时器是怎么工作的?
    3.定时器的功能
  • 二、定时器的内部实现逻辑
    1.数电基础导入
    2.AUXR辅助寄存器
    3.工作模式寄存器TMOD
    4,控制寄存器TCON
    5.中断允许控制寄存器IE
  • 三、定时器的工作模式
    1.配置模式0
    2.代码编写
  • 四、定时器在实际中的运用
    1.定时产生中断
    2.NE555

一、 为什么要有定时器

1.为什么需要定时器?

在我们的日常生活中,很多事情都需要按特定的时间间隔来完成。例如,当你设置闹钟来叫醒自己,或者你使用微波炉加热食物时,你其实是在利用时间进行“计时”。而在电子设备和计算机系统中,定时器的作用与我们生活中的“计时”非常相似。它帮助设备在准确的时间点执行任务,让系统更加有序、有效。

对于单片机或嵌入式系统而言,定时器就像是一个“电子时钟”,它帮助设备跟踪时间,并且根据设定的时间间隔来触发各种操作。如果没有定时器,设备将无法精确地管理时间,很多功能也无法顺利执行。

2.定时器是怎么工作的?

自动执行任务

假设你想让一个设备每隔1秒钟闪烁一次LED灯。通过定时器,你可以设定“1秒”作为时间间隔,并告诉设备在每次时间到达时自动执行闪烁操作。这样,你无需一直手动干预,设备就能按照设定的规则自动工作。

定时提醒

另一个常见的应用是定时提醒。例如,你的设备可以通过定时器来提醒你什么时候喝水或吃药。当设定的时间到达时,定时器就会触发提醒操作,让你不会错过重要的任务。

控制时间间隔

在一些应用中,定时器可以帮助控制时间间隔。例如,在测量某个事件发生的频率时,定时器可以精确地记录时间,从而帮助我们了解事件的发生规律。它就像一个精准的计时器,帮助系统测量时间差或控制延时。

3.定时器的功能

定时延时

比如你希望设备等待2秒钟再执行下一步操作。定时器可以在2秒钟内“计时”,然后触发相应的操作。

定时中断

定时器不仅可以计时,还能在达到设定时间时,自动中断正在进行的操作,转而执行另一个任务。就像你给设备设置了一个“提醒”,到时间后它会“打断”当前的工作,提醒或执行其他任务。

产生周期性信号

定时器可以用来生成周期性的信号。比如,如果你需要让一个电机定时转动或LED灯按规律闪烁,定时器就可以按一定的频率产生信号,确保这些操作在精确的时间间隔内发生。

计数外部事件

在某些应用中,定时器也能用于计数。比如,如果你需要计算一个传感器在特定时间内触发了多少次,定时器就能帮助你完成这项任务。

二、定时器的内部实现逻辑

1.数电基础导入

(1)与门

功能:F = A & B
&:与运算,如下图所示

ABF
111
100
010
000

易得,A&B时遵循"全1为1,有0为0”原则
在这里插入图片描述

在这里插入图片描述

(2)或门

功能:F = A | B
|:或运算,如下图所示

ABF
111
011
101
000

易得,A|B时遵循"全0为0,有1为1”原则
在这里插入图片描述

在这里插入图片描述

(3)非门

功能:F = A ‾ \overline{A} A
A ‾ \overline{A} A:非运算,如下图所示

AF
10
01

即“有0为1,有1为0”

在这里插入图片描述

2.AUXR辅助寄存器

在这里插入图片描述
B7、B6为定时器0、1的速度控制位
功能:置0时使用12T模式,置1时为1T模式

  • 12T模式:每12个时钟周期加1,与传统51单片机相同。例如,如果系统时钟频率为12MHz,则12T模式下,定时器每12个时钟周期计数一次。
  • 1T模式:每1个时钟周期加1,速度是传统51单片机的12倍。例如,同样在12MHz的系统时钟下,1T模式下定时器每1个时钟周期计数一次。
  • 所以在配置定时器时,一般使用12T模式

B0~B5为定时器2和串口通信的控制位,一般使用定时器0和1时不用配置。
所以使用定时器0时对该寄存器的配置为:
AUXR &= 0x7f;//最高位清零,即定时器0使用12T模式
使用定时器1时对该寄存器的配置为:
AUXR &= 0xbf;//第六位清零,即定时器1使用12T模式

使用与运算是因为配置定时器0或1只需要对一位进行修改,其他位不变,所以对要修改的那位与上0就会清零,其余位与上1保持不变。

3.工作模式寄存器TMOD

在这里插入图片描述
B7 ~ B4控制定时器1,B3 ~ B0控制定时器0
B6(B2):置0时为定时器,置1时为计数器。
B5、B4(B1、B0):

M1M0定时器/计数器模式选择
0016位自动重装载定时器
0116位不可重装载定时器
108位自动重装载定时器
11定时器/计数器功能无效

B7(B3):点击跳转到定时器工作模式

4.控制寄存器TCON

在这里插入图片描述

5.中断允许控制寄存器IE

在这里插入图片描述
配置定时器0时只需要配置EA、ET0,配置定时器1时只需要配置EA、ET1。
EX0和EX1不用配置是因为如果没配置它们初值默认为0,禁止外部中断,这点与TMOD寄存器的GATE位在下文提出。点击跳转到定时器工作模式

三、定时器的工作模式

在上文讲解工作模式寄存器TMOD的每位的功能时,有提到M1、M0的取值对应着4种不同的模式,官方推荐只学习模式0即可。

1.配置模式0

在这里插入图片描述

以模式0为例,配置定时器为16位可自动冲装载的定时器/计数器时,只需要配置图上有的寄存器(位)即可。
在这里插入图片描述

  • 第一部分实现流程图如下:
初值为1
初值为0
高电平
TR0=1
低电平
GATE
通过非门后变为0
通过非门后变为1
直接通过与门
INT0判断电平
定时器/计数器开始计时
定时器计数器不工作

在这里插入图片描述

  • AUXR寄存器配置已经提过,C/ T ‾ \overline{T} T为1时,计数器模式,C/ T ‾ \overline{T} T为0时,定时器模式。
  • TH0、TL0的配置
    计算初值:
    假设使用12MHz的晶振频率,机器周期为1μs(即1/12MHz = 1μs)
    定时1ms需要计数1000次(1ms = 1000μs)
    由于16位计数器的最大值为65536(2^16),因此初值应为65536 - 1000 = 64536
    转换为十六进制:
    64536转换为十六进制为0xFC18
    其中,TH0存储高8位(0xFC),TL0存储低8位(0x18)

2.代码编写

定时器0

//配置定时器0为12MHZ,定时1ms
void Timer0Init()
{
	AUXR &= 0x7F;//配置定时器0为12T模式
	TMOD &= 0xF0;//设置定时器模式
	TL0 = 0x18;
	TH0 = 0xFC;
	TF0 = 0;//清楚溢出中断标志位
	TR0 = 1;//开始计时
	ET0 = 1;//允许定时器中断
	EA = 1;//CPU开放中断
}

定时器1

//配置定时器1为12MHZ,定时1ms
void Timer1Init()
{
	AUXR &= 0xBF;//配置定时器0为12T模式
	TMOD &= 0x0F;//设置定时器模式
	TL1 = 0x18;
	TH1 = 0xFC;
	TF1 = 0;//清楚溢出中断标志位
	TR1 = 1;//开始计时
	ET1 = 1;//允许定时器中断
	EA = 1;//CPU开放中断
}

四、实际运用

1.定时产生中断

定时1ms时间加1,LED以1s为间隔闪烁

unsigned int Time_1000ms;
bit LedFlash;

void Led_Proc()
{
	ucLed[0] = LedFlash;
	LedDisp(ucLed);
}

void Timer1_Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xBF;			//定时器时钟12T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0x18;				//设置定时初始值
	TH1 = 0xFC;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
	ET1 = 1;				//使能定时器1中断
	EA = 1;
}

void Timer1_Isr(void) interrupt 3
{
	Time_1000ms++;
	if(Time_1000ms == 1000)
	{
		Time_1000ms = 0;
		LedFlash = !LedFlash;
	}
}

2.NE555

传送门:NE555脉冲

;