您的位置 首页 知识

单片机学习之十四:定时器使用(形式1)

一、实验现象:开机后程序作如下的灯光变换:第一次led0、led2亮;第二次led1、led3亮;第三次led4、led6亮;第四次led5、led7亮;第五次le…

一、实验现象:

开机后程序作如下的灯火改换:第一次led0、led2亮;第2次led1、led3亮;第三次led4、led6亮;第四次led5、led7亮;第五次led0、led2、led4、led6亮;第六次led1、led3、led5、led7亮;第七次8个二极管全亮;第八次8个二极管全灭。然后重头开端循环。每次状况转化间隔时刻是50ms。

二、实验意图

把握内部守时/计数器的作守时功用(形式1)的使用

三、实验任务剖析:

看到这个实验标题,咱们或许会说,这个实验难度不大,咱们只需把这几种灯火对应的输出存到一个表里边,然后查表就能够啦,灯火转化之间调用50ms的延时程序即可。 这样的思路当然能够,可是,假设这样作,咱们就没有必要写这个实验啦。今日,咱们要老瓶装新酒,看看这个50ms的守时时刻除了用延时程序完结,还有没有其他办法。曾经的守时,咱们常常选用延时程序来完结。其实这种办法不是很完美,因为程序的指令中还包括其他的判别指令,所以延时程序作守时不是十分准确。因为日常的电子体系常常需求守时和计数的功用,所以MCS-51单片机内部就自带了两个16位的寄存器,用来作守时/计数器,咱们给它们起了姓名,T0、T1。(咱们的AT89S52里边有3个守时器,一般的程序两个就够啦,咱们先介绍这两个吧。)
现在就来学习这两个守时/计数器的用法。这个实验的本质,便是使用自带的守时/计数器来发生50ms的守时。
先来看看这两个守时/计数器的结构吧,如下图所示。

1、守时器的结构:

从图上能够看出,守时/计数器的中心是一个加1计数器(注:16位,计数规模从0000h~ffffh),依据K0开关的不同方向,这个计数器能够对两个脉冲来历计数,一个是体系的时钟振动器,其他一个是外部的脉冲源。

2、守时器的作业办法

当计数器对体系时钟脉冲计数的时分,因为体系时钟是一个时刻基准,所以脉冲数×脉冲周期便是一段固守时刻,因而作业于守时办法;当计数器对外部的脉冲进行计数的时分(也便是对TX端计数,TX端咱们用到的时分再解说吧),就可用于对外部事情计数,作业于计数办法。咱们这个实验要发生50ms的守时,用的是守时功用,在后面的实验里咱们还要作计数功用的实验。

咱们发现,当k0向上打的时分,作业于守时办法,向下打的时分作业于计数办法。那么k0又是由什么操控的呢?
K0是一位模仿开关,方向受 这一位的操控,当 =0时,K0向上,作业于守时办法;当 =1时,K0向下,作业于计数办法。(注:数电教材的《AD转化》一章有模仿开关的原理,咱们能够查阅),
那么, 又是什么呢,它是特别功用寄存器tmod中的一位。tmod是用来操控守时/计数器的作业办法的,是一个8位的寄存器,它的各位状况如下图所示:


(注:tmod是咱们又新触摸的一个特别功用寄存器,和其他特别功用寄存器相同,在内部RAM的特别功用寄存器区。)
看到了吧, 是tmod寄存器的D2和D6位,所以,假设咱们想让T0作业于守时办法,就应该把D2置0;假设要让T0作业于计数办法,就应该把D2置1。对T1的操控也是相同的。
留意,在这儿我要特别阐明一点,咱们不能用setb指令给tmod的某一方位1,也不能用clr指令给某一方位0。为什么呢?记住咱们曾经对ie寄存器能够这样作:setb ea(开中止),clr ea(关中止),那么tmod寄存器为什么不可呢?
这是因为tmod寄存器是不能够“位寻址”的,也便是说,咱们不能独自的对其间一位进行操作,而有必要对整个寄存器进行赋值。而曾经咱们学过的ie、psw、tcon、acc这几个特别功用寄存器却是能够“位寻址”的。具体的哪些寄存器能够位寻址,而哪些寄存器不可,咱们能够参照相关教材,有很具体的阐明。
再看一下k1,它也是一个模仿开关,当与门输出是1的时分,开封闭合,发动计数器;当与门输出是0的时分,开关翻开,计数器中止。至于它怎么操控咱们稍后介绍。

3、守时时刻的核算

好啦,知道了怎样挑选守时仍是计数办法,咱们就要考虑一下守时时刻的核算了。要核算守时时刻,咱们就要知道计数器的输入脉冲周期是多少。实际上,计数器是对机器周期计数的,而咱们也知道,1个机器周期=12×振动周期,所以,计数器的输入脉冲周期是:12×(1/12MHZ)=1us。

可见,要发生50ms的守时,只需计数器记50000个脉冲就能够啦。那么,怎样让计数器在记入了50000个脉冲后,向单片机宣布一个音讯,表明守时时刻到呢?这就要用到咱们曾经学习过的概念-中止啦。咱们曾经说过,单片机有5个中止源,两个是外部中止 和 ,两个是T0和T1的溢出中止,还有一个是串行口中止。咱们曾经用过外部中止 ,这个实验咱们要用到T0的溢出中止。

16位的计数器从0开端,记入216=65536个脉冲的时分,会向外面发生溢出,这个溢出把TFX置一,(注:TF0是T0的溢出中止标志,TF1是T1的溢出中止标志),然后向CPU请求中止,在进入中止处理程序后,由硬件对TFX清0,不需求咱们操作。(注:趁便说一下TF0和TF1,它是咱们曾经触摸过的tcon特别功用寄存器中的两位,tcon是一个能够“位寻址”的特别功用寄存器,咱们在实验七顶用这个寄存器设置过外部中止的触发办法,想不起来的话,回头看看前面的实验吧。)

4、计数初值的核算

持续方才的问题,16位的计数器要记入65536个脉冲才会发生溢出中止,那么怎样让它在记入50000个脉冲后发生中止呢?这就要用到咱们在数电中心学习过的内容啦。咱们能够给计数器置一个初值65536-50000=15536,这样计数器在记入50000个脉冲之后就会发生溢出中止了。

那么,怎样给计数器置初值呢?T0和T1是两个16位的计数器,咱们能够把它们分为高8位THX和低8位TLX。Cpu和T0、T1之间的联系如下图所示(注:其间,P3.4和P3.5用作第二功用,是作业于计数办法的时分,外部的计数脉冲输入,也便是守时/计数器结构图10-1中的TX端。)

咱们以T0为例,要给它置入初值15536,就要对高8位的TH0和低8位的TL0别离置数。15536改换成16进制的数是3CB0(注:转化办法能够查阅数电教材《进制转化》一章),所以咱们就这样给T0置初值:mov th0,#3ch ;mov tl0,#0b0h,就能够啦。

5、计数器的发动和中止

在给T0置入初值之后,而且在答应T0溢出中止(注:由IE寄存器中的ET0操控,具体阐明可见实验7),和cpu敞开中止的前提下,咱们就要发动T0开端守时了。咱们前面说过T0的发动和中止是由图10-1中与门的输出决议的。当与门输出是1的时分,T0发动;当与门输出是0的时分,T0中止。
那么什么时分与门输出是1呢?从图上可知有两种状况。
(1)、当gate=0时,只需求tr0=1,即可发动T0计数
(2)、当gate=1,而且tr0=1的时分,还需求int0=1才干发动T0计数

在该实验中,咱们用到第一种状况,也便是咱们把gate赋值0,然后经过对tr0的置1和置0来发动和中止计数器。这是一种常用的办法,至于第二种办法,咱们今后经过实验给咱们剖析它们之间的不同。

Gate在哪里呢?咱们再看看上面给出的tmod寄存器图,便是d3和d7位。所以咱们在对T0初始化的时分,要给d3赋值0。至于d4~d7都和T0没有联系,能够是任何状况。
再说说tr0的问题,它也是tcon寄存器中的一位,它的各位功用如下图所示,咱们把用到的作个简略介绍。


1、TF0:T0的溢出中止,当T0溢出的时分由硬件置位,在进入中止服务程序后,由硬件清0,不必咱们操作;TF1相似。(注:假设咱们选用查询办法,经过查询TFx的状况判别是否抵达守时,而不进入中止服务程序,那就要对这1位用软件清0啦!可不要忘啦!)
TR0:当gate=0时,置一发动T0计数,置0中止T0计数;TR1相似

好啦,现在基本上剖析清楚了,咱们来看看主程序和中止服务程序的流程图吧。

四、程序流程图:

五、实验程序
(留意:在作这个实验的时分,不要忘了把JMP0跳线置于1、2的方位,挑选二极管显现单元)
org 0000h
ajmp main

org 000bh ;T0溢出中止进口地址
ajmp time0

org 0020h
main: clr p1.5
mov r1,#0ffh
mov sp,#70h ;设置仓库
mov tmod,#01h ;T0初始化,作业于守时办法,具体解说见注释
mov th0,#3ch ;T0置计数初值
mov tl0,#0b0h
setb et0 ;答应T0溢出中止
setb ea ;cpu开中止
setb tr0 ;发动T0计数
ajmp $ ;等候

time0:inc r1 ;查表求灯火,输出到p0口,具体解说见多位数码显现实验
mov a,r1
mov dptr,#tab
movc a,@a+dptr
mov p0,a
cjne a,#0ffh,next
mov r1,#0ffh
next: mov th0,#3ch ;因为计数器现已溢出,所以需求重设计数初值
mov tl0,#0b0h
reti

tab: db 0fah,0f5h,0afh,05fh ;按次序存储灯火的表格
db 0aah,55h,00h,0ffh
end

六、几点阐明
咱们来看看T0初始化的句子mov tmod,#01h,现在咱们把tmod的各位功用具体阐明一下。

(1) d2是守时/计数办法挑选,这儿应该把d2置0,挑选T0作业于守时办法
(2)d3也应该置0,这样经过操控tr0即可发动T0
(3)d1d0(M1M0)用来指明T0的位数,阐明如下:
M1M0=00:13位的计数器;
M1M0=01:16位计数器;
M1M0=10:可主动再装入的8位计数器
M1M0=11:把守时器0分红两个8位的计数器,或许封闭守时器1

(2) 在这个实验中,因为守时50ms需求16位的计数器,故d1d0=01
从上面的剖析可见,咱们给tmod能够赋值:XXXX0001,能够是01h,也能够是0f1h,咱们随意吧。

现在把这个程序下载到学习板上,看看作用吧。咱们发现,灯火改换的速度太快啦,简直没有办法看清楚,原因很简略,因为50ms的守时太短了。16位的计数器守时最多能够到达65.536ms,那么假设咱们需求更长时刻的守时,比方仍然是方才的实验,可是时刻要求是1s,该怎么办呢?

其实也很简略,咱们设一个计数器,初值是0,每次T0溢出中止的时分,给这个计数器加一。在主程序里,咱们重复检测这个计数器的值,到达20的时分调用灯火子程序就能够啦。
下面便是这个守时1s的程序,其间,咱们用r2作这个计数器。
org 0000h
ajmp main

org 000bh ;T0溢出中止进口地址·
ajmp time0

org 0020h
main: clr p1.5
mov r1,#0ffh
mov r2,#00h ;给计数器r2赋初值0

mov sp,#70h ;设置仓库
mov tmod,#01h ;设置T0作业办法
mov th0,#3ch ;T0置计数初值
mov tl0,#0b0h
setb et0 ;答应T0溢出中止
setb ea ;cpu开中止
setb tr0 ;发动T0开端计数

wait: cjne r2,#20,wait ;守时时刻未到,持续查询等候
acall light ;守时时刻到,调用查表求灯火子程序
ajmp wait

;以下是查表求灯火子程序
light: mov r2,#00h ;计数器从头赋初值

inc r1 ;查表求灯火,具体解说见实验5“多位数码显现”
mov a,r1
mov dptr,#tab
movc a,@a+dptr
mov p0,a
cjne a,#0ffh,next
mov r1,#0ffh
next: ret ;子程序回来

;以下是中止服务程序
time0: inc r2 ;计数器加1
mov th0,#3ch ;重置计数初值
mov tl0,#0b0h
reti ;中止回来

tab: db 0fah,0f5h,0afh,05fh ;灯火改换表格
db 0aah,55h,00h,0ffh
end

好啦,把这个程序下载到学习板上,就会很清楚的看到灯火的改换办法啦。

在这个实验里边,因为咱们的守时时刻较长,所以选用了16位的计数器,假设守时时刻短的话,守时/计数器还能够选用其他作业办法,例如13位,或许8位等。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/266878.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部