8 定时器原理与应用

学习笔记
作者: MingXiao

8.1 定时器概述

定时的方法

  • 软件定时:占用了CPU时间,降低利用率
  • 时基电路:如555等,不可编程
  • 定时芯片:8253/8254等,很好

两个16bit Timer;仅PC, DPTR和两个Timer是16bit

本质是+1计数器;如果使用外部时钟,称为计数器;如果是内部时钟,称为定时器
\[ t = n\cdot T \]
其中\(t,n,T\)分别是定时,计数和周期

8.2 结构与原理

分为两个8bit,当MSB溢出时产生一个中断信号

定时:对机器周期进行定时,是震荡周期的12倍

计数:每个机器周期进行采样,根据采样定理,计数脉冲频率必须是机器频率的一半以下,即计数脉冲周期大于2us

计数的原理:

设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。在每个机器周期的S5P2期间采样T0、T1引脚电平。当某周期采样到一高电平输入,而下一周期又采样到一低电平时,则计数器加1,更新的计数值在下一个机器周期的S3P1期间装入计数器。由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。当晶振频率为12MHz时,最高计数频率不超过1/2MHz,即计数脉冲的周期要大于2 us。

工作模式:初始化寄存器

高4bit和低4bit分别控制两个Timer

  • GATE=0时,用软件将TR0/TR1=1就可以定时/计数
  • GATE=1时,除了软件置位外,还需要外部中断引脚INT0/INT1=1
  • \(\mathsf{C/\bar{T}}\):定时/计数选择;=0为定时,接内部时钟;=1为计数,接外部脉冲
  • M1M0的用处如下

方式2用于精确定时

控制寄存器TCON

0/1分别控制Timer0/1,以1为例

  • TF1:是T1溢出中断请求标志位。T1溢出时硬件自动置为1,CPU响应后自动清零;CPU可以查询/更改TF1状态,可作为标志位或进行软件更改,效果和硬件一致
  • TR1TR1=1,T1开始工作;TR1=0,T1停止工作;由软件决定,故可以软件控制Timer的启动/停止;硬件不会改变这值,程序员自己改变

8.3 工作模式

方式0

注意计数位只有13位,且中间是不用的,在初始化时要注意;TMOD选为00

初值的计算公式为
\[ x = 2^{13} - N \]
其中\(N\)为要计的时长对应的数字

方式1

16位,都能用,TMOD选为01

初值计算公式为
\[ x = 2^{16} - N \]

方式2

此时是自动补充模式,8位,TMOD选为10

初值计算公式为
\[ x = 2^{8} - N \]

方式3

此时将T0拆分为两个独立的8位计数器,高八位占用了T1的资源,因此T1不能工作在这个模式;此时T1只能作为非中断方式使用,如作为串口波特率发生器等

8.4 应用实例

例:测量外部中断管脚输入的正脉冲宽度

解:初值为0,GATE=1, TR0=1,等待外部正脉冲开始计时,工作在MOD=0,将脉冲接在INT0作为中断输入,在电平转为负时停止计数,读出计数值,乘以周期

例:扩展外部中断

解:工作在MOD=2TH0=TL0=FFH,此时只要T0口来一个脉冲下降沿,TL0+=1产生一个定时器中断

例:用T0的方式1,产生10ms的定时,并使P1.0引脚上输出20ms的方波,系统时钟频率为12MHz

解:机器周期为1us,需要计数\(N=10000\)次,\(X=2^{16}-N=\mathsf{D8F0H}\),将D8送入TH0,将F0送入TL0

M1M0=01, GATE=0, C/T=0,程序如下

ORG   0000H
		LJMP  MAIN              ;跳转到主程序
ORG   000BH              		;T0的中断入口地址
		LJMP  DVT0              ;转向中断服务程序
ORG   0100H
MAIN:	MOV   TMOD, #01H		;置T0工作于方式1
        MOV   TH0, #0D8H        ;装入计数初值
        MOV   TL0, #0F0H          
        SETB  ET0               ;T0开中断
        SETB  EA                ;CPU开中断
        SETB  TR0               ;启动T0
        SJMP $                  ;等待中断
DVT0:	CPL   P1.0              ;P1.0取反输出
        MOV   TH0, #0D8H        ;重新装入计数值
        MOV   TL0, #0F0H
		RETI                    ;中断返回
END


Comments