前言
本文介绍基于常见的51单片机,即如下图的芯片:
- AT89C51具备2个定时器/计数器,即定时器/计数器 0、定时器/计数器 1 ( 简称 T0 / T1)。
- T0 有 4 种工作方式,T1 有 3 种工作方式,2个定时器前3种工作方式一样,但是在T0 处于工作方式 3 时,T1 只能作为波特率发生器。
工作方式 | 说明 |
0 | 13位定时/计数器(最大值8192) |
1 | 16位定时/计数器(最大值65535) |
2 | 8位自动重装载定时/计数器(最大值255) |
3 | 定时器0为双8位定时器,可独立使用 |
- 有关定时器配置的2个重要寄存器为:TMOD(T工作模式寄存器) 和 TCON(T控制寄存器)
一、定时器/计数器相关寄存器介绍
1.TMOD:定时器/计数器工作模式寄存器
作用于 T1 | 作用于 T0 | |||||||
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
TMOD | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
对寄存器位功能介绍如下:
①GATE
GATE=0,TR0或TR1软件置1,定时器T0/T1工作。一般应用下此位配置为0
GATE=1,TR0或TR1软件置1,同时外部中断引脚INT0/INT1对应为高电平,定时器T0/T1工 作
②C/T:
C/T=0,T作为定时器时钟来自 晶振
C/T=1,T作为计数器时钟来自P3.4(T0)或P3.5(T1),即外部脉冲
③M1、M0
2位取值不同,设置定时器/计数器的工作方式。
M1 | M0 | 工作方式 | 说明 | 12M晶振下最大计数值 |
0 | 0 | 0 | 13位定时/计数器(最大值8192) | 8.192 ms |
0 | 1 | 1 | 16位定时/计数器(最大值65535) | 65.535 ms |
1 | 0 | 2 | 8位自动重装载定时/计数器(最大值255) | 256 us |
1 | 1 | 3 | 定时器0为双8位定时器,可独立使用 | 256 us |
一般应用中,方式 0 使用较少;方式 1 一般用来做定时器中断,定时处理某个程序;方式 2 一般用来做波特率发生器,因为其自动重装载功能可能减少软件装载产生的时间误差;方式 3 也较为少用,在定时器不够且需要串口通信时,T0 使用在方式 3 做2个8位定时器用,T1工作在方式 1 做串口波特率发生器。
2.TCON:定时器/计数器控制寄存器(可位寻址)
位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
TCON | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
对寄存器位功能介绍如下:
①TF1: T1 溢出标志位。T1溢出后,硬件置1,硬件清0。
②TR1:T1 运行控制位。在 GATE=0时(此位功能见上文TMOD介绍),只要TR1=1 , T1开始工作。
③TF0:T0 溢出标志位。T0溢出后,硬件置1,硬件清0。
④TR0:T0 运行控制位。在 GATE=0时(此位功能见上文TMOD介绍),只要TR0=1 , T0开始工作。
⑤IE1:外部中断1请求标志位。硬件置1,硬件清0。
⑥IT1:外部中断1触发方式控制位。IT1=0,低电平触发;IT1=1,下降沿触发。
⑦IE0:外部中断0请求标志位。硬件置1,硬件清0。
⑧IT0:外部中断0触发方式控制位。IT0=0,低电平触发;IT0=1,下降沿触发。
在这个寄存器中,只需要管 TR0 和 TR1 位,因为这是用来启动定时器的。TF0 和 TF1 溢出标志位用于CPU触发定时器中断,不需要配置。
3.TL0、TH1、TL1、TH1
这四个位,用来配置 T0 和T1 的初值。
12M 晶振下,T0 工作方式1 下定时 50ms,程序配置语句为:
TL0=(65535-50000) %256 ;
TH0=(65535-50000) / 256 ;
以上是比较简单快捷的赋值方法,如果使用十六进制,则为:
TL0 = 0xAF ;
TH0 = 0x3C ;
因为 (65535-50000) = 15535 = 0x3CAF ; 方式1最大定时65.536ms,如果定时更久就要用软件处理,多次定时叠加。
二、程序应用
1、T0 方式 1 定时器中断 500ms
#include "reg51.h"
unsigned int count=0;
void TIM0( ) interrupt 1
{
TL0=(65535-50000)%256;
TH0=(65535-50000)/256;
if(--count == 0 )
{
count=10; // 50ms *10 = 500ms
//........(something to do)
}
}
void main( )
{
TMOD=0X01; //定时器T0工作方式1
TL0=(65535-50000)%256; //50ms
TH0=(65535-50000)/256;
TR0=1; //启动T0
ET0=1; //使能T0溢出中断
EA=1; //打开总中断
while(1);
}
1、T1 方式 1 定时器中断 300ms
#include "reg51.h"
unsigned int count=0;
void TIM1( ) interrupt 3
{
TL1=(65535-3000)%256;
TH1=(65535-5000)/256;
if(--count == 0 )
{
count=100; // 3ms *100 = 300ms
//........(something to do)
}
}
void main( )
{
TMOD=0X10; //定时器T1工作方式1
TL1=(65535-3000)%256; //3ms
TH1=(65535-3000)/256;
TR1=1; //启动T1
ET1=1; //使能T1溢出中断
EA=1; //打开总中断
while(1);
}
可以对比着看一下2个定时器配置上的不同,如果想自定义自己的功能,可以充分理解上述内容后自己编写程序。