定时/计数器的原理和应用

发布者:WhisperingWaves最新更新时间:2022-03-15 来源: eefocus关键字:定时  计数器  寄存器 手机看文章 扫描二维码
随时随地手机看文章

定时/计数器实质上是一个加1计数器,计数值是存在THX,TLX(X取0或1)这2个8位的寄存器里的.它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。


定时/计数器T0和T1的原理图:

除了用于存计数值的寄存器外,还有2个寄存器,一个是工作方式寄存器TMOD,作用是确定T0/T1的工作方式和功能。第二个是控制寄存器TCON,作用是控制T0/T1的启动和停止及设置溢出标志.  

 

工作方式寄存器TMOD的原理图:

每一位功能说明

然后这个工作方式一般都是选方式1的,因为这时候是16位定时/计数器,就是把THX和TLX的全部位也就是16位都用来存计数值了,这样子的话能存的计数值是65535。 ps:再计一个数就溢出变成0了

控制寄存器TCON的原理图:

位说明:

另外补充说明一下只有高4位是用于定时/计数器的,低4位是用于外部中断0和1的.

最后总结一下当我们使用于定时/计数器时需要做的事

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

2.计算初值,并将其写入THX,TLX

3.要用定时/计数器中断时,要对EA赋值,开放定时器中断.

4.使TR1/TR0置位,启动定时/计数器T0/T1来定时或计数.

接下来具体说说怎么计数初值,在这之前要先理解机器周期,因为TH0,TL0存的计数值是每一个机器周期加1的

机器周期也就是CPU完成一个基本操作所需要的时间。

时钟周期=1/单片机的时钟频率。

51单片机内部时钟频率是外部时钟的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。比如说你用的是12MHZ的晶振,那么单片机内部的时钟频率就是12/12MHZ,当你使用12MHZ的外部晶振的时候。机器周期=1/1M=1us。

而我们定时1ms的初值是多少呢,1ms/1us=1000。也就是要计数1000个数,初值=65536-1000(初值=溢出值-计数值)=64536.

计算出初值以后就把初值存到THX,TLX里,TLX=初值%256,THX=初值/256.可以把计数值理解为256进制的数,THX存的是高位,TLX存的是低位,低位每满256就清0,同时向高位(THX)进1.

下面贴一份应用了定时器的代码,目的是在点阵上轮流显示1到10.

#include "reg51.h"

#include            

 

typedef unsigned char u8;

typedef unsigned int u16;

 

 

sbit SRCLK=P3^6;                  

sbit RCLK=P3^5;

sbit SER=P3^4;

 

u8 code tabledu[]={

0x00,0x00,0x12,0x3E,0x02,0x00,0x00,0x01,0x00,0x00,0x26,0x2A,0x32,0x00,0x00,0x01,

0x00,0x00,0x2A,0x2A,0x3E,0x00,0x00,0x01,0x00,0x00,0x38,0x08,0x3E,0x00,0x00,0x01,

0x00,0x00,0x3A,0x2A,0x2E,0x00,0x00,0x01,0x00,0x00,0x3E,0x2A,0x2E,0x00,0x00,0x01,

0x00,0x00,0x20,0x20,0x3E,0x00,0x00,0x01,0x00,0x00,0x3E,0x2A,0x3E,0x00,0x00,0x01,

0x00,0x00,0x3A,0x2A,0x3E,0x00,0x00,0x01,0x00,0x3E,0x00,0x3E,0x22,0x3E,0x00,0x01

};//段选数据表,输入到74hc595芯片

 

u8 code tablewe[]={                                     

0x7f,0xbf,0xdf,0xef,

0xf7,0xfb,0xfd,0xfe

};//位选表,用于依次点亮1到8列

 

 

void Hc595(u8 dat)   //要注意输入到595的数据只能是u8型                     

{

u8 a;

SRCLK=0;

RCLK=0;

 

for(a=0;a<8;a++)

{

SER=dat>>7;

dat<<=1;

SRCLK=1;

_nop_();

_nop_();

  SRCLK=0;

}

RCLK=1;

_nop_();

_nop_();

RCLK=0;

}

 

void main()

{

    static u8 i=0;       

    static u8 b=0;

    static u16 cnt=0;

    TMOD=0x01;                           

    TH0=(65536-1000)/256;//计数值为1000,每1ms溢出一次

    TL0=(65536-1000)%256;

    TR0=1;

    while(1)

    {

        if(TF0==1)                          

        {

            TF0=0;                                  

            TH0=(65536-1000)/256;                      

            TL0=(65536-1000)%256;

            cnt++;

            if(cnt==1000)//当前的数字显示了1s后,显示下一个数字                                  

            {

                cnt=0;                                

                if(b==80)                            

                {

                    b=0;

                }

            }

            Hc595(0x00);                        

            switch(i)                               

            {

            case(0):P0=tablewe[i];Hc595(tabledu[b+i]);i++;break;

            case(1):P0=tablewe[i];Hc595(tabledu[b+i]);i++;break;

            case(2):P0=tablewe[i];Hc595(tabledu[b+i]);i++;break;

            case(3):P0=tablewe[i];Hc595(tabledu[b+i]);i++;break;

            case(4):P0=tablewe[i];Hc595(tabledu[b+i]);i++;break;

            case(5):P0=tablewe[i];Hc595(tabledu[b+i]);i++;break;

            case(6):P0=tablewe[i];Hc595(tabledu[b+i]);i++;break;

            case(7):P0=tablewe[i];Hc595(tabledu[b+i]);i=0;break;

        

            }

        }

 

    }

}

关键字:定时  计数器  寄存器 引用地址:定时/计数器的原理和应用

上一篇:51单片机实习-数码管动态显示4399(模块化编程)
下一篇:矩阵键盘的原理及应用

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved