精华内容
下载资源
问答
  • 本文主要讲了51单片机定时器工作原理及用法,希望对你的学习有所帮助。
  • (一)运算放大器的原理核心  如图2所示,运算放大器内由多级串接而成,有极大的开环放大倍数(Au﹥105),使得在有限较低电源电压下,“+”端(同相端)与“—”端(反相端)的电位近似...555集成定时器工作原理
  • 函数返回一个数值类型的ID唯一标示符,此ID可以用作 clearTimeout 的参数来取消定时器: var timeoutID = window.setTimeout(code, delay); IE0+ 还支持回调参数的传入: var timeoutID = window.setTimeout(func,...
  • 51定时器工作原理

    2015-01-15 22:17:22
    本资源为51单片机的程序,能够使用定时器进行时间控制,以达到一定教学目的
  • X281xDSP——CPU定时器工作原理分析

    千次阅读 2019-12-17 15:57:02
    CPU定时器工作原理分析

    CPU定时器工作原理分析

    在这里插入图片描述

    可以由图看出有几个寄存器:

    • 32位的定时器周期寄存器 PRDH:PRD
    • 32位的计数器寄存器TIMH:TIM
    • 16位的定时器分频器寄存器TDDRH:TDDR
    • 16位预定标计数器PSCH:PSC

    解释:

    1. XH:X形式表示寄存器的方式
    2. 因为X281x DSP的寄存器都是16位的,而CPU定时器是32位的,所以需要将2个16位的寄存器XH和X来表示32位的寄存器(XH表示高16位,X表示低16位)
    3. 通过图我们可以类比的看出它其实有点想两层for循环,即如下所示
    int i,j;
    for(i=0; i<100; i++)
    	for(j=0; j<100; j++)
    	{...}
    

    下图或许更能看出这种关系,上面框框为外循环,下面框框为内循环
    在这里插入图片描述
    在上面那个框中,在CPU定时器工作前,先根据需要计算好CPU定时器周期寄存器的值,然后给PRDH:PRD赋值,相当于for循环中的i=100。开始工作时将PRDH:PRD的值装载入TIMH:TIM,然后没来一个脉冲,减一,然后判断是否为0,则一直递减,当为0时输出一个中断信号。所以一个CPU定时器周期所经历的时间为:(PRDH:PRD+1)*TIMCLK
    而计数器存储器TIMH:TIM多久减1是由下面框中PSCH:PSC多久为0决定。同理可以得出TIMCLK = (TDDRH:TDDR+1)*SYSCLKOUT
    综上,假设系统时钟SYSCLKOUT的值为X(单位为MHz),那么CPU定时器一个周期所计量的时间为T = (PRDH:PRD+1)*(TDDRH:TDDR+1)/ (X*10^6)(单位为s)

    展开全文
  • javascript定时器工作原理

    千次阅读 2012-08-13 18:43:39
    在基础知识层面上,了解javascript定时器工作原理是很重要的。由于javascript是工作在一个单线程环境中,所以它们经常表现出一些违反直觉的行为。下面我们就从创建和操作三个定时器入手来分析定时器工作原理。 ...

    原文地址:http://ejohn.org/blog/how-javascript-timers-work/

    在基础知识层面上,了解javascript定时器的工作原理是很重要的。由于javascript是工作在一个单线程环境中,所以它们经常表现出一些违反直觉的行为。下面我们就从创建和操作三个定时器入手来分析定时器的工作原理。

    • var id=setTimeout(fn,delay); 初始化一个定时器,它将在delay延迟后触发fn函数。setTimeout方法返回一个用来标示定时器的唯一id,生成唯一id之后可以用这个id来取消所标示的定时器;
    • var id=setInterval(fn,delay);和setTimeout类似,不过setInterval会持续的每隔delay延迟后调用fn方法,直到它被取消;
    • clearInterval(id);clearTimeout(id);这两个方法都接收一个定时器id(前面两个函数的返回值)作为参数,用来取消相应的定时器。

    为了理解定时器内部是如何工作的,我们需要探索这样一个重要的概念:定时器的延迟是不能被保证的。因为在浏览器中javascript都是在一个单线程中执行的,异步事件(比如鼠标点击和定时器)只有在执行环境有空隙的时候才会执行。为了更好的理解,用如下的图示进行说明。

    上面的图示中有很多需要理解的信息,不过一旦完全理解了,你会对javascript异步执行有个清晰的认识。上面的图表是一维的,竖直方向是以毫秒为单位的时间,蓝色块代表javascript事件执行。比如,第一个javascript代码块大约执行了18ms,鼠标点击事件块大约执行了11ms等等。

    因为javascript同一时间只能执行一块代码(这是因为它的单线程特点决定的),每一个块的执行都会阻塞其它的异步事件,这就意味着当一个异步事件产生(比如一次鼠标点击,定时器触发,或者一个XMLHttpRequest完成)会被加入到一个事件队列中等待被执行(不同的浏览器处理事件队列的方式有很大的不同,但大概的过程是如此)。

    在上图示意中,在第一个javascript代码块执行中,初始化了两个定时器,分别为10ms的setTimeout和10ms的setInterval。当普通定时器触发的时候第一个javascript代码块还没执行完,所以回调函数会被加入到队列里等待被执行。

    另外,在第一个javascript代码块里有一次鼠标点击产生了,鼠标点击的回调函数也是一个异步事件(因为我们不知道用户点击时间什么时候会发生,所以也认为它是一个异步事件)同样也不会立即被执行,它也被放入队列中等待被执行。

    当第一个代码块执行完毕,浏览器会立即查询等待被执行的队列,在上图示意中,鼠标点击事件和定时器都在等待队列中,浏览器会按照产生的时间顺序选择鼠标点击事件来执行,定时器会继续等待直到下次空闲时间。

    注意到,当鼠标点击事件回调函数执行时,第一个间隔定时器(interval)回调函数被触发了,同普通定时器一样它的回调函数被放入队列中等待执行。然而,注意到当间隔定时器再次被触发时(当普通定时器回调函数正在被执行时),这次的间隔定时器回调函数会被丢弃而不会被放入队列中,因为,如果在一个非常大的javascript代码块执行过程中把每次间隔定时器触发的回调函数都放入队列的话,导致的结果是当这个大javascript代码块执行完毕时,有很多的回调函数会被无延迟的依次执行(这和我们当初需要间隔执行的目的相违背),所以,浏览器采用的作法是当等待队列中没有间隔定时器的回调函数时才会放入一个间隔定时器的回调函数。

    实际上我们可以看见,这正是导致当第三个间隔定时器被触发时有一个间隔定时器回调函数正在被执行。这给我展示了一个重要的事实,间隔定时器不关心当前是哪个事件正在执行,它会立即被放入到等待队列中,这就意味着这两个间隔定时器回调函数将会无间隔的执行。

    最后,在第二个间隔定时器回调函数执行完毕后,我们可以看见已经没有事件等待被执行了,这就意味着浏览器等待一个新的异步事件发生。我们注意到在第50ms的时候,间隔定时器再次被触发了,在当前事件,等待队列中没有事件,所以这次的回调函数立即执行了。

    让我们看一个能更加说明setTimeout和setInterval之间区别的例子。

    setTimeout(function(){
         /* Some long block of code... */
         setTimeout(arguments.callee, 10);
       }, 10);
       
      setInterval(function(){
         /* Some long block of code... */
       }, 10);

    第一眼看上去的时候你会觉得这两块代码的执行效果会是一样的,但是,它们是不同的。值得注意的是,setTimeout的执行时间永远是10ms(只可能多不可能少),而setInterval会尝试着每隔10ms执行一次,而会忽略上一次的执行时间。

    通过上述我们学习到很多,让我们总结一下:

    • javascript引擎是单线程,它会强制异步事件排队等待执行;
    • setTimeout和setInterval执行原理是不一样的;
    • 如果一个普通定时器被阻塞了,它会等待直到有合适的执行时间(等待时间有可能比它定义的延迟时间长);
    • 如果间隔定时器回调函数执行时间很长(长于定义的间隔时间)的话,间隔定时器有可能无间隔的持续执行。

    以上的这些知识都是非常重要的,了解javascript引擎是怎样工作的,尤其是当大量的异步事件发生时。了解这些是写出杰出代码的基础。

     

    展开全文
  • 定时器工作原理及其应用

    千次阅读 2020-05-21 20:38:29
    2 定时器/计数器的4种工作方式 2.1 方式0 2.2 方式1 2.3 方式2 2.4 方式3 1)工作方式3下的T0 2)T0工作在方式3下T1的各种工作方式 1 定时器T0和T1 T0和T1是2个独立的16bit向上计数定时器。T0共有4种不同的...

    【说明】本文学习自《单片机原理及应用(张毅刚)》。

    目录

    1 定时器T0和T1

    2 定时器/计数器的4种工作方式

    2.1 方式0

    2.2 方式1

    2.3 方式2

    2.4 方式3

    2.4.1 工作方式3下的T0

    2.4.2 T0工作在方式3下T1的各种工作方式

    3 定时器/计数器得编程和应用

     3.1 方式1的应用

    3.2  方式2的应用

    3.3  方式3的应用

    3.4 门控制位GATE的应用——测量脉冲宽度


     

    1 定时器T0和T1

         T0和T1是2个独立的16bit向上计数定时器。T0共有4种不同的操作模式:

    • 模式1:13位向上计数定时器;

    • 模式2:16位向上计数定时器;

    • 模式3:8位向上计数寄存器,并指定重装值;

    • 模式4:独立的2个8位向上计数定时器。

          T1有2种不同的操作模式:(只有T0的模式1和模式2)

    • 模式1:13位向上计数定时器;

    • 模式2:16位向上计数定时器。

        T0和T1分别支持ET0和ET1中断。

     

    2 定时器/计数器的4种工作方式

    2.1 方式0

            当M1、M0为00时,定时器/计数器被设置为工作方式0,这时定时器/计数器的等效框图如图2-1所示(以定时器/计数器T1为例,TMOD.5、TMOD.4 = 00)。

           定时器/计数器工作在方式0时,为13位的计数器,由TLX(X=0,1)的低5位和THX的高8位所构成。TLX低5位溢出则向THX进位,THX计数溢出则置位TCON中的溢出标志位TFX。

           图2-1中,​ 位控制的电子开关决定了定时器/计数器的工作模式:

           1)电子开关打在上面位置,T1位定时器工作模式,以系统时钟振荡器12分频后的信号作为计数信号。

           2)​ 电子开关打在下面位置,T1为计数器工作模式,计数脉冲为P3.5引脚上的外部输入脉冲,当引脚上发生负跳变时,计数器加1。

           GATE位的状态决定定时器/计数器运行控制取决于TRX一个条件还是TRX和​引脚这两个条件。

           1) GATE=0时,A点(见图2-2)电位恒为1,B点的电位仅取决于​状态。​,B点为高电平,控制断控制电子开关闭合。计数脉冲加到T1(或T0)引脚,允许T1(或T0)计数。​,B点为低电平,电子开关断开,禁止T1(或T0)计数。

             2)GATE=1时,B点电位由​的输入电平和​的状态这两个条件来确定。当​,且​时(X=0或1),B点才为1,控制端控制电子开关闭合,允许定时器/计数器计数,故这种情况下计数器是否计数是由TRX和​ 2个条件来控制的。

                                                    图2-1 定时器/计数器方式0逻辑结构框图

    2.2 方式1

            当M1、M0为01时,定时器/计数器工作于方式1,这时定时器/计数器的等效电路如图2-2所示(以定时器/计数器T1为例)。

            方式1和方式0的差别仅仅在于计数器的位数不同,方式1为16位的计数器,由THX作为高8位和TLX作为低8位构成(X-0,1),方式0则为13位计数器,有关控制状态位的含义(GATE、C/T、TFX、TRX)与方式0相同。

                                                    图2-2 定时器/计数器方式1逻辑结构框图

    2.3 方式2

    ​         方式0和方式1的最大特点是计数溢出后,计数器为全0。因此在循环定时或循环计数应用时就存在反复装入计数初值的问题。这不仅影响定时精度,而且也给程序设计带来麻烦。方式2就是针对此问题而设置的。

    ​        当M1、M0为10时,定时器/计数器处于工作方式2,这时定时器/计数器的等效框图如图6-4所示(以定时器T1为例,X=1)。

    方式0和方式1的最大特点是计数溢出后,计数器为全0。因此在循环定时或循环计数应用时就存在反复装入计数初值的问题。这不仅影响定时精度,而且也给程序设计带来麻烦。方式2就是针对此问题而设置的。

             当M1、M0为10时,定时器/计数器处于工作方式2,这时定时器/计数器的等效框图如图2-3所示(以定时器T1为例,X=1)。

     

                                                    图 2-3 定时器/计数器方式2逻辑结构框图

           定时器/计数器的方式2为自动恢复初值的(初值自动装入)8位定时器/计数器,TLX作为常数缓冲器,当TLX计数溢出时,在置1溢出标志TFX的同时,还自动的将THX中的初值送至TLX,使TLX从初值开始重新计数。定时器/计数器的方式2工作过程如图2-4若是(X=0,1)。

           这种工作方式可以省去用户软件中重装初值的程序,简化定时初值的计算方法,可以相当精确的确定定时时间。

     

                                                    图 2-4 方式2工作过程

     

    2.4 方式3

            方式3是为了增加1个附加的8位定时器/计数器而提供的,从而使MCS-51具有3个定时器/计数器。方式3只适用与定时器/计数器T0,定时器/计数器T1不能工作在方式3。T1处于方式3相当于TR1=0,停止计数(此时T1可用来作串口波特率产生器)。

    2.4.1 工作方式3下的T0

            当TMOD的低2位位11时,T0的工作方式被选为方式3,各引脚与T0的逻辑关系框图如图2-5所示。

                                                    图 2-5 各引脚与T0的逻辑关系

            定时器/计数器T0分为2个独立的8位计数器:TL0和TH0,TL0使用T0的状态控制位​、GATE、TR0、​,而TH0被固定为1个8位定时器(不能为外部计数模式),并使用定时器T1的状态控制位TR1和TF1,同时占用定时器T1的中断请求源TF1。

    2.4.2 T0工作在方式3下T1的各种工作方式

           一般情况下,当T1用作串行口的波特率发生器时,T0才工作在方式3。T0处于工作方式3时,T1可定为方式0、方式1和方式2,用来作为串行口的波特率发生器,或不需要中断的场合。

    (i)T1工作在方式0

            T1的控制字中M1、M0=00时,T1工作在方式0,工作示意图如图2-6所示。

                                                    图 2-6 T0工作在方式3时T1为方式0的工作示意图

    (ii)T1工作在方式1

            T1的控制字中M1、M0=01时,T1工作在方式1,工作示意图如图2-7所示。

                                                    图 2-7 T0工作在方式3时T1为方式1的工作示意图

    (iii) T1工作在方式2

            T1的控制字中M1、M0=10时,T1的工作方式为方式2,工作示意图如图2-8所示。

                                                    图 2-8 T0工作在方式3时T1为方式2的工作示意图

    (iv)T1工作在方式3

          T1的控制字中M1、M0=11时,T1停止计数。

          在T0为方式3时,T1运行的控制条件只有2个,即​和M1、M0。​选择时定时器模式还是计数器模式,M1、M0选择T1运行的工作方式。

    • 知识补充,在51单片机中,为什么T1不能工作于方式3

      • 51单片机只有T0、T1,没有T2(52才有)。如果工作在方式0、方式1、方式2的话,51单片机T0、T1都可以做波特率发生器(一般时方式2做波特率发生器)。但是T0可以工作在方式3,T1不能工作在方式3。这种情况下,只能用T1作为波特率发生器,T1的字源TF1、TR1给了T0,T0工作在方式3,可以当作定时器、计数器用。而如果用T0做波特率发生器,因为T1不能工作在方式3,方式3就没法用了。

     

    3 定时器/计数器得编程和应用

            定时器/计数器的4种工作方式中,方式0与方式1基本相同,只是计数器位数不同。方式0为13位计数器,方式1为16位计数器。由于方式0是为兼容MCS-48而设,且其计数初值计算复杂,所以在实际应用中,一般不用方式0,而采用方式1。

     3.1 方式1的应用

            例1 假设系统时钟频率采用6MHz,要在P1.0上输出1个周期为2ms的方波,如图3-1所示。

                                                                             图 3-1 

            方波的周期用定时器T0来确定,即在T0中设置1个初值,在初值的基础上进行计数,每隔1ms产生1次中断,CPU响应中断后,在中断服务程序中对P1.0引脚信号取反。T0中断入口地址为000BH。为此要做如下几步工作:

          (i)计算初值

                                                          T_{machine}=2\mu s = 2 \times 10 ^{-6}s机器周期 = 2\mu s = 2 \times 10 ^{-6}s

    设:需要装入T0的初值为X,则有:(2^{16} - X) \times 2 \times 10^{-6} = 1 \times 10^{-3}

                                      2^{16} - X = 500 ,       X=65036

           X化为十六进制,即X=FE0CH=1111111000001100B

    所以,T0的初值为:

           TH0=0FEH,    TL0=0CH

          (ii)初始化程序设计

             本例采用定时器中断方式工作。初始化程序包括定时器初始化和中断系统初始化,主要是对寄存器IP、IE、TCON、TMOD的相应位进行正确的设置,并将计数初值送入定时器中。

          (iii)程序设计

             中断服务程序除了完成产生要求的方波这一工作之外,还要注意将计数初值重新装入定时器中,为下一次产生中断作准备。主程序可以完成任何其它工作,一般情况下常常是键盘程序和显示程序。在本例中,由于没有这方面得要求,用一条转至自身的短跳指令来代替主程序。

             按上述要求设计的参考程序如下:

    		ORG  		0000H
    RESET:	AJMP   	  MAIN                                     ;转主程序
                    ORG         000BH                                  ;T0的中断入口
                    AJMP       1T0P                                     ;转T0中断处理程序1T0P
                    ORG         0100H 
    MAIN:   MOV        SP,# 60H                            ;设堆栈指针
                    MOV        TMOD,#01H                     ;设置T0为方式1
                    ACALL     PT0M0                                   ;调用子程序PT0M0
    HERE:   AJMP       HERE                                     ;自身跳转
    PT0M0: MOV       TL0,#0CH                           ;T0中断服务程序,T0重新置初值
                       MOV      TH0,#0FEH
                       SETB     TR0
                       SETB     EA
                       RET
    ITOP:   MOV		TL0,#0CH                               ;T0中断服务子程序,T0置初值
                  MOV        TH0,#0FEH
                  CPL          P1.0                                          ;P1.0的状态取反
                  RETI

              如果CPU不做其它工作,也可以采用查询的方式进行控制,程序要简单的多。

              查询方式的参考程序如下:

    		MOV 		TMOD,#01H                  ; 设置T0为方式1
    		SETB        TR0                                     ; 接通T0
    LOOP: 	MOV   		TH0, #0FEH                      ; T0置初值
                    MOV        TL0, #0CH
    LOOP1: JNB       TF0,  LOOP1                     ; 查询TF0标志是否为1,如为1,说明T0溢出,则往下执行
                     CLR       TR0                                      ; T0溢出,关闭T0
                     CPL       P1.0                                     ; P1.0的状态求反
                     SJMP    LOOP

            由上可见,程序虽然简单,但CPU必须得不断查询TF0标志,不能再做其它工作。

            例2 假设系统时钟为6MHz,编写定时器T0产生1s定时的程序。

            (i)定时器T0工作方式的确定

            因定时时间较长,采用哪一种工作方式合适呢?由前面介绍的定时器的个种工作方式的特性可以计算出:

            由上可见,可选方式1,每隔100ms中断1次,中断10次为1s。

            (ii)计算计数初值

            因为:(2^{16}-X)\times 2\times10^{-6}=10^{-1}

            所以:X=15536=3CB0H

            因此:TH0=3CH,TL0=B0H

            (iii)10次计数的实现

            对于中断10次计数,可使T0工作在计数方式,也可用循环程序得方法实现。本例采用循环程序法。

            (iv)程序设计

            参考程序如下:

    		ORG				0000H
    RESET:   LJMP             MAIN                        ;上电,转主程序入口MAIN
    		ORG                000BH                     ;T0的中断入口
    		LJMP              IT0P                         ;转T0中断处理程序IT0P
    		ORG                1000H  
    MAIN: 	  MOV                SP,#60H                 ;设堆栈指针
                     MOV                B,#0AH                ;设循环次数10次
                     MOV                TMOD,#01H      ;设T0工作在方式1
                     MOV                TL0, #B0H             ;给T0设初值
                     MOV                TH0,#3CH 
                     SETB               TR0                         ;启动T0
                     SETB               ET0                         ;允许T0中断
                     SETB               EA                           ;CPU开放中断
    HERE:    SJMP               HERE                    ;等待中断
    ITOP:     MOV                 TL0, #0B0H        ;T0中断服务子程序,重新给T0装入初值
                    MOV                 TH0, #3CH
                    DJNZ                B, LOOP
                    CLR                   TR0                       ;1s定时时间到,停止T0工作
    LOOP:   RETI                           

    3.2  方式2的应用

            方式2是1个可以自动重新装载初值的8为计数器/定时器。这种工作饭是可以省去用户程序中重新装入初值的指令,并可产生相当精确的定时时间。

             例3 当T0(P3.4)引脚上发生负跳变时,从P1.0引脚上输出1个周期为1ms的方波。如图3-2所示。(假设系统时钟为6MHz)

                                                                                    图 3-2

            (i)工作方式选择

            T0定义为方式1计数器模式,T0初值为0FFFFH,即外部计数输入端T0(P3.4)发生1次负跳变时,计数器T0加1且溢出,溢出标志TF0置1,向CPU发出中断请求。在进入T0中断程序后,把F0标志置1,说明T0引脚生已接收里负跳变信号。T1定义为方式2定时器模式。在T0引脚产生1次负跳变后,启动T1每500us产生1次中断,在中断服务程序中对P1.0引脚信号求反,使P1.0产生周期为1ms的方波。(T0和T1定时器进行合作)

            (ii)计算T1的初值

            设T1的初值为X:

            则

                                          (2^8-X) \times 2 \times 10^{-6} = 5 \times 10^{-4}       

                                         X = 2^8 -250 = 6 =06H

            (iii)程序设计

    		ORG				0000H
    RESET:  LJMP		  MAIN     					;复位入口转主程序
    		ORG				000BH
    		LJMP		   ITOP						 ;转T0中断服务程序
    		ORG				001BH
    		LJMP		   IT1P                       ;转T1中断服务程序
    		ORG    			0100H
    MAIN:   MOV             SP, #60H
    		ACALL		  PT0M2					 ;调用对T0,T1初始化子程序
    LOOP:   MOV             C, F0                      ;T0产生过中断了吗?产生过中断,则F0=1
                    JNC              LOOP                    ;T0没有产生过中断,则跳到LOOP,等待T0中断
                    SETB            TR1                       ;启动T1
                    SETB            ET1                       ;允许T1中断
    HERE:   AJMP           HERE
    PT0M2:MOV             TMOD, #26H      ;对T1,T0初始化,T1为方式2定时器,T0为方式1计数器
                   MOV             TL0, #0FFH         ;T0置初值
                   MOV             TH0, #0FFH
                   SETB           TR0                        ;启动T0
                   SETB           ET0                        ;允许T0中断
                   MOV            TL1, #06H            ;T1置初值
                   MOV            TH1, #06H
                   CLR              F0                           ;把T0已发生中断标志F0清0
                   SETB           EA                           ;CPU开放中断
                   RET
    IT0P:    CLR             TR0                         ;T0中断服务程序,停止T0计数
                   SETB          F0
                   RETI
    IT1P:     CPL            P1.0                         ;T1中断服务程序,P1.0位取反
                   RETI               

            在T1定时中断服务程序IT1P中,由于方式2是初值可以自动重新装载的,省去了T1中断服务程序中重新装入初值06H的指令。       

            例4 例用定时器T1的方式2对外部信号计数,要求每计满100个数,将P1.0引脚信号取反。  

            本例是方式2计数模式的应用举例。

            (i)选择工作方式         

             外部信号由T1(P3.5)引脚输入,每发生1次负跳变计数器加1,每输入100个脉冲,计数器产生溢出中断,在中断服务程序中将P1.0引脚信号取反1次。

              T1工作在方式2的方式控制字位TMOD=60H。不使用T0时,TMOD的低4位可任取,但不能使T0进入方式3,这里取全0。

            (ii)计算T1的初值

                                     X=2^8-100=156=9CH

               因此,TL1的初值为9CH,重装初置寄存器TH1=9CH。

            (iii)程序设计

    			ORG				0000H
    			LJMP			MAIN
                ORG				001BH				;T1中断服务程序入口
    			CPL				 P1.0					;P1.0位取反
                RETI
                ORG				0100H
    MAIN:MOV			TMOD, #60H		;设置T1为方式2计数
    			MOV            TL0, #9CH           ;T0置初值
    			MOV			   TH0, #9CH
    			SETB		   TR1						  ;启动T1
    HERE: AJMP         HERE						

    3.3  方式3的应用

            方式3对T0和T1大不相同。T0工作在方式3时,T1只能工作在方式0、1、2。T0工作在方式3时,TL0和TH0被分成2个独立的8位定时器/计数器。其中,TL0可作为8位的定时器/计数器;而TH0只能作为8位的定时器。

            一般情况下,当定时器T1用作串行口波特率发生器时,T0才设置为方式3。此时,常把定时器T1设置为方式2,用作波特率发生器。

            例5 假设某MCS-51应用系统的2个外部中断源已被占用,设置定时器T1工作在方式2,作波特率发生器用。现要求增加1个外部中断源,并控制P1.0引脚输出1个5kHz的方波。假设系统时钟为6MHz。

            (i)选择工作方式

            由第5章介绍的利用定时器作为外部中断源的思想,设置TL0工作在方式3计数模式,把T0引脚(P3.4)作附加的外部中断输入端,TL0的初值设为0FFH,当检测到T0引脚电平出现负跳变时,TL0溢出,申请中断,这相当于跳沿触发的外部中断源。TH0为8位方式3定时模式,定时控制P1.0输出5kHz的方波信号。如图3-3所示。

                                                                                图 3-3

            (ii)初值计算

           TL0的初值设为0FFH。

           5kHz方波的周期为200​us,因此TH0的定时时间为100​us。TH0初值​计算如下:

                                                                      (2^8-X) \times 2 \times 10^{-6} = 1 \times 10^{-4}

                                                                        X = 2^8 - 100 =156 = 9CH

            (iii)程序设计

            源程序如下:

    				ORG				0000H
    				LJMP		   MAIN
    				ORG				000BH				;T0中断入口
    				LJMP		   TL0INT			   ;跳T0中断服务程序
    				ORG             001BH               ;注意,在T1为方式3时,TH0占用了T1的中断
    				LJMP		   TH0INT             ;跳TH0中断服务程序
    				ORG             0100H
    MAIN:MOV             TMOD, #27H   ;T0为方式3计数,T1为方式2定时
    				MOV			   TL0, #0FFH      ;置TL0初值
    				MOV            TH0, #9CH       ;置TH0初值
    				MOV            TL1, #data1     ;data是根据波特率常数要求来定,见第7章
    				MOV            TH1, #datah    
    				MOV            TCON, #55H     ;允许T0中断
    				MOV            IE, #9FH             ;启动T1
    				                     .
    				                     .
    				                     .
    TL0INT:MOV           TL0, #0FFH        ;TH0中断服务程序,TH0重新装入初值
    				CPL             P1.0                     ;P1.0位取反输出
    				RETI

    3.4 门控制位GATE的应用——测量脉冲宽度

            下面以T1为例,来介绍门控制位GATE1的应用。门控制位GATE1可使定时器/计数器T1的启动计数受\overline{INT1}的控制,当GATE1 = 1,TR1为1时,只有\overline{INT1}引脚输入高电平时,T1才被允许计数,利用GATE1的这个功能,(对于GATE0也是一样,可使T0的启动计数受\overline{INT1}的控制),可测量的控制),可测量\overline{INT1}引脚(P3.3)上正脉冲的宽度(机器周期数),其方法如图3-4所示。

                                                                                图 3-4

            参考程序如下:

    		ORG				0000H
    RESET:  AJMP		  MAIN					;复位入口转主程序
    		ORG				0100H
    MAIN:	MOV			SP, #60H
    		MOV			   TMOD, #90H		;设控制字,T1为方式1定时
    		MOV			   TL1, #00H
    		MOV			   TH1, #00H
    LOOP:   JB				  P3.3, LOOP		  ;设控制字,T1为方式1定时
    		SETB           TR1                        ;如果$\overline{INT1}$为低,启动T1
    LOOP1: JNB            P3.3, LOOP1       ;等待$\overline{INT1}$升高
    LOOP2: JB               P3.3, LOO2          ;等待$\overline{INT1}$降低
    		CLR             TR1                        ;停止T1计数
    		MOV            A, TL1                   ;T1计数值送A
    		【将A中的T1计数值送显示缓冲区并转换成可显示的代码】
    LOOP3: LCALL       DIR				           ;调用显示子程序DIR(略)显示T1计数值
                    AJMP         LOOP3

             执行以上程序,使\overline{INT1}​引脚上出现的正脉冲宽度以机器周期数的形式显示在显示器上。

    展开全文
  • 说到 javascript 中的... Loop) 的角度来分析两者的工作原理和区别。 setTimeout() MDN对 setTimeout 的定义为: 在指定的延迟时间之后调用一个函数或执行一个代码片段。 语法 setTimeout 的语

    说到 javascript 中的定时器,我们肯定会想到 setTimeout() 和 setInterval() 这两个函数。本文将从 事件循环(Event Loop) 的角度来分析两者的工作原理和区别。

    setTimeout()

    MDN对 setTimeout 的定义为:

    在指定的延迟时间之后调用一个函数或执行一个代码片段。

    语法

    setTimeout 的语法非常简单,第一个参数为回调函数,第二个参数为延时的时间。函数返回一个数值类型的ID唯一标示符,此ID可以用作 clearTimeout 的参数来取消定时器:

    var timeoutID = window.setTimeout(code, delay);

    IE0+ 还支持回调参数的传入:

    var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

    setInterval()

    MDN 对 setInterval 的定义为:

    周期性地调用一个函数(function)或者执行一段代码。

    由于 setInterval 和 setTimeout 的用法一样,所以这里不再列出。

    对第二个参数(delay)的说明

    由于javascript 的事件循环机制,导致第二个参数并不代表延迟delay毫秒之后立即执行回调函数,而是尝试将回调函数加入到事件队列。实际上,setTimeout 和 setInterval 在这一点上处理又存在区别:

    • setTimeout:延时delay毫秒之后,啥也不管,直接将回调函数加入事件队列。

    • setInterval: 延时delay毫秒之后,先看看事件队列中是否存在还没有执行的回调函数(setInterval的回调函数),如果存在,就不要再往事件队列里加入回调函数了。

    所以,当我们的代码中存在耗时的任务时,定时器并不会表现的如我们所想的那样。

    通过一个例子来理解

    下面的代码,本来希望能够在 100ms 和 200ms 的时候(也就是刚好等待 100ms)调用回调函数:

    var timerStart1 = now();
    setTimeout(function () {
      console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);
    
      var timerStart2 = now();
      setTimeout(function () {
        console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
      }, 100);
    }, 100);
    // 输出:
    // 第一个setTimeout回调执行等待时间: 106
    // 第二个setTimeout回调执行等待时间: 107

    这样的结果看上去正是我们所想的那样,但是一旦我们在代码中加入了耗时的任务时候,结果就不像我们所期望的那样了:

    var timerStart1 = now();
    setTimeout(function () {
      console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);
    
      var timerStart2 = now();
      setTimeout(function () {
        console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
      }, 100);
    
      heavyTask();  // 耗时任务
    }, 100);
    
    var loopStart = now();
    heavyTask(); // 耗时任务
    console.log('heavyTask耗费时间:', now() - loopStart);
    
    function heavyTask() {
      var s = now();
      while(now() - s < 1000) {
      }
    }
    
    function now () {
      return new Date();
    }
    // 输出:
    // heavyTask耗费时间: 1015
    // 第一个setTimeout回调执行等待时间: 1018
    // 第二个setTimeout回调执行等待时间: 1000

    两个 setTimeout 的等待事件由于耗时任务的存在不再是 100ms 了!我们来描述一下事情的经过:

    1. 首先,第一个耗时任务(heavyTask())开始执行,它需要大约 1000ms 才能执行完毕。

    2. 从耗时任务开始执行,过了 100ms, 第一个 setTimeout 的回调函数期望执行,于是被加入到事件队列,但是此时前面的耗时任务还没执行完,所以它只能在队列中等待,直到耗时任务执行完毕它才开始执行,所以结果中我们开的看到的是: 第一个setTimeout回调执行等待时间: 1018

    3. 第一个 setTimeout 回调一执行,又开启了第二个 setTimeout, 这个定时器也是期望延时 100ms 之后能够执行它的回调函数。 但是,在第一个 setTimeout 又存在一个耗时任务,所有它的剧情跟第一个定时器一样,也等待了 1000ms 才开始执行。

    可以用下面的图来概括:

    再来看 setInterval 的一个例子:

    var intervalStart = now();
    setInterval(function () {
      console.log('interval距定义定时器的时间:', now() - loopStart);
    }, 100);
    
    var loopStart = now();
    heavyTask();
    console.log('heavyTask耗费时间:', now() - loopStart);
    
    function heavyTask() {
      var s = now();
      while(now() - s < 1000) {
      }
    }
    
    function now () {
      return new Date();
    }
    // 输出:
    // heavyTask耗费时间: 1013
    // interval距定义定时器的时间: 1016
    // interval距定义定时器的时间: 1123
    // interval距定义定时器的时间: 1224

    上面这段代码,我们期望每隔 100ms 就打出一条日志。相对于 setTimeout 的区别, setInterval 在准备把回调函数加入到事件队列的时候,会判断队列中是否还有未执行的回调,如果有的话,它就不会再往队列中添加回调函数。 不然,会出现多个回调同时执行的情况。

    可以用下面的图来概括:

    总结

    上面对javascript定时器执行原理进行了简要的分析,希望能够帮助我们更深入的理解javascript。文中有描述不当的地方可以在评论中指出。

    文章地址:http://blog.mcbird.cn/2015/09/18/javascript-timers/

    展开全文
  • JS 定时器工作原理

    千次阅读 2013-01-06 14:16:52
    在对JS本质理解的层面上,重要的是了解JS定时器是如何工作的。很多时候我们觉得定时器的执行不够直观, 那因为它们运行在单线程的环境里。我们先来仔细观察下面三个js的内置函数,然后我们再具体去使用它们: ...
  • Systick定时器工作原理 1. STM32 Systick定时器基础 2. STM32 Systick定时器相关寄存器库函数 1. STM32 Systick定时器基础 Systick定时器, 系统滴答定时器,24位的倒计数定时器,计数到0时,将从RELOAD寄存器中...
  • 电子设计教程53:555定时器工作原理与常见应用

    千次阅读 多人点赞 2020-07-27 22:18:54
    555定时器原理   有很多芯片厂家都生产了自己的555定时器产品。尽管产品的型号繁多,但最后三位都是“555”。一般来说,多数555定时器的功能与外部引脚的排列都完全相同。   以NE555为例,它包含3个5K电阻,...
  • 单片机:中断及定时器工作原理

    千次阅读 2019-01-15 09:22:03
     CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务);  待CPU将事件B处理完毕后,再回到原来事件A中断的地方继续处理事件A(中断返回),这一过程称为中断。  引起CPU中断的根源叫做中断源。  ...
  • 定时器是PLC中最常见的编程元件之一,其功能与继电器...在S7-200PLC中,按工作方式不同,可以将定时器分为三类,分别是通电延时型定时器,断电延时型定时器和保持型通电延时定时器。指令格式如下图1。图1:定时器指...
  • 定时器方式0工作原理

    2014-06-06 21:11:26
    定时器工作方式0工作原理Flash动画,形象、直观,方便理解。
  • 定时器原理

    千次阅读 2020-06-16 09:02:03
    1. 定时器介绍 程序里的定时器主要实现的功能是在未来的某个时间点执行相应的逻辑。在定时器模型中,一般有如下几个定义。 interval:间隔时间,即定时器需要在...接下来我们一起看下这些方法的具体实现原理。 ..
  • 51单片机定时器工作方式1、2原理详解

    万次阅读 多人点赞 2019-08-09 18:38:36
    51单片机方式1、2的详解:写在前面知识填充方式一工作原理初值的设定代码实现方式二工作原理初值的设定代码实现 写在前面 1.本篇博文旨在帮助那些像我一样刚入门51单片机,如果你对定时器有一定了解,但是其中的的...
  • 定时器原理

    2012-11-12 20:36:37
    介绍了定时器原理,有需要的朋友可以看看
  • 看门狗定时器工作原理 单片机等MCU用
  • JavaScript中的定时器大家基本在平时的开发中都遇见过吧,但是又有多少人去深入的理解其中的原理呢?下面我们就来分析一下定时器的实现原理。一、储备知识在我们在项目中一般会遇见过这样的两种定时器,第一种是...
  • JavaScript定时器工作原理(翻译)

    万次阅读 2018-08-08 16:35:43
    JavaScript定时器工作原理(翻译) 标签(空格分隔): JavaScript定时器 最近在看ajax原理的时候,看到了一篇国外的文章,讲解了JavaScript定时器工作原理,帮助我很好的理解了js的单线程工作模式。在这里...
  • 定时器/计数器的结构定时器/计数器...定时器/计数器的工作原理计数器输入的计数脉冲源系统的时钟振荡器输出脉冲经12分频后产生;T0或T1引脚输入的外部脉冲源。计数过程每来一个脉冲计数器加1,当加到计数器为全1(即FF...
  • 定时器是的重点中的重点,但不是难点,大家一定要完全理解并且熟练掌握定时器的应用。定时器的初步认识时钟周期:时钟周期t是时序中最小的时间单位具体计算的方法就是1/时钟源,如果大家用的晶振是11.0592m,那么...
  • 555定时器原理.zip

    2021-07-05 18:01:54
    555定时器原理
  • 现在我想让定时器在50ms之后产生中断,则只需要让计数器从TH0TL0初值开始计数,刚刚好50ms之后就溢出,这样便可以控制定时器产生中断。 那么, TH0TL0这个初值是多少呢? 求这个初值只需要 65536 - (50ms内的机器...
  • 这篇文章主要介绍了Python定时器线程池原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 定时器执行循环任务: 知识储备 Timer(interval, function, ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 68,727
精华内容 27,490
关键字:

五五定时器工作原理