找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6988|回复: 8
打印 上一主题 下一主题
收起左侧

51单片机的定时器

[复制链接]
跳转到指定楼层
楼主
ID:51090 发表于 2014-10-15 22:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以前学了好几次单片机,都是半途而废,这次要把基础打好点才行。
话说定时器还是很重要的。。。

对51单片机来说,其实定时器和计数器是一样的东西,下面把它们统称为定时器了。

51单片机有两个定时器,它们的核心是两个16位的加1计数器T0和T1,它们又被分为两个8位的计数器TH0,TL0,TH1,TL1。

当作为计数器使用时,计数脉冲来自外部引脚P3.4(T0)和P3.5(T1)。当该脚的输入信号发生由高到低的负跳变时,读数器TH、TL的值就加1。
定时器其实也是计数,只不过计数的脉冲来源的内部时钟。

程序是怎样知道定时器的时间到了呢?用中断啦。。。
定时器使用的是加法计数,而且只在计数溢出时才申请中断,因此,要实现自定义定时或计数,需要自己计算计数的起点,并将它们填到TH、TL中。
也就是说,如果我要记1000个时钟脉冲,我就将TH和TL的值设到距离最大值还差1000的位置。
假设计数的最大值是MAX(工作模式不同,这个值不同),则起点X的计算方法如下:
在计数方式下,X=MAX-计数值
在定时方式下,X=MAX-定时值/T,其中T为单片机的机器周期。如当机器周期=0.5us时,如果定时器工作于模式0,MAX = 2^13 * 0.5us = 4.096ms;如果工作于模式1,则最大定时值为MAX = 2 ^ 16 * 0.5us = 32.768ms。
在注意的是,在溢出后,除了模式2之外,程序都要重新装入初值!

使用定时器的步骤:
1. 指定工作模式,即TMOD寄存器;
2. 装入初始值,即对TH和TL赋值;
3. 启动定时器中断,通过赋值IE和优先级寄存器IP来实现,如果不使用中断,则忽略此步骤;
4. 启动定时器,即置位TR0或TR1。

模式0:
此模式为13位计数器,使用TH及TL中的低5位组成,此模式主要是为了向前兼容而设计的;在此模式下,当TL的低5位溢出时,向TH进位,当TH溢出时,计数器清零,同时TF置1,另外发出中断请求。
模式1:
此模式为16位计数器,使用TH和TL中的所有位,此模式方便计算初值,而模式0中要由TH和TL中的5位组成一个13位的数,麻烦。
模式2:
此模式是8位自动重新装入的计数器,其中TH作为计数初值寄存器,初值在程序中设置,程序初始化时,TL=TH,当TL溢出时,自动设置TL=TH,重新计数,TF标志置1,TH中的数不受影响。溢出信号还将送到串行通信系统,产生串口通讯的波特率。
模式3:
此模式是将TL和TH分成两个独立的计数器。T1没有模式3,只有T0有模式3。如果T0工作在方式3下,那么T1就只能工作在0、1、2方式下,因为TR1及TF1已经被T0借用。

可以通过TMOD和TCON两个寄存器控制它们。

TMOD
---------------------------------------------------------
                   用于T1          |         用于T0              
---------------------------------------------------------
GATE | C/T  |  M1  |  M0  |  GATE  |  C/T  |  M1  |  M0 |

TCON
------------------------------------------------------------
     用于定时/读数器        |          用于中断
------------------------------------------------------------
TF1  | TR1  | TF0  |  TR0  |  IE1  |  IT1  |  IE0  |  IT0  |
------------------------------------------------------------

TF是溢出的标志,TR是运行控制位,当置TR0=1时,定时器1即启动。
IT是外部中断触发方式选择位,0是低电平触发,1是负跳变触发。
IE是外部中断请求位。

定时/计数器有四种工作方式,TMOD中的M1和M0即为指定工作方式;
C/T决定是工作于定时还是计数方式;
GATE可控制定时器的启动,当GATE=0时,定时器仅由TR控制,当GATE=1时,除TR置1外,还必须等待外部脉冲输入端P3.4或P3.5有个高电平,定时器才能启动。若外部输入低电平,则定时器关闭,这样可由外部控制定时器的启停。

初值计算举例(以T0为例):
模式0, 6MHz的晶振,单片机的机器周期为12/6MHz=2us=0.002ms,如果要定时1ms,则有算式:1ms = (2^13-X)*0.002,解出X=7692=0x1E0C,转化为2进制为1111000001100,这里面低5位要放到TL中,即TL0=01100=0xC,其余放到TH中,即TH0=11110000=0xF0;
模式1, 12MHz的晶振,单片机的机器周期为12/12MHz=1us=0.001ms,如果要定时10ms,则有算式: 10ms=(2^16-X)*0.001,解出X=55536=0xD8F0,则TH0=0xD8,TL0=0xF0;
模式3, 6MHz的晶振,机器周期为2us=0.002ms,如果要定时200us,则有200=(2^8-X)*2,解出X = 156 = 0x9C, 则TL0 = 0x9C

程序举例:
T0工作于方式1,定时时间50ms,输出周期为1000ms的方波,晶振为11.0592MHz
机器周期为12/11.0592us,最大值为2^16=65536,X=0x4C00
程序如下:

#include "reg51.h"

sbit P0_1 = P0^1;
char i = 0;

void main()
{
    TMOD = 0x01; //T0方式1
    TL0  = 0x00; //TL0的初值
    TH0  = 0x4C; //TH0的初值
    ET0  = 1;    //打开定时器0的中断允许开关
    EA   = 1;    //开中断
    TF0  = 0;
    TR0  = 1;  
    while(1);
}

void Int_T0() interrupt 1 using 2
{
    TL0 = 0x00; //重新装入初值
    TH0 = 0x4C;
i++;
if (i==10)
    {
P0_1 = !P0_1;
i = 0;
}
}

下面这段中断的程序还须进一步研究,呵呵

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:67472 发表于 2014-10-16 11:50 来自手机 | 只看该作者
谢谢楼主
回复

使用道具 举报

板凳
ID:67422 发表于 2014-10-16 20:28 | 只看该作者
谢谢分享
回复

使用道具 举报

地板
ID:92169 发表于 2015-10-18 15:19 | 只看该作者
其实你的中断服务函数里面尽量不要那么多,只要留下i++;后面的可以写在while里面
回复

使用道具 举报

5#
ID:92169 发表于 2015-10-18 15:20 | 只看该作者
我也在学习
回复

使用道具 举报

6#
ID:92785 发表于 2015-10-18 18:24 | 只看该作者
谢谢楼主了!
回复

使用道具 举报

7#
ID:104763 发表于 2016-7-16 17:13 | 只看该作者
楼主,关于定时器复用的有没有
回复

使用道具 举报

8#
ID:120095 发表于 2016-7-17 15:42 | 只看该作者
对于初学者非常的重要
回复

使用道具 举报

9#
ID:226737 发表于 2019-11-19 19:23 | 只看该作者
谢谢你的分享!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表