本讲任务:
了解单片机定时器工作原理,通过例程讲解单片机定时器中断程序的编写。
引言:
定时器/计数器的核心是一个16位宽的,由计数脉冲触发的,按递增规律(即累加方式)工作的,循环累加计数器(THx+TLx)。
工作时,循环累加计数器从预先设定的初始值开始,每来一个计数脉冲就加1,当加到循环累加计数器为全1时,再输入一个脉冲,就会产生溢出现象,循环累加计数器回零,同时产生溢出中断请求信号(TFx置1)。
如果定时器工作于定时模式,则表示定时时间已到。
STC89C52RC单片机定时器:
单片机STC89C52RC中有两个定时器/计数器,T0和T1,本讲只讲T0。每个定时器/计数器既可以实现定时功能,也可以实现计数功能,本讲只讲定时功能。
定时器/计数器的结构:
定时器/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD是定时器/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。
定时器/计数器的工作原理:
加1计数器输入的计数脉冲有两个来源:
一个是由系统的时钟振荡器输出脉冲经12分频(机器周期)后送来;
一个是T0或T1引脚输入的外部脉冲信号。
每来一个脉冲计数器加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TF0或TF1置1,向单片机发出中断请求(定时器/计数器中断允许时)。
如果定时器/计数器工作于定时模式,则表示定时时间已到;
如果工作于计数模式,则表示计数值已满。
可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。
定时器/计数器的控制 :
51单片机定时器/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。
一、工作方式寄存器TMOD
工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如下:
GATE:门控位。GATE=0时,只要用软件使TCON中的TR0或TR1为1,就可以启动定时器/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚也为高电平时,才能启动定时/计数器工作。即此时定时器的启动多了一条件。
C/T :定时/计数模式选择位。 C/T =0为定时模式; C/T =1为计数模式。
M1M0:工作方式设置位。定时/计数器有四种工作方式,由M1M0进行设置。
二、控制寄存器TCON
TCON的低4位用于控制外部中断,已在前面介绍。TCON的高4位用于控制定时器/计数器的启动和中断申请。其格式如下:
TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。单片机响应中断后TF1由硬件自动清0。
TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1同。
TR0(TCON.4):T0运行控制位,其功能与TR1类同。
定时/计数器的工作方式 :
一、方式0
方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向单片机发出中断请求。
二、方式1
方式1的计数位数是16位,由TL0作为低8位、TH0作为高8位,组成了16位加1计数器。
三、方式2
方式2为自动重装初值的8位计数方式。TL0的溢出不仅置位TF0,而且将TH0内容重新装入TL0,TH0内容由软件预置,重装时TH0内容不变。
四、方式3
对定时器1,在模式3时,定时器1停止记数,效果与将TR1设置为0相同。
对定时器0,在此模式下定时器0的TL0及TH0作为2个独立的8位计数器。
定时器0初值计算:
定时器初始化:
1:选择工作方式(设置M1,M0)
2:选择控制方式(设置GATE)
3:选择定时器还是计数器模式(设置C/T)
4:给定时/计数器赋初值(设置THx和TLx)
5:开启定时器中断(设置ET0或ET1)
6:开启总中断(设置EA)
7:打开计数器(设置TR1或TR0)
例程:
/*****************定时器0定时点亮LED******************
*单片机:STC89C52RC
*开发环境:KEIL
*功能:上电三秒后,发光二极管被点亮
***********************************************************/
#include<reg52.h>
#define uint unsigned int
uint num=0;
sbit LED=P1^0;
void timer_init()
{
TMOD=0x01; //模式设置0000 0001
TH0=0xff; //定时器0设置,每隔100微秒发起一次中断。
TL0=0xa4;
ET0=1; //允许定时器0中断
EA=1; //开总中断
TR0=1; //打开定时器
}
void main()
{
timer_init();
while(1)
{
if(num==30000) //时隔3s后,LED被点亮。
{LED=0;}
}
}
void time0() interrupt 1
{
TH0=0xff;
TL0=0xa4;
num++;
}
最后,求求看到的此文的小伙伴点赞和关注支持一下下哦。毕竟,码字不容易哦,您的支持是我最大的动力呀!!!呜呜呜~~~