1.定时器/计数器的结构
AT89S51的定时器/计数器结构如图1-1所示,T0由特殊功能寄存器TH0、TL0构成,T1由特殊功能寄存器TH1、TL1构成。
T0 和T1都具有定时器和计数器两种工作模式,4种工作方式(方式0~3)。属于增计数器。
特殊功能寄存器TMOD用于选择T0、T1的工作模式和工作方式。特殊功能寄存器TCON用于控制T0、T1的启动和停止计数,同时包含了T0、T1的状态。
图1-1
2.定时器工作原理
启动定时器后,每个机器周期到来,初值寄存器自动加1,直到计满溢出
- 启动:需要一个启动信号
- 机器周期:以晶振为12MHz为例讲解,一个机器周期是1us
- 初值寄存器:TH0和TL0;TH0是高八位,TL0是低八位;初值均为00H;TH0和TL0共同构成T0的寄存器
- 自动加1:经过一个机器周期加1,从TL0加起
- 溢出:当TH0和TL0为11111111 11111111(转换为十进制为65535),此时再加1则为1 00000000 00000000,1被丢失,即从65535到65536为溢出,定时结束。如图2-1共计65536个机器周期即65536us=65.536ms
图2-1
初值计算
定时50ms(50000us)的实现(65536us以内)
定时时长 | 计机器周期个数 |
---|---|
65536us | 65536 |
50000us | 50000 |
需要实现计50000个周期就溢出,但溢出状态不能修改,则需修改初值
x+50000=65536
x=65536-50000=15536=3cb0
其中3c和b0分别赋给高八位与低八位
TH0=0x3c;
TL0=0xb0;
或
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
定时1s的实现(65536us以外)
50ms*20或10ms*100
编程实现步骤
-
报备
以T0为例
GATE-门控位
0:TR0=1 启动定时器
C/T-定时/计数
0:定时
1:计数
M1、M0-工作方式设置(低八位)
M0 | M1 | |
---|---|---|
模式0:13位定时器/计数器 (TMOD = 0x00) | 0 | 0 |
模式1:16位定时器/计数器 (TMOD = 0x01) | 0 | 1 |
模式2:8位自动重装定时器/计数器 (TMOD = 0x02) | 1 | 0 |
模式3:双重8位定时器/计数器 (TMOD = 0x03) | 1 | 1 |
不可使用每个位单独操作,必须整体赋值
2.置初值
TH0=0x3c;
TL0=0xb0;
或
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
3.启动
启动:TR0=1
停止:TR0=0
4.等待计时时间
TF0溢出后自动置1;手动清0:TF0=0
5.重置初值
6.清溢出
TF0=0;
7.返回第4步等待溢出
定时器方式1
//定时器方式1实现
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
void main(void)
{
unchar k,n,i;
n=0x01;
k=0;
TMOD = 0x01; //定时方式1
TH0 = (65535-50000)/256; //设置定时器时间为50ms
TL0 = (65535-50000)%256;
TR0= 1; //定时计数器启动
while(1);
{
n=0x01;
for(i=0;i<8;i++)
{
p0=~n;
while(k<10);
{
while(TF0==0);
TH0 = (65535-5000)/256; //重置初值
TL0 = (65535-5000)%256;
TF0=0; //清溢出
k++;
}
k=0;
n=n<<1;
}
}
}
定时器方式2
与方式1的不同点
- 计数长度不同
方式2 256
方式1 65536
- 方式2可自动重置初值
TL0=初值
TH0=初值