定时/计数器

一、定时/计数器 的方式寄存器 TMOD

TMOD D7 D6 D5 D4 D3 D2 D1 D0
(89H) GATE C/T M1 M0 GATE C/T M1 M0
定时器1 定时器1 定时器1 定时器1 定时器0 定时器0 定时器0 定时器0

M1 M0 定时计数器的方式

T0的4个工作方式、T1的3个工作方式:

M1 M0 工作方式 方式说明
0 0 0 13位定时计数器
0 1 1 16位定时计数器
1 0 2 8位自动重置定时计数器
1 1 3 两个8位自动重置定时计数器 (仅T0有)

C/T 定时 或 计数器

C/T = 1 计数方式

C/T = 0 定时方式

GATE

门控位,用于定时或计数是否受外部中断请求信号的影响。

二、定时/计数器 的方式寄存器 TCON

TCON D7 D6 D5 D4 D3 D2 D1 D0
88H TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

TF 定时/计数器溢出位,超出上限值就会置1,若进入中断自动清0 定时/计数器范围(0—-2几位定时-1)

TR 设置定时计数器是否启动

IE 外部中断请求标志位

IT 外部中断的触发方式位 ==0 电平触发 ==1边缘触发

初值保存在TH/L 高八位:TH0/1 和 低八位:TL0/1

定时器

定时器工作方式计算

(单片机的定时器是微秒 um)1000000um=1000ms=1s

f: 晶振频率 51单片机有 12MHz 或者 11.0592MHz(用于通信)

方式0: 13位定时器

计数值 N:要获得的时间(微秒um)

初值 X = 8192 - N / ( 12 / f ) 213= 8192

数值保存在:高八位:TH0/1 和 低八位:TL0/1

计数完后,计数器值为0,重新计数要重置初值

方式1: 16位定时器

计数值 N:计数的时间(微秒um)

初值 X = 65536- N / ( 12 / f ) 216= 65536

数值保存在: 高八位:TH0/1 和 低八位:TL0/1

计数完后,计数器值为0,重新计数要重置初值

方式2:8位自动重置定时器

自动装填,保持上次的初值,不需要重复赋初值。

初值 X = 256- N / ( 12 / f ) 28= 256

方式3:只有T0才有

自动装填,保持上次的初值,不需要重复赋初值。

初值 X = 256- N / ( 12 / f ) 28= 256

程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include"reg51.h"
char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
char count=0,num=0;

// 使用定时器0 所以高四位设置为0,低四位配置。使用16位,定时器 所以第四位为:0001
void inittimer()
{
TMOD=0x01; // TMOD: 0000 0001
TH0=(65536-50000)/256; // 这里是高八位
TL0=(65536-50000)%256; // 取余是低八位
ET0=1; // 开启定时器0的中断
EA=1; // 开启总中断
TR0=1; // 启动定时器0
}

void display()
{
P2=s[num];
if(num==10)
{
num=0;
}
}

void main()
{
inittimer(); // 初始化寄存器
while(1)
{
display();
}
}

// 进入中断
// 0表示外部中断0;1表示定时器中断0 ;2表示外部中断1; 3表示定时器中断1; 4表示串口中断;
void timer_isr() interrupt 1
{
TH0=(65536-50000)/256; // 这里要重新赋初值
TL0=(65536-50000)%256;
count++;
if(count==20)
{
num++;
count=0;
}
}

计数器

定时器工作方式计算

方式0: 13位计数器

计数值 N:要获得的时间(微秒um)

初值 X = 8192 - N 213= 8192

计数完后,计数器值为0,重新计数要重置初值

方式1: 16位计数器

计数值 N:计数的时间(微秒um)

初值 X = 65536- N 216= 65536

计数完后,计数器值为0,重新计数要重置初值

方式2:8位自动重置计数器

自动装填,保持上次的初值,不需要重复赋初值。

初值 X = 256- N 28= 256

方式3:只有T0才有

自动装填,保持上次的初值,不需要重复赋初值。

初值 X = 256- N 28= 256

程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include"reg51.h"

char s[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //段码
int num=0;

void initcounter() //初始化计数器
{
TMOD=0x06; // 0000 0110
TH0=256-3;
TL0=256-3;
ET0=1;
EA=1;
TR0=1;
}

void display()
{
P2=s[num];
if(num==10)
num=0;
}

void main()
{
initcounter();
while(1)
{
display();

}
}

void counter_isr() interrupt 1
{
num++;
}