51单片机定时器概述及例程分析

控制/MCU

1814人已加入

描述

6.1 51单片机定时器概述

6.1.1 定时器的描述

要实现定时功能,除了利用单片机内部的定时/计数器,也可以采用下面三种方法:

(1)软件定时:软件定时不占用硬件资源,但占用了CPU时间,降低了CPU的利用率。

(2)采用时基电路定时:例如采用555电路,外接必要的元器件(电阻和电容),即可构成硬件定时电路。但在硬件连接好以后,定时值与定时范围不能由软件进行控制和修改,即不可编程。

(3)采用可编程芯片定时:这种定时芯片的定时值及定时范围很容易用软件来确定和修改,此种芯片定时功能强,使用灵活。在单片机的定时/计数器不够用时,可以考虑进行扩展。

定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0,T1的启动和停止及设置溢出标志。

加1计数器输入的计数脉冲有两个来源,一个是由系统的时钟振荡器输出脉冲经12分频后送来;另一个是 T0 或T1引脚输入的外部脉冲源。每来一个脉冲计数器加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出会使TCON中TF0或TF1置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值。

设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值乘以机器周期就是定时时间。

设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。在每个机器周期的某个期间采样T0、T1引脚电平。当某周期采样到一高电平输入,而下一周期又采样到一低电平时,则计数器加1,更新的计数值在下一个机器周期装入计数器。由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。当晶振频率为12MHz 时,最高计数频率不超过6MHz,即计数脉冲的周期要大于2us。

6.1.2 51单片机定时器结构

计数器

6.1 定时器中断相关寄存器

6.1.1 工作模式寄存器TMOD

寄存器地址:0x89

 

Bit  7 Bit  6 Bit  5 Bit  4 Bit  3 Bit  2 Bit  1 Bit  0
GATE C/T M1 M0 GATE C/T M1 M0

 

Bit 7:定时器1门控

0:关闭门控,只要TR1为1,就可以启动定时/计数器工作

1:开启门控,此时只有当TR1为1且外部中断引脚为高电平时,才能够启动定时器工作

Bit 6:定时器1工作模式选择

0:定时模式,时钟源来自MCU内部

1:计数模式,时钟源来自T1引脚上

Bit 5~Bit 4:定时器1计数模式选择

00:数据寄存器使用13位

01:数据寄存器使用16位

10:8位自动重装定时/计数器

11:T1停止计数

Bit 3:定时器0门控

0:关闭门控,只要TR0为1,就可以启动定时/计数器工作

1:开启门控,此时只有当TR0为1且外部中断引脚为高电平时,才能够启动定时器工作

Bit 2:定时器0工作模式选择

0:定时模式,时钟源来自MCU内部

1:计数模式,时钟源来自T0引脚上

Bit 1~ Bit 0:定时器0计数模式选择

00:数据寄存器使用13位

01:数据寄存器使用16位

10:8位自动重装定时/计数器

11:T0分成两个独立的8位定时/计数器

6.1.2 定时器0数据寄存器高字节TH0

寄存器地址:0x8C

 

Bit  7 Bit  6 Bit  5 Bit  4 Bit  3 Bit  2 Bit  1 Bit  0
定时器0计数值高八位

 

6.1.3 定时器0数据寄存器低字节TL0

寄存器地址:0x8A

 

Bit  7 Bit  6 Bit  5 Bit  4 Bit  3 Bit  2 Bit  1 Bit  0
定时器0计数值低八位

 

6.1.4 定时器1数据寄存器高字节TH1

寄存器地址:0x8D

 

Bit  7 Bit  6 Bit  5 Bit  4 Bit  3 Bit  2 Bit  1 Bit  0
定时器1计数值高八位

 

6.1.5 定时器1数据寄存器低字节TL1

寄存器地址:0x8B

 

Bit  7 Bit  6 Bit  5 Bit  4 Bit  3 Bit  2 Bit  1 Bit  0
定时器1计数值低八位

 

6.2 例程分析

6.2.1 原理图

计数器

6.2.2 实现的功能

使用定时器0,控制LED以1Hz频率闪烁。

6.2.3 源代码

计数器

重点关注以下几行代码:

第20行:定义了一个unsigned char的变量,为什么要定义这样一个全局变量。首先定时器的数据寄存器只有16位,也就是说最大数据范围只有65535,超过这个数据后就会从0重新开始计时,根据单片机的计数周期设置在1us,最大定时时间只有65.535ms,而达到1s是远远不够的,所以定义一个全局变量来计算定时器产生中断的次数,假设我们设置定时器50ms中断一次,那么,当进入20次中断,则意味着定时器刚好定时1s。

第28行:这里用到了一条语句,LED = !LED,叹号代表取反,只能用于布尔型变量,所谓布尔型变量就是只有0和1两种状态,也就是1个二进制位,在C语言中,叹号代表二进制位取反,“~”则代表按位取反运算,例如有一个二进制位初值是1,取反的结果就是0,但是如果有一个字节0x8F,此时只能用按位取反运算,而不能用二进制位取反运算,0x8F按位取反的结果应该是0x70,例程中这条语句的含义就是LED二进制位取反后将结果重新赋值给LED变量。

第23行~第24行:这两行用于给定时器重新写入初值,因为51单片机的数据寄存器进入中断后就会从0开始重新计数,假设最开始设置的值是1000,进入中断后,定时的时间就是65535-1000+1=64536us,进入中断如果不设置初值,那么下一次进入中断时定时的时间就是65536us,与最初的时间误差是65536-64536=1000us,所以每次进入中断都需要给数据寄存器重新写入初值。

第42行~第43行:定时器在初始化的时候就要给写入初始值,为什么要写入这个初始值呢,首先数据寄存器是只能加1运算,从0加到65535,但是如果我们只想要定时50us就进入中断应该怎么处理呢,这就需要给定时器的数据寄存器先写入一个数,让定时器从这个数开始加1,加到65535刚好是50us,那么这个初值就是65535-50,这个定时的时间刚好就是50us,而/和%则是代表取整和取余。

注:取整与取余运算

(1)取整运算:用/表示,代表取除法运算中整数部分,例如2/3,得到的结果就是商为0且余数为2,此时取整运算得到的结果就是0;

(2)取余运算:用%表示,代表取除法运算中余数部分,例如2/3,得到的结果就是商为0且余数为2,此时取余运算得到的结果就是2。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分