在单片机控制应用中定时和计数的需求很多,为此在单片机中都有定时器/计数器.
80C51单片机中有两个16位定时器/计数器,分别为定时器/计数器0和定时器/计数器1.
由于作为定时器使用的机会多一些,所以常把定时器/计数器简称为定时器
80C51的两个定时器/计数器都是16位加法计数结构. 由于在80C51中只能使用8位字节寄存器,所以把两个16位定时器分解为4个8位定时器,依次为TL0,TL1,TH0,TH1,对应地址为8AH,8BH,8CH,8DH. 他们均属于专用寄存器之列.
定时器/计数器顾名思义具有定时和计数的功能,分别对此进行介绍
计数是对外部事件进行的. 外部事件以脉冲形式输入,作为计数器的计数脉冲. 为此芯片上有T0和T1两个引脚, 用于为这两个计数器输入计数脉冲. 计数脉冲是负跳变有效,供计数器进行加法计数.
使用计数功能时,单片机在每个机器周期的S5P2拍节对计数脉冲输入引脚进行采样. 如果前一机器周期采样为高电平,后一机器周期采样为低电平.即为一个计数脉冲,在下一个机器周期的S3P1进行计数. 由于采样计数脉冲需占用两个2个机器周期,所以计数脉冲的频率不能高于振荡脉冲频率的1/24.
定时功能也是通过计数器的计数来实现的,不过此时的计数脉冲来自芯片内部. 每个机器周期有一个计数脉冲,即每个机器周期计数器加一. 由于一个机器周期等于12个振荡脉冲周期,因此,计数频率为振荡频率的1/12. 如果单片机使用12MHz晶振,则计数频率为1MHz, 即1μs计数器加1.
在使用定时器时,即可以根据计数值计算出定时时间,也可以通过定时时间的要求计算出计数器的预置值.
在80C51中,与定时器/计数器应用有关的控制寄存器共有3个,分别是定时器控制寄存器,工作方式控制寄存器和中断允许控制寄存器
寄存器地址为88H,位地址为8FH~88H. 位定义和位地址如下表:
位地址 | 8FH | 8EH | 8DH | 8CH | 8BH | 8AH | 89H | 88H |
---|---|---|---|---|---|---|---|---|
位符号 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
该寄存器中,与定时器/计数器有关的控制位有四位:
当采用查询方法时候,溢出标志位被查询,并在后续处理程序中应以软件方法及时清0
当采用中断方法时候,溢出标志位不但能自动产生中断请求.而且清0操作也能在转向中断服务程序时候由硬件自动进行
TMOD用于设定定时器/计数器的工作方式
寄存器地址为89H
(《单片机基础第三版》书上这么写,不知道是不是写错了),但它没有位地址,不能进行位寻址,只能用字节传送指令设置其内容,该寄存器位定义如下表:
B7H | B6H | B5H | B4H | B3H | B2H | B1H | B0H |
---|---|---|---|---|---|---|---|
GATE | C/ T ‾ \overline{\text{T}} T | M1 | M0 | GATE | C/ T ‾ \overline{\text{T}} T | M1 | M0 |
它的低半字节对应定时器/计数器0,高半字节对应定时器/计数器1. 前后半字节的位格式完全对应,位定义如下:
该寄存器地址为A8H,位地址位AFH~A8H.寄存器位定义及位地址如下表:
位地址 | AFH | AEH | ADH | ACH | ABH | AAH | A9H | A8H |
---|---|---|---|---|---|---|---|---|
位符号 | EA | – | – | ES | ET1 | EX1 | ET0 | TX0 |
其中与定时器/计数器有关的是定时器/计数器中断允许控制位ET0和ET1
ET0/ET1 =0,禁止定时器中断
ET0/ET1 =1,允许定时器中断
80C51单片机的两个定时器/计数器都有四种工作方式,下面以定时器1为例进行介绍
工作方式0是13位计数结构,计数器由TH1的全部8位和TL1的低5位构成,TL1的高3位不用,逻辑结构大致如下:
在工作方式0下,计数脉冲即可以来自外部脉冲,也可以来自芯片内部.
来自内部的是机器周期,图中振荡器经过12分频后得到单片机的机器周期脉冲. 来自外部的计数脉冲由引脚T1引入,计数脉冲控制寄存器TMOD的C/ T ‾ \overline{\text{T}} T位控制. 当C/ T ‾ \overline{\text{T}} T = 0时,开关接通机器周期脉冲,计数器每个机器周期进行一次加一,这就是定时器工作方式. 当C/ T ‾ \overline{\text{T}} T =1时,开关接通外部计数引脚T1,从T1引入计数脉冲输入,这就是计数器工作方式
不管是哪种工作方式,当TL1的低5位计数溢出时,向TH1进位,而全部13位计数溢出时,向计数溢出标志位TF1进位,将其置1,表示计数/定时完成.
定时器/计数器的启停控制有两种方式,一种是纯软件方式,另一种是软件和硬件结合的方式. 两种方式有门控位GATE的状态进行选择
使用工作方式0的计数功能时,由于只有13位用来计数,所以计数范围为1~8192(213). 使用工作方式0的定时功能时,定时时间的计算公式为:
(213-计数初值) × \times × 晶振周期 × \times × 12 或 (213-计数初值) × \times × 机器周期
时间单位与晶振周期或机器周期的时间单位相同,为μs. 若晶振频率为6MHz,则
最小定时时间为 1 × \times × 晶振周期 × \times × 12 = 2 μs
最大定时时间为 213 × \times × 晶振周期 × \times × 12 = 16384 μs
应用举例
晶振频率为6MHz,使用定时器1,方式0产生周期为500μs的等宽正方形连续脉冲,并由P1.0输出
计算计数初值
想产生500μs的等宽正方波脉冲,只需要每250μs输出一次等宽的电平就可以,只需要改变电平的高低状态就行. 因此定时器的周期为250μs. 因此:
(212-计数初值) × \times × 晶振周期 × \times × 12 = 250
其中晶振周期为1/6μs. 得到计数初值为8067.
二进制表示为1111110000011. 转为十六进制,高8位为FCH,低5位为03H. 所以TH1 = FCH. TL1 = 03H.TMOD寄存器初始化
为设定为工作方式0,则M1M0=00;为实现定时功能,应使C/ T ‾ \overline{T} T = 0; 为实现定时器/计数器1的运行控制,则GATE = 0. 由于定时器/计数器0不用,有关位设置为0, 因此TMOD寄存器初始化为00H.
程序中通过反复检测溢出是否出现,来控制程序的运行方向,这种程序控制方式称为Query方式. Query是反复提取特定数据的意思,在程序中通过JBC指令反复检测TF1位的状态,以了解所设置的时间宽度是否达到,达到之后程序转LOOP1向下运行,若没有达到则继续查询等待.
工作方式1是16位计数结构的工作方式. 计数器由TH1的全部8位和TL1的全部8位构成. 他的逻辑电路和工作情况与方式0完全相同,所不同的是计数器的位数,因此计数范围也有所不同,为1~65536
定时时间计算公式为:
(216-计数初值) × \times × 晶振周期 × \times × 12 或 (216-计数初值) × \times × 机器周期
时间单位与晶振周期或机器周期的时间单位相同,为μs. 若晶振频率为6MHz,则
最小定时时间为 1 × \times × 晶振周期 × \times × 12 = 2 μs
最大定时时间为 216 × \times × 晶振周期 × \times × 12 = 131072 μs ≈ \approx ≈ 131 ms
工作方式0和工作方式1有一个共同特点,就是计数溢出后计数器全为0,因此循环定时应用时,需要反复设置计数初值. 这不但影响定时精度,而且也给程序设计带来了麻烦. 工作方式2就是针对此问题而设置的,它具有自动重新加载计数初值的功能,免去了反复设置计数初值的麻烦. 所以工作方式2也称为自动重新加载工作方式.
在工作方式2下,16位计数器被分为两部分,TL作为计数器使用,TH作为预置寄存器使用, 初始化时,把计数初值分别装入TL和TH中. 当计数溢出后,由预置寄存器TH以硬件方法自动给计数器TL重新加载. 变软件加载为硬件加载. 下图为工作方式2的逻辑结构:
初始化时,8位计数初值同时装入TL1和TH1中. 当TL1计数溢出时,置位TF1, 并用TH1中的计数初值自动加载TL1,然后开始重新计数. 如此重复. 这样不但省区了用户程序中的重装指令,而且有利于提高定时精度. 但这种工作方式是8位计数结构,计数值有限,最大只能到255.
这种自动重新加载工作方式适用于循环定时或循环计数应用.
例如,用于产生固定脉宽的脉冲,此外还可以作为串行数据通信的波特率发送器使用.
在前3中工作方式下,对两个定时器/计数器的设置和使用是完全相同的. 但在工作方式3下,两个定时器/计数器的设置和使用是不同的,因此要分开介绍
在工作方式3下,定时器/计数器0被拆分成两个独立的8位计数器TL0和TH0,这两个计数器的使用完全不同
TL0既可以用于计数,又可以用于定时. 与定时器/计数器0相关的各个控制位和引脚信号均由它使用. 其功能和操作与工作方式0或1完全相同,而且逻辑电路结构也十分相似.如图(a)所示:
工作方式3下定时器/计数器0的另一半是TH0,只能作简单的定时器使用. 而且由于寄存器TCON的定时器0的控制位已被TL0独占,因此只能借用定时器1的控制位TR1和TF1为其服务. 即用计数溢出置位TF1,而定时的启停则受TR1的状态控制.
由于TL0既能作定时器使用,又能作计数器使用,而TH0只能作定时器使用,所以在工作方式3下,定时器/计数器0可以分解成2个8位定时器或1个8位定时器和1个8位计数器
如果定时器/计数器0已经在工作方式3下,则定时器/计数器1只能工作在方式0,1或2下. 因为它的运行控制位TR1及计数溢出标志位TF1已经被定时器/计数器0借用.
他的使用方法如图所示:
这时,定时器/计数器1通常是作为串行口的波特率发生器使用.
因为已经没有计数溢出标志位TF1可供使用,因此只能把计数溢出直接送到串行口. 作为波特率发生器使用时,只需要设置好工作方式,便可以自动运行.
若要停止工作,只需要向工作方式选择寄存器TMOD送入一个能把它设置未方式3的控制字就可以了. 因为定时器/计数器1不能在方式3下使用, 如果硬把它设置为方式3,就会停止工作.