1 定时/计数器的主要特点
- MCS -51系列中51子系列有两个16位的可编程定时/计数器:定时/计数器 T0 和定时/计数器T1;52子系列有三个,比51子系列多一个定时/计数器T2。
- 每个定时/计数器既可以对系统时钟计数实现定时,也可以对外部信号计数实现计数功能,这些功能都是通过编程设定来实现的。
- 每个定时/计数器都有多种工作方式,其中 T0有四种工作方式:T1有三种工作方式,T2有三种工作方式。通过编程可设定工作于某种方式。
- 每一个定时/计数器定时计数时间到时产生溢出,使相应的溢出位置位。溢出可通过查询或中断方式来处理。
2 定时/计数器T0、T1的结构及工作原理
定时/计数器 T0 、T1的结构如图1所示,它由加法计数器、方式寄存器 TMOD 、控制寄存器 TCON 等组成。
定时/计数器的核心是16位加法计数器,在图中用特殊功能寄存器TH0、TL0及TH1、TL1表示。TH0、 TL0 是定时/计数器 T0 加法计数器的高8位和低8位。TH1、 TLI 是定时/计数器T1加法计数器的高8位和低8位。方式寄存器 TMOD 用于设定定时/计数器 T0 和T1的工作方式,控制寄存器 TCON 用于对定时/计数器的启动、停止进行控制。
当定时/计数器用于定时时,加法计数器对内部机器周期 Tcy 进行计数。由于机器周期时间是定值,因此对 Tcy 的计数就是定时,如 Tcy = 1us ,计数100,定时100us。当定时/计数器用于计数时,加法计数器对单片机芯片引脚T0(P3.4)或T1(P3.5)上的输入脉冲进行计数。每来一个输入脉冲,加法计数器加1。当由全1再加1变成全0时产生溢出,使溢出位 TF0 或TF1置位,如中断允许,则向 CPU 提出定时/计数中断;如中断不允许,则只有通过查询方式使用溢出位。
第一,由于它是加法计数器,每来一个计数脉冲,加法器中的内容加1个单位,当由全1加到全0时计满溢出。因而,如果要计 N 个单位,则首先应向计数器置初值为 X ,且有:
初值 X =最大计数值(满值) M ﹣计数值 N
在不同的计数方式下,最大计数值(满值)不一样。一般来说,当定时/计数器工作于 R 位计数方式时,它的最大计数值(满值)为2的 R 次幂。
第二,当定时/计数器工作于计数方式时,对芯片引脚 T0(P3.4)或T1(P3.5)上的输入脉冲计数。计数过程如下:在每一个机器周期的S5P2时刻对T0(P3.4)或T1(P3.5)上的信号采样一次,如果上一个机器周期采样到高电平,下一个机器周期采样到低电平,则计数器在下一个机器周期的S3P2时刻加1计数一次。因而需要两个机器周期才能识别一个计数脉冲,所以外部计数脉冲的频率应小于振荡频率的1/24。
3 定时/计数器的方式和控制寄存器
方式寄存器 TMOD 用于设定定时/计数器T0和T1的工作方式。它的字节地址为 (89H)。
其中各二进制位的含义说明如下 。
M1、M0:工作方式选择位,用于对 T0 的四种工作方式、T1的三种工作方式进行选择,选择情况如表:
C / T :定时或计数方式选择位。当C/T=1时工作于计数方式;当C/T=0时工作于定时方式 。
GATE :门控位,用于控制定时/计数器的启动是否受外部中断请求信号的影响。如果 GATE =0,定时/计数器的启动与外部中断请求信号引脚INT0(P3.2)和INT1(P3.3)无关。如果 GATE =1,定时/计数器 T0 的启动还受芯片外部中断请求信号引脚 INT0 (P3.2)的控制,定时/计数器 TI 的启动还受芯片外部中断请求信号引脚INT1(P3.3)的控制,只有当外部中断请求信号引脚 INT0(P3.2)或INT1(P3.3)为高电平时才开始启动计数;利用 GATE 的这个特点可以测量加在 INT0 (P3.2)或INT1(P3.3)引脚上正脉冲的宽度,在一般情况下 GATE =0。
4 定时/计数器的控制寄存器TCON
控制寄存器 TCON 用于控制定时/计数器的启动与溢出,它的字节地址为88H,可以进行位寻址。
其中各二进制位的含义说明如下。
TFl :定时/计数器T1的溢出标志位。当定时/计数器T1计满时,由硬件使它置位,如中断允许则触发T1中断。进入中断处理后由内部硬件电路自动清除
TR1:定时/计数器 TI 的启动位。可由软件置位或清零,当TR1=1时启动;TR1=0时停止。
TF0 :定时/计数器 T0 的溢出标志位,当定时/计数器 T0 计满时,由硬件使它置位,如中断允许则触发T0 中断。进人中断处理后由内部硬件电路自动清除。
TR0 :定时/计数器 T0 的启动位。可由软件置位或清零,当TR0=1时启动; TR0=0 时停止。
TCON 的低4位是用于外中断控制的
5 实例分析
1、 设置一个灯每秒闪烁一次;
2 、设计流水灯,每秒移动一位;
3、 设计一个开关,通过查询方式读入开关状态,控制流水灯移动的方向。
#include "reg51.h"
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit led=P1^0;
sbit key=P3^0;
uchar i,j;
void delay(uint k){
while(k--);
}
//定时器初始化
void time_init(){
TMOD=0x01;//定时器T0
TH0=0xD8;//定时10ms 65536-10000
TL0=0xF0;
TR0=1;//启动T0定时器
ET0=1;
EA=1;
}
void left(){//LED灯每1秒闪烁一次并向左移动
P2=0x00;
j=0x01;
while(1){
if(i==100){
led=!led;
P2=~j;
j=j<<1;
if(j==0){j=0x01;}
i=0;
}
}
}
void main()
{
i=0;
P2=0x00;//系统默认定义变量,大写
j=0x80;
P3=0xff;
time_init();
while(1){
if(i==100){//设置了10*100ms=1s的定时,流水灯每隔1s闪烁
led=!led; //led灯 D1每秒闪烁一次
P2=~j;
j=j>>1;
if(j==0){j=0x80;}
i=0;
}
//开关
if(key==0x00){
delay(1000);//消抖
if(key==0x00){//按动开关流水灯,从低电平走向高电平,并每一秒移动1位
left();
while(!key);
}
}
}
}
void T0_int() interrupt 1{
//TH0,TH0需要重新置入初值
TH0=0xD8;
TL0=0xF0;
i++;
}
示波器得知,led灯每隔一秒闪烁一次。
定时器