打印
[经验分享]

51单片机定时器/计数器(定时器中断)

[复制链接]
21|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
磨砂|  楼主 | 2025-1-11 19:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
定时器介绍
1、51单片机定时器原理



定时器实质上就是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到定数器满时,再输入一个脉冲就使定时器回零,且定时器的溢出使相应的中断标志位置1,向CPU发出中断请求。如果定时器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。

定时器由高8位和低8位两个寄存器 TH0/TH1和TL0/TH1 组成。

51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD 是定时器的工作方式寄存器,确定工作方式和功能;TCON 是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。

2、工作方式寄存器 TMOD



51单片机有两个定时器,所以 TMOD 里面有两组。

GATE:是门控位, 一般默认GATE=0。

C/T :定时/计数模式选择位。低电平为定时模式;高电平为计数模式。

M1 M0:工作方式设置位。定时/计数器有四种工作方式。



方式0
13位定时/计数器,由 TL0 的低5位(高3位未用)和 TH0 的8位组成。如果TL0 的低5位溢出会向 TH0 进位,TH0 溢出时,置位 TCON 中的 TF0 标志,向CPU发出中断请求。**(这里不自动重装载,所以在中断处理函数中需要重新赋值 TH0 和 TL0) **



方式1
16位定时/计数器,由 TL0 作为低8位,TH0 作为高8位,组成了16位加1计数器 。(这里不自动重装载,所以在中断处理函数中需要重新赋值TH0和TL0)



方式2
自动重装初值的8位计数方式。(这里自动重装载,所以在中断处理函数中不需要重新赋值TH0和TL0)



方式3



3、控制寄存器 TCON



TF1:T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。

TR1:T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。

TF0:T0溢出中断请求标志位,其功能与TF1类同。

TR0:T0运行控制位,其功能与TR1类同。

4、计数器初值计算
初值的计算与外部晶振有关,一般是12MHZ或者11.056MHZ。
计数器是每次到溢出了才会中断,所以要找到初值,保证初值到溢出的时间为你想定时的时间,即:溢出数字 - 初值 = 定时时间
如果用定时器 T0,并采用方式1(16位定时/计数器),定时1ms的初值是多少?
因为方式一16位定时器,所以最多可以计数到 216-1=65525;1ms/1us=1000,所以初值=65535-1000+1=64536=FC18
可以这样赋值:
TH0=0xFC
TL0=0x18;
如果定时的时间非常大,寄存器无法存储下时,例如1s,可以用一个循环,定时1ms,将定时的1ms循环1000遍就是1s了

硬件原理



中断系统就是当系统在进行一项工作时,需要终止这项工作,转而去执行另一项工作,当执行完成后再接着执行第一项工作。

如上图,STC89C52有两个外部中断(INT0、INT1)、两个定时器中断(T0、T1)、一个串口中断(RX/TX)

以定时器中断 T0 讲解,T1 同理。

定时器中断 T0 中的 ET0 是 T0 的中断允许,将其赋值为 1 ,则可以开启 T0 的中断允许。EA 是总中断 ,只有将其打开才能允许终端。IP 是控制终端的优先级的,这里不做介绍,使用默认优先级。T0 的管脚连在 P3^4 ,T1 的管脚连接在 P3^5 。

中断标号为:

INT0 0
T0 1
INT1 2
T1 3
RX/TX 4
软件编写
定时器中断配置:

对 TMOD 赋值,以确定 T0 和 T1 的工作方式

根据所要定时的时间计算初值,并将其写入 TH0、TL0 或 TH1、TL1

如果使用中断,则对 EA 赋值,开放定时器中断

使 TR0 或 TR1 置位,启动定时/计数器定时或计数

首先将定时器中断配置好,再写出定时器中断需要执行的函数。在写定时器中断函数时需要用到关键字 interrupt ,再在后面写上中断标号。例如定时器中断 T0 的中断函数这样写 void Time0() interrupt 1 ,千万不要将中断标号写错了。

#include <REGX52.H>

sbit LED=P2^0;

void Time0_Init()
{
        TMOD|=0x01;    //选择为定时器0模式,工作方式1
        TH0=0xFC;      //给定时器赋初值,定时1ms
        TL0=0x18;      
        ET0=1;         //打开定时器0中断允许
        EA=1;          //打开总中断
        TR0=1;         //打开定时器
}

void Time0() interrupt 1   //定时器0中断函数
{
        static unsigned int i; //定义静态变量 i 如果不是静态变量会出现每次调用函数重复赋值为0;
       
        TH0=0xFC;    //再次给定时器赋初值
        TL0=0x18;    //因为1ms时间到了,寄存器中的数被置0了,所以要重新赋值 1ms
       
        i++;
        if(i==1000)   //将定时1ms循环1000遍,就是1s
        {
                i=0;
                LED=!LED;
        }
}

void main()
{
        Time0_Init();     //定时器0中断配置
        while(1)
        {
               
        }
}

————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/zhouhaoNB_/article/details/127287647

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

96

主题

4179

帖子

2

粉丝