基于单片机定时器/计数器的时钟设计以及计数设计

  • 第一部分 前言
  • 第二部分 定时器/计数器的原理
    • MCS-51定时器/计数器的结构
    • 定时器/计数器相关特殊功能寄存器
    • 定时器/计数器工作方式
  • 第三部分 定时器/计数器编程方法
  • 第四部分 定时器/计数器仿真设计
    • 设计案例一
      • 原理图
      • 动态仿真结果
      • 代码
    • 设计案例二
      • 原理图
      • 动态仿真结果
      • 代码

第一部分 前言

  本次单片机基础实验将会通过在Proteus软件中画原理图,然后Keil软件下编写源程序并编译形成可执行文件.hex,下载源程序,进行Protues和Keil的联合仿真运行,最终对单片机仿真有初步的认识。 通过本篇文章定时器/计数器T0、T1的工作方式选择和编程方法。学习Proteus了解定时器/计数器中断服务程序的设计方法


以下是本篇文章正文内容,所设计的案例可供参考


第二部分 定时器/计数器的原理

MCS-51定时器/计数器的结构

  MCS-51单片机根据不同型号,其片内定时器/计数器数目不同。8051单片机有两个16位定时器/计数器寄存器:Timer0(T0定时器)与Timer1(T1定时器1)。8052除这两个定时器/计数器外还增加了1个Timer2(T2定时器),而这3个都可设置为定时器或事件计数器。当其作为“定时器”功能时,它是对标准时钟计数,每个时钟周期寄存器自动增1。由于MCS-51单片机的一个机器周期由12个振荡器周期组成,计数速率是振荡器频率的1/12。作为“计数器”功能,寄存器在响应相应的外部输入引脚T0、T1或T2(在8052中)由1至0的转变而增1。不论是“定时器”还是外部事件“计数器”,其工作原理是一样的,即定时器/计数器电路中的内部计数器从某一预定值(此值是可编程的)开始计数,当累计到最大值时产生溢出,并同时会建立一个相应的溢出标志(即中断标志位)。除了“定时器”或“计数器”选择外,定时器0与定时器1有4种工作方式需要选择。在8052单片机中的定时器T2有3种操作方式:“捕获”、“自动重装入”与“波特率生成器”。下面主要以AT89C51单片机为例讲解定时器/计数器的基本结构。

图1 单片机的定时器/计数器结构框图

  AT89C51单片机片内定时器/计数器的结构如图1所示。定时器内部实质上是16位加法计数器,其控制电路受软件控制。当用作定时器时,对机器周期计数,每过一个机器周期,计数器加1。由于每个机器周期包含12个振荡信号周期,所以加1计数器的计数频率为振荡器信号频率的1/12。当用作计数器功能时,加1计数器的计数脉冲取自外部输入端T0(P3.4)和T1(P3.5),只要这些引脚上有从“1”到“0”的负跳变,计数器就加1。CPU在每个机器周期的S5P2时刻对外部输入状态进行采样,计数器加1的执行是在检测到跳变后的下一个机器周期的S3P1时刻。由于需要两个机器周期来识别一个从“1”到“0”的负跳变,所以最大计数频率为振荡信号频率的1/24。而外部时钟脉冲持续为0和为1的时间不能少于一个机器周期。
  两个可编程的16位定时器 /计数器T0 和 T1
  - T0 = TH0(高8位) + TL0(低8位)
  - T1 = TH1(高8位) + TL1(低8位)

定时器/计数器相关特殊功能寄存器

  • TMOD:控制定时器/计数器的工作方式
  • TCON:控制定时器/计数器的运行
  • IE、IP:定时器/计数器的中断控制

1. TMOD
  TMOD用来选择定时器/计数器的工作模式和工作方式,它的字节地址是89H,但该寄存器不能进行位寻址。

  • GATE=0,运行控制位 TR0/TR1(=1) 控制 T0/T1 启动;
  • GATE=1,INT0/1 (=1) 及运行控制位TR0/TR1(=1)控制T0/T1启动,可用于外部脉冲宽度测量
  • C/T=0,用作定时器(定时功能通过计数实现,计数脉冲来自内部系统时钟输入,一个机器周期产生一个计数脉冲);
  • C/T=1,用作计数器(对外部脉冲计数,外部输入脉冲发送负跳
    变时加1)

T0模式

M1 M0 功能
0 0 13 位定时器/ 计数器,TL1 低5 位 + TH1全8 位,最大值为8192
0 1 16 位定时器/ 计数器,TL1、TH1 全用,最大值65.536ms;
1 0 8 位自动重装载定时器,当溢出时将TH1 存放的值自动重装入TL1,最大值为256;
1 1 定时器/ 计数器1 此时无效(停止计数)

T1模式

M1 M0 功能
0 0 13 位定时器/ 计数器,TL1 低5 位 + TH1全8 位,最大值为8192
0 1 16 位定时器/ 计数器,TL1、TH1 全用,最大值65.536ms;
1 0 8 位自动重装载定时器,当溢出时将TH1 存放的值自动重装入TL1,最大值为256;
1 1 定时器0 为双8 位定时器/ 计数器,TL0 作为一个8 位定时器/ 计数器,通过标准定时器0 的控制位控制,TH0 仅作为一个8 位定时器,由定时器1 的控制位控制。

2.TCON
  TCON寄存器的字节地址为88H,可进行位寻址。高4位分别为定时器/计数器的启动控制和溢出中断标志,低4位与外部中断控制有关,

各标志位的功能:

1. IT0—选择外部中断请求0为跳沿触发方式还是电平触发方式:
IT0=0,为电平触发方式。
IT0=1,为跳沿触发方式。
  可由软件置“1”或清“0”。
2. IE0—外部中断请求0的中断请求标志位。
IE0=0,无中断请求。
IE0=1,外部中断0有中断请求。
当CPU响应该中断,转向中断服务程序时,由硬件清“0”IE0
**3. IT1—外部中断请求1为跳沿触发方式还是电平触发方式,意义与IT0类似。

  1. IE1—外部中断请求1的中断请求标志位,意义与IE0类似。
  2. TF0 —T0溢出中断请求标志位。**
      T0计数后,当最高位产生溢出时,由硬件置“1”TF0,向CPU申请中断,CPU响应TF0中断时,清“0”TF0,TF0也可由软件清0。

6. TF1—T1的溢出中断请求标志位,功能和TF0类似。
   TR1、TR0 2个位与中断无关,仅与定时器/计数器T1和T0有关。

3.IE
  中断允许寄存器:CPU对中断源的开放或屏蔽,由片内的中断允许寄存器IE控制。字节地址为A8H,可位寻址。格式如下:

IE中各位的功能如下:

1. EA:中断允许总控制位
EA=0:CPU屏蔽所有的中断请求(CPU关中断) ;
EA=1:CPU开放所有中断(CPU开中断) 。
五个中断源的中断请求是否允许,还要由IE中对应的5个中断请求允许控制位的状态来决定。

2. ES:串行口中断允许位
ES=0:禁止串行口中断;
ES=1:允许串行口中断。

3. ET1:定时器/计数器T1的溢出中断允许位
ET1=0:禁止T1溢出中断;
ET1=1:允许T1溢出中断。

4. EX1:外部中断1中断允许位
EX1=0:禁止外部中断1中断;
EX1=1:允许外部中断1中断。

5. ET0:定时器/计数器T0的溢出中断允许位
ET0=0:禁止T0溢出中断;
ET0=1:允许T0溢出中断。

6. EX0:外部中断0中断允许位。
EX0=0:禁止外部中断0中断;
EX0=1:允许外部中断0中断。

MCS-51复位后,IE清0,所有中断请求被禁止。若使某一个中断源被允许中断,除了IE相应的位被置“1” ,还必须使EA位=1。改变IE的内容,可由位操作指令或字节操作指令来实现。


定时器/计数器工作方式

  在MCS-51系列单片机中,定时器/计数器(T0、T1)具有多种工作方式,当选择工作方式不同,定时/计数器的使用方法差别很大。MCS-51单片机片内的定时器/计数器可以通过对特殊功能寄存器TMOD中的控制位 的设置来选择定时器方式或计数器方式;通过对M1 M0两位的设置来选择定时器/计数器的四种工作方式,下面具体讲解定时器/计数器的工作方式。

1. 工作方式0

  定时器/计数器0、1在工作方式0时的电路逻辑结构见图9-2。工作方式0(M1 M0 = 0 0)是13位计数结构的工作方式,其计数器由TH的全部8位和TL的低5位构成,TL的高3位不使用。当 =0时,定时器/计数器0、1处于定时工作方式,多路开关接通振荡脉冲的12分频输出,13位计数器依次进行计数。当 =1时,定时器/计数器0、1处于计数工作方式,多路开关接通计数引脚(T0),外部计数脉冲由脚T0输入。当计数脉冲发生负跳变时,计数器加1。
  当TL的低5位溢出时,都会向TH进位,而全部13位计数器溢出时,则会向计数器溢出标志位TF0进位。同时,GATA位的状态决定定时器运行控制取决于TR0一个条件还是TR0和/INT0引脚这两个条件。当GATA=1时,由于GATA信号封锁了与门,使引脚/INT0信号无效。而这时候如果TR0=1,则接通模拟开关,使计数器进行加法计数,即定时/计数器工作。而TR0=0,则断开模拟开关,停止计数,定时器/计数器不能工作。当GATA=0时,与门的输出端由TR0和INT0电平的状态确定,此时如果TR0=1,INT0=1与门输出为1,允许定时器/计数器计数,在这种情况下,运行控制由TR0和INT0两个条件共同控制,TR0是确定定时/计数器的运行控制位,由软件置位或清“0”。


  在工作方式0下,计数器的计数值X范围为1~8192(2131)。由于MCS-51单片机的T0和T1采用加计数,因此TH0(TH1),TL0(TL1)的初值N=8192-X。如当计数值X=1000,则计数初值N=7192=1C18H,那么TH0(TH1),TL0(TL1)的值分别为0E0H和18H。由于TL0(TL1)为低5为有效,所以该计数初值N不能简单地分成高8位和低8位赋值给TH0(TH1),TL0(TL1)。当计数初值N=7192=1C18H,其二进制编码如下

1C18H=0001 1100 0001 1000B

  再将16位的二进制编码去除最高的3位,保留后面13位,并取低5位写入到TL0(TL1),高8位写入到TH0(TH1),具体操作如下

1C18H=0001 1100 0001 1000 = 1110 0000 11000B

  其中,11000B是TL0(TL1)对应的低5位,其16进制编码为18H,而1110 0000这8位为TH0(TH1)的内容,其16进制编码为0E0H。
  当定时器/计数器工作于方式0且确定了定时时间T1后,其计数初值N的计算公式为

N=8192-(T1×fosc/12)

  式中,fosc为系统时钟振荡频率。
  假设单片机的晶振选为12MHz,需要用T0进行2ms定时控制,则T0的初值N计算为

N=8192-T1×fosc/12=8192-2×10-3×12×106/12=6192=1830H=0001 1000 0011 0000B

  则对应的13位二进制编码为1100 0001 1 0000则TH0=0C1H,TL0=10H

2. 工作方式1

定时器/计数器0、1工作于方式1时,其电路逻辑结构如图所示。

  工作方式1(M1 M0=0 1)是16位计数结构的工作方式。方式0和方式1的区别仅在于计数器的位数不同,方式0为13位,而方式1则为16位,由TH0作为高8位,TL0为低8位,有关控制状态字(GATA、TF0、TR0)和方式0相同。
  在工作方式1下,计数器的计数值X范围是:1~65536
  当定时器/计数器工作于方式1且确定了定时时间T1后,其计数初值N的计算公式为:

N=65536-(T1×fosc/12)

  则写入到8位寄存器TH0(TH1),TL0(TL1)值分别为
  TH0(TH1)=N/256
  TL0(TL1)=N%256

3. 工作方式2

  当M1 M0=1 0时,定时器/计数器0、1处于工作方式2,此时其电路逻辑结构如图9-4所示。以定时/计数器0为例,定时/计数器1与之完全一致。

4. 工作方式3

  当M1 M0 =1 1时,定时器/计数器工作于方式3下。方式3只适用于定时器T0,若将T1置为方式3,则它将停止计数,其效果相当于置TR1=0,即关闭定时器T1。当T0工作在方式3时,TH0和TL0被分成两个相互独立的8位计数器,其电路逻辑结构如图所示。

  在工作方式3模式下,TL0既可以作为计数器使用,也可以作为定时器使用,定时器/计数器0的各控制位和引脚信号全归它使用。其功能和操作与方式0或方式1完全相同。但TH0的功能受到限制,只能作为简单的定时器使用,而且由于定时器/计数器0的控制位已被TL0占用,因此只能借用定时器/计数器1的控制位TR1和TF1,也就是以计数溢出去置位TF1,TR1则负责控制TH0定时器的启动和停止。由于TL0既能作定时器也能作计数器使用,而TH0只能作定时器使用而不能作计数器使用,因此在方式3模式下,定时/计数器0可以构成两个定时器或者一个定时器和一个计数器。

第三部分 定时器/计数器编程方法

定时器的初始化编程包括:

  1. 设置定时器工作模式(设置TMOD);
  2. 设置定时器计数初值(设置THx/TLx);
  3. 允许定时器中断(IE);
  4. 启动定时器(TCON)。

例如:

  • 设置定时器工作模式(TMOD不能位寻址)
    TMOD = 0x01; T0工作在模式 1下,16位定时器
  • 设置定时器计数初值
    计算初值公式 (T0定时模式2,8):
    TH0=(28- 计数值) ; \ 8192 1s, 1us=110^6 ,50000,50ms
    TL0=(28 -计数值);
    计数值=定时时间/ 机器周期; 如果时钟频率fosc=12MHZ,则机
    器周期=12
    时钟周期=12*1/fosc=1us。 6mhz,
    PS:如果要求定时器按某固定时间间隔不断触发,需要在中断服务程
    序中再次设置定时器计数初值(模式2除外),否则,中断服务程序以该模
    式下的最大定时值工作。
  • 允许定时器中断(中断号)
    EA=1;ET0=1
  • 启动定时器
    定时器T0:TCON=0x10 或者 TR0=1

第四部分 定时器/计数器仿真设计

设计案例一

  基于上述原理可以设计一个60s计时的秒表,完成秒表电路的设计与编程调试。

原理图


  定时器T0或T1实现秒表的计时功能,工作模式不限,计时60s后自动从0开始重新计时, INT0中断方式实现秒表的启动和暂停计时; INT1中断方式实现秒表的计时重置。

动态仿真结果


代码

Keil代码如下:

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit duan = P2^0;
sbit wei = P2^1;
sbit int0=P3^2;
sbit int1=P3^3;
uchar code LED_D[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar code LED_W[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar count=0;
uchar Time=0;void Delay(uint x);//延迟函数
void Display2(uchar W1, Time);//显示函数
void QP();//清屏函数
//主函数
void main()
{QP(); TMOD=0x01;//设置定时器工作方式  TH0=(65536-50000)/256;//计算初值,高8位TL0=(65536-50000)%256;//计算初值,第8位ET0=1;EA=1;  //开总中断 while(1){            if(int0==0){Delay(100);if(int0==0){TR0=!TR0;while(int0==0);}}if(int1==0){Delay(100);if(int1==0){Time=0;}}Display2(6,Time);    }}
void LED_Flash() interrupt 1//中断函数
{EA=0;//关总中断TH0=(65536-50000)/256;//重装初值 TL0=(65536-50000)%256;//重装初值if(++count==20)     //开始计数{count=0;Time++;if(Time==61)Time=0;  }EA=1;
}
void Int0() interrupt 0
{if(int0==0){Delay(100);if(int0==0){TR0=!TR0;while(int0==0);}}
}
void Int1() interrupt 2//中断函数
{ EA=1;ET0=1;if(int1==0){Delay(10);if(int1==0){Time=0;}}
}
void Display2(uchar W1, Time)//显示函数
{uchar shi,ge;shi = Time/10;ge = Time%10;P0 = LED_D[shi];duan = 1;   duan = 0;P0 = LED_W[W1];wei = 1; wei = 0;Delay(3);QP(); P0 = LED_D[ge];duan = 1;duan = 0; P0 = LED_W[W1+1];wei = 1;wei = 0; Delay(3); QP();
}
void QP()
{P0=0x00;duan = 1; duan = 0; wei = 1; wei = 0;
}
void Delay(uint x)   //延时
{uchar t;while(x--) for(t=0;t<110;t++);
}

设计案例二

利用T0、T1计数器功能,实现按键计数,计数值分别在2个4位数码管上显示。

原理图

  • 利用定时器T0工作模式2,中断方式,计数初值为0,数码管显示3位数
  • T1工作模式不限,非中断方式,计数初值为256,数码管显示3位数
  • INT0中断方式实现T0、T1计数清零

动态仿真结果


  通过不同的按键来实现对应的计数功能,利用定时器的计数功能可以使得单片机得到快速响应。

代码

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit duan = P2^0;
sbit wei = P2^1;
uchar code LED_D[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar code LED_W[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uint count1,count2;
void Delay(uint x);
void Display2(uchar W1,uint count);
void QP();
void main()
{QP(); EA=1; //开总中断TMOD=0x46; //设置定时器工作方式   TH0=TL0=0; //设定初值TH1=1;TL1=0;ET0=1;EX0=1;IT0=1;TR0=1;TR1=1;while(1){ if(TF1==1) TF1=0;count1 = TL0;count2 = TH1*256+TL1;Display2(1,count1);          Display2(5,count2);       }
}
void Flash() interrupt 1
{EA=0;TL1=0;EA=1;
}
void Clear() interrupt 0
{TL0=0; TL1=0;
}
void Display2(uchar W1, uint count)
{uchar  bai,shi,ge;bai = count%1000/100;shi = count%100/10;ge = count%10;P0 = LED_D[bai];duan = 1;   duan = 0;P0 = LED_W[W1];wei = 1; wei = 0;Delay(3);QP(); P0 = LED_D[shi];duan = 1;duan = 0; P0 = LED_W[W1+1];wei = 1;wei = 0;Delay(3); QP();P0 = LED_D[ge];duan = 1;duan = 0;P0 = LED_W[W1+2];wei = 1;wei = 0;Delay(3); QP();
}
void QP()
{P0=0x00;duan = 1; duan = 0; wei = 1; wei = 0;
}
void Delay(uint x)
{uchar t;while(x--) for(t=0;t<110;t++);
}

  以上就是本次定时器/计数器的全部内容,希望通过本次的讲解能够加深大家对于定时器/计数器以及中断的理解。文章的内容可能存在部分不足之处,如有错误,请在评论区指出,谢谢。如果大家觉得文章有用,麻烦点赞关注,感谢支持,后续将会推出单片机的进阶设计文章。

基于单片机定时器/计数器的时钟设计及计数设计相关推荐

  1. keil c语言 1602时钟代码,基于单片机的LCD1602电子时钟设计.doc

    基于单片机的LCD1602电子时钟设计 设计任务和目的 1.1.设计任务 (1):用单片机设计基于LCD1602的电子时钟,显示时间和日期: (2):误差精度控制在1s/天: (3):具有时间和日期的 ...

  2. 单片机定时器_单片机定时器/计数器基本原理

    目前常用的单片机中往往都配备了定时器/计数器.在AT89S52芯片内包含有三个16位的定时器/计数器:T0.T1和T2,其核心是加1计数器.我们主要要求掌握T0和T1的结构和功能.学习中要注意从电路结 ...

  3. 51单片机——定时器/计数器

    目录 1.概述 2.定时器/计数器 2.1 定时功能 2.2.1 定时功能的用法 2.1.2 任意定时方法 2.2 计数功能 2.2.1 计数功能的用法 2.2.2 任意计数方法 2.3 定时器/计数 ...

  4. C51单片机————定时器计数器

    51单片机定时器/计数器 定时(定时控制.测量.延时...)和计数(对外部事件统计数目). Created with Raphaël 2.1.2张三张三李四李四嘿,四哥, 定时器和计数器有哪几种实现哦 ...

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

    51单片机定时器/计数器(中断系统:定时器中断) 实现功能 通过定时器终端控制LED灯 D1 间隔一秒闪烁 单片机型号:STC89C52 定时器介绍 1.51单片机定时器原理 定时器实质上就是一个加1 ...

  6. 单片机 定时器/计数器

    单片机 定时器/计数器 一.简述     MCS-51系列单片机内部有两个16位定时器/计数器,即定时器T0和定时器T1.它们都具有定时和计数功能,可用于定时或延时控制,对外部事件进行检测.计数等. ...

  7. 定时器计数器实验C语言程序,单片机定时器计数器实验报告.docx

    单片机定时器计数器实验报告 单片机定时器计数器实验报告 篇一:单片机计数器实验报告 计数器实验报告 ㈠ 实验目的 1. 学习单片机内部定时/计数器的使用和编程方法: 2. 进一步掌握中断处理程序的编程 ...

  8. 【毕设狗】【单片机毕业设计】基于单片机的室内空气质量检测系统的设计

    软件安装: Keil:点击下载 Proteus:点击下载 AD:点击下载 Visio:点击下载 设计简介: 本设计是基于单片机的室内空气质量检测系统的设计,主要实现以下功能: 实现通过甲烷气体传感器检 ...

  9. 基于单片机的LED自适应调光系统的设计与实现 - 调光电路图

    电路图简介: 本文主要介绍了基于单片机的LED自适应调光系统的设计与实现.LED自适应调光系统是一种典型的绿色照明方式,与传统照明相比,具有智能.节能.环保.寿命长.安全可靠等这些优点,这是代表着照明 ...

最新文章

  1. 万人马拉松赛事,人脸识别系统如何快速、准确完成校验?
  2. 限定项目的 Node.js 版本
  3. 【跃迁之路】【552天】程序员高效学习方法论探索系列(实验阶段309-2018.08.11)...
  4. double free or corruption (fasttop)
  5. Matlab 二维线画图函数 plot 基本用法
  6. 云上创新 | 阿里云边缘云场景化商业实践
  7. 剖析Picasso加载压缩本地图片流程(解决Android 5.0部分机型无法加载本地图片的问题)
  8. springsecurity-sample中hsqldb的使用注意
  9. 程序猿都在关注的6个优质公众号
  10. OA项目10:部门管理的三个细节问题的解决及处理懒加载问题
  11. php curl_error源码,PHP curl_error函数
  12. 如何整一个厉害的产品slogan?
  13. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】
  14. WSUS补丁服务器部署详细 利用WSUS部署更新程序
  15. 关于UIImageView的显示问题
  16. Win11未安装Defender怎么办?解决Win11未安装Defender的方法
  17. pycharm去除波浪线的方法
  18. mysql官网社区免费版下载方法
  19. revit二次开发概念_Revit二次开发那些事儿
  20. 第六节NoSQL+时序数据库+RabbitMQ安装

热门文章

  1. 人体红外测温仪PCBA方案
  2. 剥开O2O这个伪命题
  3. matlab中好看的色调,选色,套色,调出一个好看的色调就是这么简单!
  4. XP系统连接不到sql 服务器,Window XP 环境下SQL Server2008局域网连接配置
  5. python投掷骰子实验报告_用Python来掷个色子玩~
  6. Win10耳机有声音麦不能说话怎么办?麦克风说话别人听不到解决方法
  7. fatal error C1061: compiler limit : blocks nested too deeply 原因以及解决办法
  8. Android实现app内的语言切换功能
  9. 元数据管理、治理、系统、建设方案、范例等
  10. <快捷键>Pycharm快速创建推导公式