一、引言
在单片机系统中,定时器和计数器是极为重要的功能模块。它们不仅能够实现精确的定时控制,如产生特定时间间隔的定时信号以执行周期性任务,还可以对外部事件的脉冲数量进行计数,从而实现对物理量的测量与监测等功能。理解其工作原理对于深入掌握单片机应用开发至关重要。
二、定时器的基本概念与工作模式
(一)定时器的基本概念
定时器本质上是一个对内部时钟脉冲进行计数的装置。单片机内部通常有一个稳定的时钟源,定时器通过对这个时钟源产生的脉冲进行计数来实现定时功能。例如,当设定定时器的计数初值后,每来一个时钟脉冲,定时器的计数值就加 1,当计数值达到设定的最大值(溢出值)时,就表示定时时间到,并产生相应的溢出中断(如果开启中断功能)。
(二)工作模式
以常见的 8051 单片机为例,它有多种定时器工作模式。
- 模式 0:这是一个 13 位的定时器 / 计数器模式。由 TLx(低 5 位)和 THx(高 8 位)组成 13 位的计数器。在这种模式下,TLx 的高 3 位未使用。当定时器启动后,内部时钟脉冲不断输入,计数器从设定的初值开始计数,当计数值达到 0FFFFH(13 位全为 1)时产生溢出。例如,若时钟频率为 12MHz,机器周期为 1μs,要实现一个 10ms 的定时,可根据公式计算出合适的计数初值并设置到 THx 和 TLx 中。
- 模式 1:这是 16 位的定时器 / 计数器模式,TLx 和 THx 共同组成 16 位的计数器。其计数范围更大,定时精度相对更高。同样以 12MHz 时钟频率为例,可实现更长时间且更精确的定时任务,如定时 50ms 等。在这种模式下,计算计数初值的公式为:初值 = 2^16 - 定时时间(微秒)/ 机器周期(微秒)。
- 模式 2:自动重装载的 8 位定时器 / 计数器模式。TLx 作为 8 位计数器,THx 用于存放计数初值。当 TLx 计数溢出时,会自动将 THx 中的初值重新装载到 TLx 中,继续下一轮计数。这种模式适用于需要周期性产生固定时间间隔中断的场合,比如以固定频率闪烁的指示灯控制等,无需在中断服务程序中重新设置计数初值,减少了软件开销。
- 模式 3:仅适用于定时器 0。在这种模式下,定时器 0 被拆分成两个独立的 8 位定时器 / 计数器,TL0 和 TH0 分别作为两个计数器独立工作。TL0 使用定时器 0 的控制位和引脚信号,而 TH0 只能作为简单的定时器使用,并且占用定时器 1 的中断资源。这种模式在一些特殊应用场景下,如需要同时进行两个不同时间尺度的定时任务时,可以发挥作用。
三、计数器的工作原理
(一)计数功能概述
计数器的功能是对外部输入的脉冲信号进行计数。当单片机的相应计数器引脚检测到外部脉冲的下降沿或上升沿(可通过设置控制寄存器选择)时,计数器的值就加 1。例如,在一个转速测量系统中,将传感器产生的脉冲信号连接到单片机的计数器引脚,每来一个脉冲,计数器就计数一次,通过在一定时间内统计脉冲的数量,就可以计算出转速。
(二)与定时器的关联与区别
计数器与定时器在硬件结构上有一定的相似性,但工作方式不同。定时器是对内部时钟脉冲计数实现定时,而计数器是对外部脉冲计数。不过,它们的计数本质都是通过加法计数器来实现的。在一些应用中,两者的功能可以相互配合。比如,在一个既有定时要求又需要对外部事件计数的系统中,可以先利用定时器设定一个固定的时间间隔,在这个时间间隔内利用计数器对外部脉冲进行计数,从而实现对单位时间内外部事件发生次数的统计与分析。
四、定时器 / 计数器的控制寄存器
(一)控制寄存器的作用
单片机通过一系列的控制寄存器来对定时器和计数器进行配置和控制。这些控制寄存器决定了定时器 / 计数器的工作模式、启动与停止、中断允许等重要参数。
(二)具体寄存器介绍
- TMOD 寄存器(定时器 / 计数器模式控制寄存器):在 8051 单片机中,TMOD 用于设置定时器 0 和定时器 1 的工作模式。它的高 4 位用于设置定时器 1,低 4 位用于设置定时器 0。例如,其每一位的不同取值组合可以确定定时器是工作在定时器模式还是计数器模式,以及具体是哪种工作模式(如模式 0 - 模式 3)。
- 工作方式控制寄存器TMOD用于定时器/计数器的功能选择、工作方式设置等,不能位寻址。
TMOD的格式如图所示,其中高4位控制T1,低4位控制TO。
3.TCON 寄存器(定时器 / 计数器控制寄存器):它主要用于控制定时器 / 计数器的启动、停止、溢出标志以及外部中断触发方式等。其中,TFx(x = 0 或 1)位是定时器 / 计数器 x 的溢出标志位,当定时器 / 计数器计数溢出时,该位被硬件置 1,如果中断允许且相应中断被开启,就会触发中断服务程序;TRx 位则用于控制定时器 / 计数器的启动与停止,将其置 1 启动计数,置 0 停止计数。
定时器/计数器控制寄存器TCON的作用是控制定时器的启动、停止,可以位寻址。TCON的格式如图所示。
TF1和TFO:计数溢出标志位。当计数器计数溢出时,由硬件自动置1。中断允许时,向CPU发出中断请求,进入中断服务程序后,由硬件自动清0.在中断屏蔽时,用查询方式处理计数溢出,此位可供CPU查询,这时只能由软件清0。
TR1和TRO:计数器运行控制位。由软件置1或清0来启动/停止定时器。当GATE=1,且INT1为高电平时,TR1置1启动T1计数;当GATE=0时,TR1置1即可启动T1;TR1=0,停止T1 计数。TRO与TR1相同。
TCON中的低4位用于控制外部中断,与定时器/计数器无关,参见5.2.3小节。单片机复位时, TCON的所有位都清0。
五、定时器 / 计数器的应用实例
(一)定时任务应用
- 简单定时闪烁灯:利用定时器的模式 2(自动重装载模式),设置合适的计数初值来实现一个固定频率的闪烁灯控制。例如,设置定时器每 500ms 产生一次中断,在中断服务程序中改变连接到 LED 灯引脚的电平状态,从而使灯一亮一灭,产生闪烁效果。首先根据时钟频率计算出 500ms 对应的计数初值,然后将其设置到 THx 和 TLx 中,并配置 TMOD 和 TCON 寄存器启动定时器。当定时器溢出产生中断时,在中断服务程序中切换 LED 灯的状态,并由于是模式 2,无需重新设置计数初值,定时器会自动重新开始计数。
- 数据采集系统中的定时采样:在一个多传感器的数据采集系统中,需要每隔一定时间对各个传感器的数据进行采集。可以利用定时器设定采样时间间隔,如每隔 1s 启动一次数据采集。定时器按照设定的工作模式和计数初值进行计数,当定时时间到,触发中断,在中断服务程序中启动 ADC(模数转换器)对传感器数据进行采集,并将采集到的数据存储到指定的存储区域。
(二)计数应用
- 脉冲频率测量:将待测脉冲信号连接到单片机的计数器引脚,选择计数器工作模式,并设置一定的计数时间。例如,先利用定时器设定一个 1s 的计数时间,在这 1s 内计数器对输入脉冲进行计数,计数结束后,读取计数器的值,这个值就是该脉冲信号在 1s 内的脉冲数量,也就是脉冲频率。通过这种方式,可以实现对外部信号频率的精确测量,如测量电机的转速脉冲频率以计算电机转速,或者测量音频信号的频率等。
- 产品产量统计:在自动化生产线上,产品通过某个检测点时会产生一个脉冲信号,将这个脉冲信号输入到单片机的计数器引脚,计数器就可以对产品的数量进行统计。通过定期读取计数器的值并保存记录,可以实现对产品产量的实时监测和统计分析,为生产管理提供数据支持。
六、定时器 / 计数器的编程实现
(一)初始化设置
在编程使用定时器 / 计数器时,首先要进行初始化设置。这包括设置 TMOD 寄存器确定工作模式,设置计数初值到 THx 和 TLx 寄存器,设置 TCON 寄存器启动定时器等。例如,以下是 8051 单片机定时器 0 工作在模式 1,定时 10ms 的初始化代码片段:
TMOD = 0x01; // 设置定时器 0 为模式 1
TH0 = (65536 - 10000) / 256; // 计算并设置高 8 位计数初值
TL0 = (65536 - 10000) % 256; // 计算并设置低 8 位计数初值
ET0 = 1; // 允许定时器 0 中断
EA = 1; // 开总中断
TR0 = 1; // 启动定时器 0
(二)中断服务程序编写
当定时器 / 计数器计数溢出产生中断时,会执行相应的中断服务程序。在中断服务程序中,需要编写实现具体定时或计数任务的代码。例如,对于上述定时 10ms 的闪烁灯例子,中断服务程序如下:
void Timer0_ISR() interrupt 1 // 定时器 0 中断服务程序
{
static unsigned char led_state = 0;
if (led_state == 0)
{
// 点亮 LED 灯
LED_PORT = 0;
led_state = 1;
}
else
{
// 熄灭 LED 灯
LED_PORT = 1;
led_state = 0;
}
}
七、定时器 / 计数器的性能优化与注意事项
(一)性能优化
- 合理选择工作模式:根据具体的应用需求,选择合适的定时器 / 计数器工作模式。如果需要精确的长时间定时,模式 1 的 16 位计数可能更合适;如果是周期性的短时间任务,模式 2 的自动重装载模式可以减少软件开销。
- 时钟频率选择与调整:在一些对定时精度要求较高的应用中,可以选择合适的外部晶体振荡器频率来提供单片机的时钟源。例如,对于一些需要微秒级定时精度的任务,使用 11.0592MHz 的晶体振荡器可能比 12MHz 更合适,因为 11.0592MHz 可以在串口通信等方面产生更精确的波特率,同时也有利于定时器计数初值的计算与设置,减少误差。
(二)注意事项
- 中断处理时间:在中断服务程序中,要尽量减少代码执行时间,避免因中断处理时间过长而影响其他任务的执行。如果中断处理时间过长,可能会导致定时器 / 计数器的计数不准确,尤其是在多个中断同时存在或者对定时精度要求极高的情况下。
- 计数初值的计算与溢出处理:在计算计数初值时,要确保计算准确,并且要考虑到计数溢出的情况。当计数溢出时,要根据具体应用进行相应的处理,如重新设置计数初值、记录溢出次数等。同时,在一些复杂的应用中,可能需要对多个定时器 / 计数器进行协同操作,此时要注意它们之间的相互影响和时序关系,避免冲突和错误的发生。