概述
定时器简介
介绍定时器之前,先说明几个CPU 时序的有关知识。
- 振荡周期:为单片机提供定时信号的振荡源的周期
- 状态周期:1 个状态周期 = 2 个振荡周期
- 机器周期:1 个机器周期 = 6 个状态周期 = 12 个振荡周期。
- 指令周期:完成 1 条指令所占用的全部时间,以机器周期为单位。
以12MHz外接晶振为例(注意,Hz表示每秒钟周期性振动(振荡)的重复次数,每秒钟振动一次为1赫兹。单位换算:1THz=1*10^3GHz=1*10^6Mhz=1*10^9KHz=1*10^12Hz):
- 振荡周期=1/12us; //相当于1/12X10^6,所以此处单位为us
- 状态周期=1/6us;
- 机器周期=1us;
- 指令周期=1~4us
51 单片机有两组定时/计数器,因为既可以定时,又可以计数,故称之为定时器/计数器。定时/计数器的工作过程是自动完成的,不需要 CPU 的参与,它们相互独立,执行不同的任务,因此可以增加单片机的效率。
定时/计数器根据 “机器内部的时钟” 或 “外部的脉冲信号” 对寄存器中的数据加 1,可以实现精确定时的作用。
定时器原理
定时/计数器的实质是加 1 计数器(16 位),由高 8 位和低 8 位两个寄存器 THx 和 TLx 组成。随着计数器的输入脉冲进行自加 1,即,每输入一个脉冲,计数器就自动加 1,当加到计数器为全 1 时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位(TF0/TF1)置 1,向 CPU 发出中断请求(定时 /计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到; 如果工作于计数模式,则表示计数值已满。所以,由 “溢出时计数器的值” 减去 “计数初值” 才是加 1 计数器的计数值。
定时/计数器结构
内部结构如下所示:
图中的 T0 和 T1 引脚对应单片机 P3.4 和 P3.5 管脚。定时/ 计数器的工作由两个特殊功能寄存器控制。
TMOD:定时/计数器的工作方式寄存器,确定工作方式和功能
TCON:控制寄存器,控制 T0、T1 的启动和停止及设置溢出标志
工作方式寄存器TMOD
工作方式寄存器 TMOD 用于设置定时/计数器的工作方式,低四位用于T0,高四位用于 T1。其格式如下:
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节地址:89H | GATE | C/ | M1 | M0 | GATE | C/ | M1 | M0 |
GATE: 门控位, GATE=0 时,用于控制定时器的启动是否受外部中断源信号的影响。使 TCON 中的 TR0 或 TR1 为 1,就可以启动定时/计数器工作;GATA=1 时,使 TR0 或 TR1 为 1,同时外部中断引脚 INT0或 INT1 也为高电平时,才能启动定时/计数器工作。即,此时定时器的启动条件,加上了 INT0或 INT1 也为高电平这一条件。
C/T :定时/计数模式选择位。C/T =0 为定时模式;C/T =1 为计数模式。
M1、M0:工作方式设置位。定时/计数器有四种工作方式。
M1 | M0 | 工作方式 | 说明 |
---|---|---|---|
0 | 0 | 方式0 | 13位定时/计数器 |
0 | 1 | 方式1 | 16位定时/计数器 |
1 | 0 | 方式2 | 8位自动重装定时/计数器 |
1 | 1 | 方式3 | T0分成两个独立的8位定时/计数器;T1此方式停止计数 |
控制寄存器 TCON
TCON 的低 4 位用于控制外部中断,已在前面介绍。TCON 的高 4 位用于控制定 时/计数器的启动和中断申请。其格式如下(0~3为外部中断相关位):
位 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
字节地址:88H | TF1 | TR1 | TF0 | TR0 |
TF1:T1 溢出中断请求标志位。T1 计数溢出时由硬件自动置 TF1 为 1。CPU 响应中断后 TF1 由硬件自动清 0。T1 工作时,CPU 可随时查询 TF1 的状态。所以,TF1 可用作查询测试的标志。TF1 也可以用软件置 1 或清 0,同硬件置 1 或清 0 的效果一样。
TF0:T0 溢出中断请求标志位,其功能与 TF1 类同。
TR1:T1 运行控制位。TR1 置 1 时,T1 开始工作;TR1 置 0 时, T1 停止工作。TR1 由软件置 1 或清 0。即,用软件可控制定时/计数器的启动与停止。
TR0:T0 运行控制位,其功能与 TR1 类同。
定时/计数器的工作方式
这几种工作方式中应用较多的是方式 1 和方式 2。定时器中通常使用定时器方式 1,串口通信中通常使用方式 2。
方式 0:
方式 0 为 13 位计数,由 TL0 的低 5 位(高 3 位未用)和 TH0 的 8 位组成。 TL0 的低 5 位溢出时,向 TH0 进位。TH0 溢出时,置位 TCON 中的 TF0 标志,向 CPU发出中断请求。其结构图如下所示:
门控位 GATE 具有特殊的作用。
当 GATE=0 时,经非门反相后,使或门输出为 1,此时仅由 TR0 控制与门的开启,与门输出 1 时,控制开关接通,计数开始;
当 GATE=1 时,由外中断引脚信号控制或门的输出,此时控制与门的开启由 “外中断引脚信号INT0/1” 和 “TR0” 共同控制。当 TR0=1 时,若外中断引脚信号引脚为高电平,则启动计数,外中断引脚信号引脚为低电平,则停止计数。这种方式常用来测量外中断引脚上正脉冲的宽度。
计数模式时,计数脉冲是 T0 引脚上的外部脉冲。计数初值X与计数个数N的关系为:X=2^13-N。
方式 1:
方式 1 的计数位数是 16 位,由 TL0 作为低 8 位,TH0 作为高 8 位,组成了 16 位加 1 计数器。其结构图如下所示
计数初值X与计数个数N的关系为:X=2^16-N。
方式 2:
方式 2 为自动重装初值的 8 位计数方式。工作方式 2 特别适合于用作较精确的脉冲信号发生器。其结构图如下所示:
方式 3:
方式 3 只适用于定时/计数器 T0,定时器 T1 处于方式 3 时相当于 TR1=0, 停止计数。工作方式 3 将 T0 分成为两个独立的 8 位计数器 TL0 和 TH0。其 结构如下所示:
定时器配置
使用定时器时,配置如下:
- 对 TMOD 赋值,以确定 T0 和 T1 的工作方式
- 根据所要定时的时间计算初值,并将其写入 TH0、TL0 或 TH1、TL1。
- 如果使用中断,则对 EA 赋值1,打开总中断开关。
- 使 TR0 或 TR1 置位,启动定时/计数器定时或计数。
计算定时/计数 器初值
机器周期是 CPU 完成一个基本操作所需要的时间。 其计算公式是:机器周期=1/单片机的时钟频率。单片机 “内部时钟频率” 是 “外部时钟频率” 的 12 分频,即,当外部晶振的频率输入到单片机里面的时候要进行 12 分频。
以12MHZ 晶振为例,则单片机内部的时钟频率就是 12/12MHZ, 当使用 12MHZ 的外部晶振的时候,机器周期=1/1MHz=1us。
假设使用定时/计数器 T0,需要定时 1ms。那么1ms/1us=1000,也就是要计数 1000 个,那么初值就等于:65535-1000+1 (因为计数器计数到 65536(2 的 16 次方)才溢出,所以后面要加 1),且65535-1000+1 =64536,转换为16进制:FC18H(H为后缀),所以初值为 TH0=0XFC,TL0=0X18。
要实现很长时间的定时,比如定时 1 秒钟。可以通过初值设置定时 1ms,每当定时 1ms 结束后又重新赋初值,并且设定一个全局变量累计定时 1ms 的次数,当累计到 1000 次,表示已经定时 1 秒了。同理,当累计到 60000 次,表示已经定时 1 分钟了。这样就可以使用定时器来实现精确延时,替代之前的不精确的 delay 函数了。
以定时器 0 为例,介绍配置定时器工作方式为1、设定 1ms 初值、开启定时器计数功能以及总中断的程序,如下所示:
void TIME0_INIT(void)
{
TMOD |= 0X01; //选择为定时器 0 模式,工作方式 1
TH0 = 0XFC; //给定时器赋初值,定时 1ms
TL0 = 0X18;
ET0 = 1; //打开定时器 0 中断允许
EA = 1; //打开总中断
TR0 = 1; //T0 运行控制位置1,打开定时器0
}
定时器 1 也是一样的的使用方法,只是将上述的 0 变为 1 即可。
void TIME1_INIT(void)
{
TMOD |= 0X01; //选择为定时器 1 模式,工作方式 1
TH1 = 0XFC; //给定时器赋初值,定时 1ms
TL1 = 0X18;
ET1 = 1; //打开定时器 1 中断允许
EA = 1; //打开总中断
TR1 = 1; //T1 运行控制位置1,打开定时器1
}
硬件部分
使用到硬件资源如下:
- LED 模块(LED 灯D1)
- 定时器 0
定时器 0 属于 51 单片机内部资源,通过软件配置即可使用。
软件部分
代码结构和逻辑很简单,首先定义控制 LED1 指示灯的管脚,然后定义定时器 0 中断配置函数 TIME1_INIT( ),然后进入 while 循环,在循环体内没有执行任何功能程序,知识等待定时器 0中断的产生。 当定时时间到达即会进入定时器 0 中断,在中断服务函数内,重新赋初值准备下次计数,并且定义一个静态变量来累计定时 1ms 次数,当变量等于 1000 时,表示定时时间达 1 秒,然后清零变量以及控制 LED 状态翻转,实现LED灯的亮灭。执行完成后退出中断,返回主函数,当时间到达又进入中断,如此循环。
使用关键字 static 定义一个静态变量,能在每次进入或退出中断函数时,保存静态变量的值不变,这是C语言作用域相关的知识点,不理解可以网上去查看一些资料。
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
//定义LED1管脚
sbit LED1=P2^0;
void TIME0_INIT(void)
{
TMOD|=0x01;//选择为定时器0模式,工作方式1
TH0=0xFC; //给定时器赋初值,定时1ms
TL0=0x18;
ET0=1;//打开定时器0中断允许位
TR0=1;//T0 运行控制位置1,打开定时器0
EA=1;//打开总开关
}
void main()
{
TIME0_INIT();//定时器0中断配置
while(1)
{
}
}
void TIME0() interrupt 1 //定时器0中断函数
{
static u16 i; //定义静态变量
TH0=0xFC; //重新赋定时/计数的器初值,使计数器计数 1000 个后再一次溢出
TL0=0x18;
i++; //每一次进入中断增加1,增加到1000,就表示定时1s了
if(i==1000)
{
i=0; //重新赋值为0,为1s的时间积累做准备
LED1=!LED1; //实现LED灯的亮灭
}
}
现象
LED指示灯 D1 间隔 1 秒闪烁。
最后
以上就是标致酸奶为你收集整理的定时器中断定时器简介定时器原理定时/计数器结构定时/计数器的工作方式定时器配置硬件部分 软件部分 现象 的全部内容,希望文章能够帮你解决定时器中断定时器简介定时器原理定时/计数器结构定时/计数器的工作方式定时器配置硬件部分 软件部分 现象 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复