标题: 51单片机定时器/计数器基础知识介绍 [打印本页]

作者: hushao    时间: 2016-1-5 01:38
标题: 51单片机定时器/计数器基础知识介绍

一、基本概念

1、89C51有两个计数器T0和T1,89C52还有一个T2。每个计数器都是由两个8位的RAM 单元组成的,即每个计数器都是16 位的计数器,最大的计数容量是216=65536,记住是从0-65535。

2、提供给定时器的计数源又是从哪里来的呢?就是由单片机的晶振经过12 分频后获得的一个脉冲源。一个12M 的晶振,它提供给计数器的脉冲时间间隔是就是1us。

3、预置数计数法。如果每个脉冲是1微秒,则计满65536个脉冲需时65.536毫秒。但是如果只需要10毫秒就可以了,怎么办?只要在计数器里预先放进55536,这样只需要计数65536-55536=10000次,也就是10毫秒了。

 

二、相关寄存器

特殊功能寄存器TMOD(89H)
      用于T1          用于T0

GATE   C/T   M1   M0   GATE   C/T   M1   M0

GATE:0用于内部脉冲;1用于外部脉冲。

C/T:0用于定时器;1用于计数器。

M1M0:工作方式

 

 

M1,M0      范围            特性

0,0工作方式0   13位,8192次       为了和51 的前辈48系列兼容。

0,1工作方式1   16位,65536次      16位,其他特性与工作方式0相同,比较常用。

1,0工作方式2   8位,256次        自动再装入预置数,预置数放在T0(或T1)

                         的高8位中,只有低8 位参与计数,通常用于

                         波特率发生器。

 

1,1工作方式3   8位,256次        TH0只能作为定时器用,TL0可作定时器或计数

                         器。溢出标记:TL0 还是用原来的T0的标记,

                         而TH0则借用T1的标记,因此只有在T1 以工

                         作方式2 运行时,才让T0 工作于方式3。

 

特殊功能寄存器TCON(88H)

     用于定时/计数器              用于中断

TF1    TR1    TF0    TR0    IE1    IT1    IE0    IT0

TR0/TR1:定时器的开关。

TF0/TF1:计数溢出后由0变为1

IT0/IT1:定时器/计数器中断允许位。



在今天的分享中我们学习下单片机/计数器的使用,在前面的分享中我们接触到了单片机时钟周期、机器周期和指令周期的概念,我们再温习下:


  1时钟周期 1/晶振频率M

 

  1机器周期 12(51系列为12时钟周期,有的改进型单片机是1时钟周期)×时钟周期=12(1)×(1/晶振频率M)=1us(1/12us,如采用12M晶体)。


 

  如果12MHZ晶振工作在51单片机12T模式下,需要使用定时器进行50ms定时操作,定时器工作在方式1,那么我们该怎样编写程序呢?

  我们知道:

  12M的晶振每秒(s)可产生1M(106us)个机器周期。

 

  50ms就需要50×1000us×1us(1机器周期)个机器周期=50000个机器周期。


 

  如果定时器在方式1工作,是16位计数器,最大值为65536(216),也就是能进行最大65536次计数。而50ms定时操作需要50000个机器周期,1个机器周期=1us,所以需要50000次计数操作。


 

为了计数器定时器工作,需要预先填充定时器初值(初值=定时器计数最大计数次数-所需定时计数次数)。所以需设置定时器初值 15536=65536-50000,即3CB0H(10进制15536转换成16进制数3CB0),所以TH0=0x3c,TL0=0xb0,高位就是 TH0的值,低位为TL0的值。


 

   如果使用11.0592MHZ的晶振,其他条件不变,11.0592M的晶振每秒可产生0.9216M个机器周期,50ms就需要46080 个机器周期。定时器在方式1工作,是16位计数器,最大值为65536,所以需设置初值19456=65536-46080,即4C00H,所以 TH0=0x4c,TL0=0x00。


   由上面的分析,我们可以得出推导16位定时器/计数器初值设定高8位TH0,低TL0的公式为:

   TH0=(65536-所需计数次数)/256=初值/256;

 

   TL0=(65536-所需技术次数)%6=初值%6;


 

   公式中的256是什么意思呢?我们的计时器是两个8位组成的,那么要把那些差值装进这两个8位,计数从低8位开始,那么低8位最多能装256 个机器周期,那么256计满了就用高8位的,就是说低8位满一次高8位加1,那么高8位装多少,低8位就满了几次,算法就是用差值除一下256取其整数, 剩下的,就是还剩了小于256次数的就放在低8位,就是差值的余数。


  下面我们看个定时器/计数器0,产生定时中断的例程。

 

  晶振频率12M,其程序如下:


#include<reg51.h>

 

void timer0_init()

{

 TMOD = 0x01;      //定时器在方式1工作,是16位计数器,最大值为65536

 TL0 = 0xb0;         //给TL0赋计数初值0xb0

 TH0 = 0x3c;         //给TH0赋计数初值0x3c

 TR0 = 1;           //定时器开始计数

 ET0 = 1;           //定时器中断允许

 EA = 1;           //开总中断

}

 

void main()

{

 timer0_init();

 while(1);

}

 

void timer0() interrupt 1

{

 TH0=(65536-50000)/256;    //在中断处理函数中需要重新给TH0赋初值。

 TL0=(65536-50000)%6;    //在中断处理函数中需要重新给TL0赋初值。

 

 加上我们希望的语句。

 

 

}


 

  上面给大家看了一段例程,讲的是如何用定时器/计数器0实现中断。单片机一般还有一个定时器/计数器1,它的编程和定时器/计数器0差不多。


 

另外,单片机定时器/计数器的使用不单单体现在定时器中断方面,但它们的使用都万变不离其综,大家掌握了一种用法,对于其它的应用也就不难掌握了。


作者: Azuruuuu2w    时间: 2016-12-10 18:38
挺好的学习资料,谢谢楼主分享
作者: hurbocn    时间: 2018-4-7 13:08
我学了,挺好的
作者: yu1030974997    时间: 2018-7-16 08:36
知识很详细,谢谢楼书,已学!
作者: 时光倒影    时间: 2018-12-12 19:43
挺好的,谢谢分享
作者: liu631208    时间: 2019-1-22 06:44
好的学习资料,谢谢楼主
作者: SHANWAZI    时间: 2021-1-1 11:49
定时器学起来有点吃力感觉  卡就卡在初值计算方面了一直弄不明白是怎么计算的
作者: ltgyh    时间: 2022-8-27 16:24
我是看不懂,但还是要谢谢楼主
作者: 陆少    时间: 2024-6-14 13:51
TL0应该这样写吧1(65536-50000)%256才对啊




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1