STC89C5X含有3个定时器:定时器0、定时器1、定时器2
注意:51系列单片机一定有基本的2个定时器(定时器0和定时器1),但不全有3个中断,需要查看芯片手册,通常我们使用的是基本的2个定时器:定时器0/1
1、定时器介绍
CPU时序的有关知识:
①振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期)。
②状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。
③机器周期:1个机器周期含6个状态周期,12个振荡周期。
④指令周期:完成1条指令所占用的全部时间,它以机器周期为单位
eg:外接晶振为12MHz时,51单片机相关周期的具体值为:振荡周期=1/12us;状态周期=1/6us; 机器周期=1us;指令周期=1-4us;
注意:
①51单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之为定时器/计数器。
②定时器/计数器和单片机的CPU是相互独立的。定时器/计数器工作的过程是自动完成的,不需要CPU的参与。
③51单片机中的定时器/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器中的数据加1
2、单片机定时器原理
STC89C5X单片机内有两个可编程的定时/计数器T0、T1和一个特殊功能定时器T2
定时/计数器的实质是加1计数器(16 位),由高8位和低8位的两个寄存器THx和TLx组成。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时 /计数器中断允许时)
如果定时/计数器工作于定时模式,则表示定时时间已到; 如果工作于计数模式,则表示计数值已满
可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值
3、单片机定时/计数器结构 T0 T1
(1)51单片机均有的5个中断来介绍,其内部结构框图如下所示:
T0对应的是P3.4口的附加功能,TF0(TCON.5),片内定时/计数器T0溢出中断请求标志。当定时/计数器T0发生溢出时,置位TF0,并向CPU申请中断,中断号为1
T1对应的是P3.5口的附加功能,TF1(TCON.7),片内定时/计数器T1溢出中断请求标志。当定时/计数器T1发生溢出时,置位TF1,并向CPU申请中断,中断号为3
(2)51 单片机定时器/计数器内部结构如下所示:
TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志
3.1 工作方式寄存器 TMOD
工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1
(1)GATE:门控位。
GATE=0时,用于控制定时器的启动是否受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;
GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。
(2)C/T:定时/计数模式选择位。C/T=0为定时模式;C/T=1为计数模式
(3)M1M0:工作方式设置位。定时/计数器有四种工作方式
3.1.1 方式0(了解)
方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU 发出中断请求
门控位GATE具有特殊的作用。
当GATE=0时,经反相后使或门输出为1,此时仅由TR0控制与门的开启,与门输出1时,控制开关接通,计数开始;
当GATE=1时,由外中断引脚信号控制或门的输出,此时控制与门的开启由外中断引脚信号和TR0共同控制。
当TR0=1时,外中断引脚信号引脚的高电平启动计数,外中断引脚信号引脚的低电平停止计数。这种方式常用来测量外中断引脚上正脉冲的宽度。
计数模式时,计数脉冲是T0引脚上的外部脉冲。计数初值与计数个数的关系为:X=2^13-N。
3.1.2 方式1(用于定时器)
方式1的计数位数是16位,由TL0作为低8位,TH0作为高8位,组成了16位加1计数器
与方式0的运行模式一样
计数初值与计数个数的关系为:X=2^16-N
3.1.3 方式2(用于串口)
方式2为自动重装初值的8位计数方式。工作方式2特别适合于用作较精确的脉冲信号发生器
与方式0的运行模式一样
计数初值与计数个数的关系为:X=2^8-N
3.1.4 方式3(了解)
方式3只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,停止计数。工作方式3将T0 分成为两个独立的8位计数器TL0和TH0
与方式0的运行模式一样
3.2 控制寄存器 TCON
TCON的低4位用于控制外部中断,已在前面介绍。TCON的高4位用于控制定时/计数器的启动和中断申请
(1)TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。 所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
(2)TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1 停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
(3)TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
(4)TR0(TCON.4):T0运行控制位,其功能与TR1类同。
4、定时器配置
(1)对TMOD赋值,以确定T0和T1的工作方式,如果使用定时器0即对T0配 置,如果使用定时器1即对T1配置
(2)根据所要定时的时间计算初值,并将其写入TH0、TL0或TH1、TL1
(3)如果使用中断,则对EA赋值,开放定时器中断
(4)使TR0或TR1置位,启动定时/计数器定时或计数
eg:以定时器0为例介绍配置定时器工作方式1、设定1ms初值
void time0_init(){
TMOD|=0x01; //工作方式1,|:为了不干扰定时器1
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
EA=1; //打开总中断开关
ET0=1; //打开定时器0的中断允许
TR0=1; //打开定时器
}
TH0=0XFC和TL0=0X18是通过51定时器计算软件得到的
5、软件设计
要实现的功能是:通过定时器0中断控制D1指示灯间隔1秒闪烁
#include "reg51.h"
typedef unsigned int u16;
typedef unsigned char u8;
sbit LED1=P2^0;
//初始化定时器0中断,使用工作方式1
void time0_init(){
TMOD|=0x01; //|:为了不干扰定时器1
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
EA=1; //打开总中断开关
ET0=1; //打开定时器0的中断允许
TR0=1; //打开定时器
}
void main(){
time0_init();
while(1){
}
}
//定时器中断服务函数
void time0() interrupt 1{
static u16 i=0; //一定要加static关键字
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
i++;
if(i==1000){ //计时1s
i=0;
LED1=!LED1;
}
}
为什么要使用关键字static将i定义为静态变量呢?
我们希望每次进入中断函数时,i保存的是上次累加值,使用了static关键字,就可以让变量i实现这种功能,即不会每次进入中断函数后被初始化为0。假如去掉static关键字,那么变量i就是一个局部变量,每次进入中断函数后,变量i初始值都是0, 也就是说它的值永远也不会递增到1000,从而实现不了1s定时。可以这样理解, 使用了static关键字就相当于将i变成了一个全局变量功能