51单片机定时器工作方式1、2原理详解 您所在的位置:网站首页 定时器中断有什么作用 51单片机定时器工作方式1、2原理详解

51单片机定时器工作方式1、2原理详解

2024-07-04 01:34| 来源: 网络整理| 查看: 265

写在前面

1.本篇博文旨在帮助那些像我一样刚入门51单片机,如果你对定时器有一定了解,但是其中的的工作方式不能理解,那么这篇文章很适合你,如果你是大神的话…直接绕行吧……

2.我在学习的过程中由于知识上的不足很多的讲解看不懂,在翻找了许多资料真正理解之后,打算以一种简单易懂的方式进行解释,这是一份很 详尽基础 的讲解手册。

3.全文以定时器0为例,定时器1的用法与其相同。

4.由于是讲定时器实现原理,文章文字显得较多,不过都是很简单的文字,只要认真看都能看得懂。

知识填充

虽然看懂这篇博文不需要太多的知识储备,但是在这里还是做一个简单的知识普及,便于下文的讲解

4位二进制数可以和1位十六进制数相互转化,如二进制数1111转化为十六进制是0xf; 二进制转化11111111转化为十进制是255。51单片机的时钟周期由晶振决定,假定晶振频率是12M,那么它的时钟周期为1/12M,机器周期是12倍的时钟周期,即为12/12M,文章以12M晶振为例讲解。 方式一 工作原理

采用方式1时,计数位数时16位,由TH0作为高八位,TL0 作为低八位,组成16位加一计数器,在TR0 置1后单片机开始计时,每经过一个机器周期单片机输出一个脉冲使定时器加一,加到16位全为1时会溢出,使TF0 置1,利用此性质可以去执行相应的功能,TF0置1是一个信号。 若 TH0 和 TL0 的初值都为0(即整个定时器的值为0000000000000000),当16位全为1时,单片机一共输出了655361个脉冲,时间经过了65536*12/12M秒钟即为65.536ms。

初值的设定

那么问题来了,我们想要利用的时间都是1s,2s这种,而不是65.536ms,如果能让开始计时到TF0 置1这个时间变成50ms这种,就能够通过几次计数溢出达到计时1s钟的目的,这就到了初值的计算。 由之前的分析可知,单次计时最长为65.536ms,以单次定时50ms(0.05s)为例,需要20次可以定时1s钟。假设开始计时时16位定时器的初值为x,由于单片机定时固定到达65536溢出,那么(65536-x)*12/12M = 0.05,可计算得到x = 15536。化为16进制为0x3cb0。那么TH0 = 0x3c, TL0 = 0xb0;2

代码实现

定时1s钟的代码如下:

#include void main() { unsigned char cnt = 0; TMOD = 0x01; //设置定时器为工作方式1 TH0 = 0x3c; TL0 = 0xb0; //设置初值 TR0 = 1; //打开定时器开关,开始定时 while(1) { if(TF0 == 1) { TF0 = 0; TH0 = 0x3c; TL0 = 0xb0; //单次计时完成后,TH0 与TL0 的值均为11111111,所以需要对他们重新赋初值 cnt++; if(cnt == 20) { cnt = 0; //此处填写定时完成时要执行的功能 } } } } 方式二 工作原理

方式2是自动重装初值的8位计数方式,在本质上是与方式1一样的。在工作方式2中,TH0 只起到为TL0 重装初值的作用,并不参与计数。当TL0 计数到全为1时再有一个脉冲就会触发溢出,TL0 的溢出不仅使TF0 置1,TF0置1是一个信号 ,而且将TH0内容重新装入TL0 ,TH0 内容由代码设置,重装时值不变,然后进行新一轮的定时 ,这就是所谓方式2自动重装初值。

初值的设定

方式2的初值的计算方式和方式1相同,与方式1不同的是:由于方式2只有TL0 计数,最多可以记256个脉冲(8位从全0编为全1),单次定时最长也就只有0.256ms(方式1为65.536ms) 依然以定时1s钟为例,单次定时时间为0.2ms,设初值为x,(256-x)*12/12M = 0.2**10-3(0.2乘10的-3次方,由于格式问题只能打两个星号……),解得x = 56,化为十六进制为0x38,则TH0 和TL0 的初值均为0x38;

代码实现 #include void main() { unsigned int cnt = 0; TMOD = 0x02; TH0 = 0x38; TL0 = 0x38; TR0 = 1; if(TF0 == 1) { TF0 = 0; //TH0 = 0x38; //TL0 = 0x38; 这两处由于是自动重装初值,所以单次定时结束后不需要再赋值 cnt++; if(cnt == 5000) { cnt = 0;//单次定时0.2ms,5000次后定时1s //此处填写定时完成时要执行的功能 } } }

效果跟方式1相同3,经过笔者实验方式2更精准一些?咱也不知道,咱也不敢问

16位全为1的二进制数的值为216 = 65536 ↩︎

计算初值还有另外一个方法,就是以产生的脉冲次数(频率)为中心。 单片机时间频率为12M,机器频率为12M/12,即定时1s钟定时器计数的个数为12M/12(我在这里卡住很长时间,不太好理解),但是方式1单次计数个数最多为65536,远远达不到12M/12次。 计时1s单片机计数个数为12M/12.那计时50ms(0.05s)计数个数就应该是(12M/12)/ 20 = 50000,那初值就应该是15536。 ↩︎

不知道读者有没有注意到,在定义cnt变量时,方式1采用的是unsigned char cnt = 0; 而方式2采用的却是unsigned int cnt = 0; 这里涉及到了数据结构的问题,我会在其它博文里提到,这里只需简单理解为方式2中cnt的值过大,unsigned char型容不下就行了。 ↩︎



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有