定时器的原理与应用
定时器/计数器的方式和控制寄存器
~方式寄存器TMOD
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
定时器1 | 定时器0 |
---|
M1、M0为工作选择位,用于对T0的4种工作方式,T1的3种工作方式(前三种)进行选择,选择情况如下
M1 | M0 | 工作方式 | 方式说明 |
---|---|---|---|
0 | 0 | 0 | 13位定时/计数器 |
0 | 1 | 1 | 16位定时/计数器 |
1 | 0 | 2 | 8位自动重置定时/计数器 |
1 | 1 | 3 | l两个8位定时/计数器(只有T0有) |
C/T:定时或计数器选择位
- C/T=1:计数器方式
- C/T=0:定时方式
GATE:门控位。(一般给0)用于控制定时/计数器的启动是否受外部中断请求信号的影响
- GATE=0: 仅由TR0,TR1置位分别启动定时器T0、T1
- GATE=1:由外部中断引脚INT0、INT1来启动定时器T0、T1
~控制寄存器TCOM
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
TF0(TF1):计数溢出标志位,当计数器计数溢出时,该位置1。
TR0(TR1):定时器运行控制位
- TR0(TR1)=0 停止定时器/计数器工作
- TR0(TR1)=1 启动定时器/计数器工作
IE0(IE1):外部中断0(或1)的请求标志位
- 当CPU采样到P3.2(P3.3)出现有效中断请求时,此位由硬件置1。在中断响应完成后转向中断服务时,再由硬件自动清0。
IT0(IT1):外中断请求信号方式控制位
- IT0(IT1)=1 脉冲方式(后沿负跳有效)
- IT0(IT1)=0 电平方式(低电平有效)此位由软件置1或清0。
定时器/计数器的工作方式
开始先来介绍一下初值有什么用?——初值就是为了设置定时时间或次数
方式0——13位定时/计数器方式
- 计数值N和初值X的关系: X=8192-N/(12/fosc)
- 初值定义:
- 定时/计数器0:TH0(高八位),TL0(低八位)
- 定时/计数器1:TH1(高八位),TL1(低八位)
- 上次计数完,计数器为0,要重复计数需重置初值
方式1——16位定时/计数器方式
- 计数值N和初值X关系:X=65536-N/(12/fosc)
- 上次计数完,计数器为0,要重复计数需重置初值
方式2——8位自动重置定时/计数器(下同)
方式3——8位定时/计数器(只有配置T0才能使用)
- 计数值N和初值X的关系:X=256-N/(12/fosc)
- 上次计数完,计数器自动重置初值。不需要用户重置
注意:
- fosc为晶振频率,51单片机一般为12MHz或者11.0592MHz
- 单片机的单位:μs
代码部分
实现效果
- 通过定时器0中断实现数码管1s循环变化
定时器0中断需要初始化参数
- TMOD
- TH0
- TL0
- ET0
- EA
- TR0
电路图展示
代码
#include"reg51.h"
unsigned char count=0,num=0;
unsigned char str[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//数码显示数字
void inittimer()
{
TMOD=0x01;//0000 0001 定时器0 方式1-16位定时器
TH0=(65536-50000)/256;//定时50ms 取高八位,因此除以256=2^8,相当于初值》8位
TL0=(65536-50000)%256; //取低八位,因此求余256
ET0=1;//开启定时器0中断
EA=1;//开启总中断
TR0=1;//开启定时0
}
void display()
{
P2=str[count];
if(count==10)
{
count=0;
}
}
void main()
{
inittimer();//初始化定时器
while(1)
{
display();//数码管显示
}
}
//定时器中断服务函数
void timer_isr() interrupt 1//0表示外部中断0,1表示定时器中断0,2表示外部中断1,3表示定时器中断1,4表示串口中断
{
TH0=(65536-50000)/256;//重新赋初值
TL0=(65536-50000)%256;
num++;
if(num==20)//50ms*20=1s
{
count++;//中断中要做的事
num=0;
}
}