定时计数器中断系统 - 图文

更新时间:2023-10-10 00:48:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

例1.选用TO操作模式0,用于定时,由P1.0输出周期为10ms的方波,设晶振fosc= 6MHz。

解:P1.0输出周期为10ms宽的方波,只要每隔5ms取反一次即可得到10ms的方波。因此可以选用TO定时5ms。

Xo=213-fosc×t/12=8192—6×5×1000/12=8192—2500=5692=163CH

由于作13位计数器使用,TL0的高3位未用,应填0,而将计数初值低字节的高3位左移至高字节的低3位,其余5位均左移3位。TH0占高8位,所以Xo的实际值应为: X=1011000100011100B=B11CH

根据题意设置模式控制字:00000000 00H

由于上电复位后,TMOD各位均为0,所以此字可以不用写入。 初始化程序如下: ORG 8000H

MOV TL0,#1CH ;TO的计数初值X0 MOV THO,#081H

SETB TR0 ;启动TO

LPl:JBC TF0,LP2 ;查询TO计数溢出否,同时清除TF0

AJMP LPl ;没有溢出等待 LP2:MOV TH0,#081H

MOV TL0,#1CH ;溢出重置计数初值 CPL P1.0 :输出取反 SJMP LPl ;重复循环

例2.用定时器1产生一个50Hz的方波,由P1.1输出,仍用程序查询方式,fosc=12MHz。 解:方波周期T=1/50=O.02s=20ms,用T1定10ms,计数初值X1:

16

X1=2—12×10×1000/12=65536—10000=55536=D8FOH 源程序如下:

MOV TMOD,#10H ;T1模式1,定时 SETB TRl ;启动T1

LOOP: MOV THl,#0D8H ;T1计数初值

MOV TLl,#0FOH

JNB TFl,$ ;T1没有溢出等待 CLR TFl ;产生溢出清标志位 CPL P1.1 ;P1.1取反输出 SJMP LOOP ;循环

例3.用定时器1,模式2计数,要求每计满200次,将P1.0端取反。

解:T1工作于计数方式,外部计数脉冲由T1(P3.5)引脚引入,每来一个由1至0的跳变计数器加1,由程序查询TFl的状态。

8

计数初值 Xl=2—200=56=38H

THl=TLl=38H,TMOD=60H(计数方式,模式2) 源程序如下:

MOV TMOD,#60H ;T1模式2,计数方式 MOV THl,#38H ;T1计数初值 MOV TLl,#38H

1

SETB TRl ;启动T1 LOOP: JBC TFl,REP ;TFl=1转 SJMP LOOP ;否则等待

REP: CPL P1.0 ;P1.o取反输出 SJMP LOOP

例4.由P3.4引脚(TO)输入一低频脉冲信号(其频率小于0.5kHz),要求P3.4每发生一次负跳变时,P1.0输出一个500μs的同步负脉冲,同时P1.0输出一个lms的同步正脉冲。已知fosc =6MHz。

解:按题意画出输出信号的波形如图。

编程思路:

设初态P1.0输出高电平(系统复位时即为高),P1.1输出低电压,设TO为模式2,计数工作方式(初值为FFH)。当加在P3.4上的外部脉冲产生由1至0的负跳变时,则使TO计数器加1而产生溢出,程序查询到TF0为1时,改变为500μs定时工作方式,并且使P1.0输出为0,P1.1输出1。当TO第一次定时500μs到时,计数器溢出后,使P1.o恢复为1,TO继续第二次500μs定时的计数,产生溢出后恢复P1.1为0。然后TO又恢复对外部脉冲的计数方式,如此循环。

500μs定时的计数初值X为:X=256—500×6/12=6 程序如下:

START:MOV TMOD,#06H ;TO模式2,计数工作方式

MOV TH0,#0FFH ;TO计数初值 MOV TL0, #0FFH

CLR P1.1 ;P1.1初态为0 SETB TR0 ;启动TO

LOOP: JBC TF0, LP1 ;检测外部信号负跳变否?

SJMP LOOP ;无等待

LPl: CLR TR0 ;关定时器

MOV TMOD,#02H ;TO改变为定时500μs,模式2 MOV TH0,#06H ;定时的计数初值 MOV TL0, #06H

SETB P1.1 ;P1.1输出1 CLR P1.0 ;P1.0输出0 SETB TR0 ;启动TO定时

2

LOOPl:JBC TF0, LP2 ;第一个500μs到否?

SJMP LOOP1 ;未到等待

LP2: SETB P1.0 ;到了P1.0恢复 LOOP2:JBC TF0, LP3 ;第二个500μs到否?

SJMP LOOP2

LP3: CLR P1.1 ;P1.1恢复0

CLR TR0 ;关定时器 AJMP START

模式2的这种操作方式,用户可以省去重装计数初值的程序,并可产生相当精度的定时时 间。特别适用于作串行口波特率发生器。

例5.设某用户系统中已使用了2个外部中断源,并置定时器T1工作于模式2,作串行口波特率发生器用。现要求再增加一个外部中断源并由P1.o输出一个5kHz的方波。fosc= 12MHz。

解:为了不增加其他硬件开销,可设置TO工作于模式3计数方式,把TO的引脚作附加的外部中断输入端,TL0的计数初值为FFH,当检测到TO引脚由1至0的负跳变时,TL0立即产生溢出,申请中断,相当于边沿触发的外部中断源。 TO模式3下,TL0作计数用,而TH0可用作8位的定时器,定时控制P1.0输出的51 KHz 的方波信号。

TL0的计数初值为FFH;TH0的计数初值x为:

P1.0的方波频率为5kHz,故周期T:1/5kHz=0.2ms=200μs 用TH0定时100μs,X=256—100×12/12=156 程序如下:

MOV TMOD, #27H ;TO模式3,计数;T1模式2,定时 MOV TL0,#0FFH ;TL0计数初值 MOV TH0,#156 ;TH0计数初值

MOV THl,#data ;data是根据波特率要求设置的常数 MOV TLl, #data

MOV TCON, #55H ;外中断0、l边沿触发,启动TO,T1 MOV IE, #9FH ;开放全部中断 TL0溢出中断服务程序(由000BH转来): TLOINT:MOV TL0,#0FFH ;TL0重赋初值 (中断处理) RETI

TH0溢出中断服务程序(由001BH转来): TH01NT:MOV TL0,#156 ;TH0重赋初值 CPL P1.0 ;P1.o取反输出 RETI

串行口及外部中断0,1的服务程序在此不再一一列出。

例6.将例4采用中断方式实现其要求的功能,即TO初始化只要有负跳信号就可引起TO中断,在TO中断服务程序中产生相应的波形输出。其程序如下: ORG 0000H SJMP START

3

ORG 000BH

AJMP INTR0 ;TO中断入口 ORG 0100H

START: MOV SP,#30H :设置堆栈

MOV TMOD,#06H :TO模式2,计数

MOV TH0,#0FFH ;TO计数方式的计数初值 MOV TL0,#0FFH SETB TR0

CLR P1.1 ;P1.1初态为低 SETB P1.0 ;P1.0初态为高 MOV IE,#82H :CPU、TO开中断 WAIT: SJMP $ ;等待TO引脚负跳变 AJMP START :重复循环 T0中断服务程序:

INTR0: CLR TR0 ;关T0

MOV TMOD,#02H ;T0改为定时500μs,模式2 MOV TH0,#06H ;T0定时方式计数初值 MOV TL0, #06H

SETB TR0 ;启动TO定时 SETB P1.1 ;P1.1输出高 CLR P1.0 ;P1.0输出低

LP0: JBC TF0,LPl ;第一个500μs到否? SJMP LP0 ;未到,等待

LPl: SETB P1.1 ;到了,P1.0恢复高 LP2: JBC TF0,LP3 ;第二个500μs到否? SJMP LP2

LP3: CLR P1.1 ;P1.1恢复低:

CLR TR0 ;关TO

SETB EA ;CPU开中断 SETB ET0 ;TO开中断

RETI ;中断返回

例7.用定时器1定时,由P1.0输出周期为2分钟的方波。已知fosc =12MHz。

解:此例要求P1.0输出方波的周期时间较长,用一个定时器无法实现长时间的定时,解决的办法可用定时器加软件计数的方法或是两个定时器合用的方法来实现。下面分别介绍这二种方法。 方法一:

解:用定时器T1定时10ms;加软件计数实现定时一分钟。 、 40H单元作Ins的计数单元:ls/10ms=100次 41H单元作s的计数单元:lmin/ls=60次

29H单元的(4FH)137位作分的计时标志位:标志用4FH T1的计数初值:X=216—12×10×1000/12=55536=D8FOH 主程序:

ORG 0000H

4

AJMP 2000H ORG 001BH

AJMP 2100H ;T1中断服务程序入口 ORG 2000H

MOV TMOD, #10H ;T1定时,模式1 MOV THl, #0138H ;T1计数初值 MOV TLl, #0FOH

MOV IE, #88H ;CPU、T1开中断 SETB TRl ;启动T1 MOV 40H, #100 ;ms计数初值 MOV 41H, #60 ;S计数初值 CLR 4FH

TT:JNB 4FH, TT ;等待1分钟到 CLR 4FH ;清分标志位 CPL P1.0 ;输出变反 AJMP TT ;反复循环 T1中断服务程序:(由001BH转来) ORG 2100H

MOV THl, #0D8H ;T1重赋初值 MOV TLl, #0FOH

DJNZ 40H, TTl ;判1S到否? MOV 40H, #100 ;到,重赋计数值 DJNZ 41H, TTl ;判1rain到否? MOV 41H, #60 ;到,重赋计数值 SETB 4FH ;置lmin到标志位 TTl: RETI ;中断返回

方法二: . 解:采用两个定时器合用实现长时间的定时,两个定时器中一个定时,另一个作为计数,定时的时间到可以输出一个控制信号作为另一个定时器的计数脉冲。具体的方法如下:线路连接见图

设T0定时60ms,模式1;T1计数。当TO 60ms到,控制P1.2输出方波作为T1的计数脉冲(P1.2的输出与T1(P3.5)连接起来);T1计满溢出,控制P1.0输出脉宽为2分钟的方波,TO的计数初值Xo:

16

X0=2—12×60×100/12=5536=15AOH T1的计数初值X1:

16

X1=2—1×60×1000/60=64536=FCl8H 主程序如下:

ORG 0000H SJMP START ORG 000BH

AJMP INTR0 ;TO中断服务程序人口 ORG 001BH

AJMP INTRl ;T1中断服务程序入口

5

ORG 2000H

START: MOV TMOD,#51H ;TO定时、模式1、T1计数模式1

MOV TH0,#15H ;TO计数初值 MOV TL0,#0AOH

MOV THl,#0FCH ;T1计数初值 MOV TLl,#18H

MOV IE,#8AH ;CPU、TO、T1开中断 SETB TR0 ;启动TO SETB TRl ;启动T1

LL: SJMP LL ;等待min到中断 T0的中服务程序(由000BH转来):

INTR0: MOV TH0,#15H ;TO重赋初值 MOV TL0,#0AOH

CPL P1.2 ;P1.2取反作T1的计数脉冲输入

RETI ;中断返回

T1的中断服务程序(由001BH转来)

INTRl: MOV THl,#0FCH ;T1重赋初值

MOV TLl,#18H

CPL P1.0 ;P1.0取反输出

RETI

由此程序可知,定时器仅在初始化和计满溢出产生中断时,才占用CPU的工作时间,启动之后,定时器的定时,计数过程全部是独立运行的,因而采用中断后使CPU有较高的效率。

例8:利用T0门控位测试/INT0引脚上出现的正脉冲的宽度,并以机器周期数的形式显示在显示器上.

根据要求可这样设计程序:将T0设定为方式1,GATE设为1,置TR0为1。一旦/INT0 (P312)引脚上出现高电平即开始计数,直至出现低电平,停止计数,然后读取T0的计数值 并显示。

测试过程如下:

源程序如下:

BEGIN: MOV TMOD, #09H ;T0工作于方式1,GATE置1 MOV TL0, #OOH MOV TH0, #00H

WAITl: JB P3.2, WAITI ;等待INT0变低 SETB TRo ;启动T0

WAIT2: JNB P3.2, WAIT2 ;等待正脉冲到 WAIT3: JB P3.2, WAIT3 ;等待INTo变低 CLR TR0 ;停止To计数

MOV R0, #DISBUF ;显示缓冲区首地址送R0

6

MOV A, TL0 ;机器周期的存放格式为低位占低地址, 高位占高地址,连续4个显示缓冲单元 XCHD A, @Ro INC Ro SWAP A

XCHD A, @Ro INC R0

MOV A, THo XCHD A, @Ro INC Ro SWAP A

XCHD A, @Ro

DIS: LCALL DISUP ;长调用显示子程序 AJMP DIS ;重复显示机器周期数

由于定时方式l的16位计数长度有限,被测脉冲高电平宽度只能小于65536个机器 周期。

例9:下面的程序使定时器/计数器T0工作在模式3,TL0和TH0作为两个独立的8位定时器/计数器分别产生200微秒和400微秒的定时中断,使P1.0和P1.1产生400微秒和800微秒的方波(晶振频率为6MHz)。 . ‘ ORG 0000H

RESET:AJMP MAlN ,复位入口转主程序 ORG 000BH

AJMP ITOP ,转T0中断服务程序 ORG 001BH AJMP ITlP ORG 0100H

MAIN: MOV SP, #60H ACALL PTOM3 HERE: AJMP HERE

PTOM3: MOV TMOD, #03H ;TO初始化程序 MOV TL0, #9cH ;TO置初值 MOV TH0. #038H

SETB TRO ;启动TO

SETB ET0 ;允许TO中断 SETB TRl ;启动T1

SETB ETl ;允许T1中断 SETB EA ;cPu开放中断

RET

ITOP: MOV TL0, #9CH CPL P1.0 RETI

ITlP: MOV TH0, #38H

CPL P1.1 ;P1.1位取反

7

RETI

例10:可编程乐曲演奏器。

单片机用做可编程乐曲演奏器的原理是,通过控制定时器的定时时间来产生不同频率的 方波,驱动喇叭发出不同音阶的声音,再利用延迟来控制发音时间的长短,即可控制音调中 的节拍。把乐谱中的音符和相应的节拍变换为定常数和延迟常数,作为数据表格存放在存储 器中。由程序查表得到定时常数和延迟常数,分别用以控制定时器产生方波的频率和发出该 频率方波的持续时间。当延迟时间到时,再查下一个音符的定时常数和延迟常数。依次进行 下去,就可自动演奏出悦耳动听的乐曲。 下面是歌曲“新年好”的一段简谱:

l=C 1 1 1 5 I 3 3 3 l I 1 3 5 5 I 4 3 2一I

用定时器Tl方式1来产生歌谱中各音符对应频率的方波,由P1.0输出驱动喇叭。节拍的控制可通过调用延时子程序D200(延时200 ms)次数来实现,以每拍800 ms的节拍时间为例,那么一拍需要循环调用D200延时子程序4次。同理,半拍就需要调用2次。设单片机晶振频率为6MHz,乐曲中的音符、频率及定时常数三者之间的对应关系如下所示。

乐曲演奏控制程序如下:

ORG 001BH ;定时器Tl中断入口 M0V THl, R1 ;重装定时初值 MOV TLl, R0

CPL P1.0 ;输出方波 RETI ;中断返回 ORG 1000H ;主程序

START:M0V TMOD, #10H ;定时器T1方式1 MOV IE, #88H ;允许T1中断 MOV DPTR, #TAB ;表格首地址 L00P:CLR A

MOVC A, @A+DPTR ;查表

MOV R1, A ;定时器高8位存R1 INC DPTR CLR A

MOVC A, @A+DPTR ;查表

M0V R0, A ;定时器低8位存R0 0RL A, R1

JZ NEXTO ;全O为休止符 MOV A, R0 ANL A, R1

CJNE A, #0FFH, NEXT ;全l表示乐曲结束

8

SJMP START ;从头开始,循环演奏 NEXT:MOV THl, R1 ;装入定时值 MOV TLl, R0

SETB TRl ;启动定时器 SJMP NEXTl

NEXT0:CLR TRl ;关闭定时器,停止发音 NEXTl:CLR A INC DPTR

MOVC A, @A+DPTR ;查延迟常数 MOV R2, A

LOOPl: LCALL D200 ;调和延时200ms子程序 DJNZ R2, LOOPl ;控制延迟次数 INC DPTR

AJMP L00P ;处理下一个音符 D200: MOV R4, #81H ;延时20ms子程序 D200B: MOV A, #0FFH D200A: DEC A JNZ D200A DEC R4

CJNE R4, #00H, D200B RET

TAB: DB 0FEH,25H,02H,0FEH,25H,02H DB OFEH,25H,04H,0FDH,80H,04H DB 0FEH,84H,02H,0FEH,84H,02H DB 0FEH,84H,04H,0FEH,25H,04H DB 0FEH,25H,02H,OFEH,84H,02H DB 0FEH,0COH,04H,OFEH,OCOH,04H DB 0FEH,98H,02H,0FEH,84H,02H DB 0FEH,57H,08H,00H,00H,04H DB 0FFH,0FFH END

例11:如图所示,将P1口的P1.4~P1.7作为输入位,P1.O~P1.3作为输出位,要 求利用8031将开关所设的数据读入单片机内,并依次通过P1.0~P1.3输出,驱动发光二极管,以检查P1.4~P1.7输入的电平情况(若输入为高电平则相应的LED发亮)。现要求采用中断边沿触发方式,每中断一次,完成一次读写操作。

解:如图所示,采用外部中断O,中断申请从/INT0输入,并采用了去抖动电路.

当P1.0~P1.3的任何一位输出1时,相应的发光二极管就会发光。当开关s1闭合时,发中断请求,中断服务程序的入口地址为0003H。

ORG O000H

AJMP MAIN ;上电,转向主程序 0RG O003H ;外部中断O入口地址 AJMP INSER ;转向中断服务程序 ORG 0100H ;主程序

9

SETB EX0 ;允许外部中断O中断 SETB IT0 ;选择边沿触发方式 SETB EA ;CPU开中断 HERE:SJMP HERE ;等待中断 0RG 0200H ;中断服务程序

MOV A, #OFOH

MOV P1, A ;设P1.4~P1.7为输入 MOV A, P1 ;取开关数

SWAP A ;A的高低四位互换 MOV P1, A ;输出驱动LED发光 RETI ;中断返回 END

当外部中断源多于2个时,可采用硬件请求和软件查询相结合的办法,把多个中断源通过硬件经或非门引入到外部中断输入端/INTX,同时又连到某个I/O口。这样,每个中断源都可能引起中断,在中断服务程序中读入I/O口的状态,通过查询就能区分是哪个源引起的中断,若有多个中断源同时有中断请求,则查询的次序就是同一优先级中断中的优先权。

例12:如图所示。此中断线路可实现系统的故障显示。当系统的各部分正常工作时,4个故障源的输入均为低电平,显示灯全不亮,当有某个部分出现故障时,则相应的输入线由低电平变为高电平,相应的发光二极管亮。

解:如图所示,当某一故障信号输入线由低电平变为高电平时,会通过INT0线引起8031 中断(边沿触发方式),在中断服务程序中,应将各故障源的信号读入,并加以查询,进行相 应的发光显示。

源程序如下

ORG 0000H

10

AJMP MAIN ;上电,转向主程序 ORG 0003H ;外部中断O入口地址 AJMP INSER ;转向中断服务程序

MAIN:ANL P1, #55H ;P1.O,P1.2,P1.4,P1.6为输入 ;P1.1,P1.3,P1.5,P1.7输出为O SETB EX0 ;允许外部中断0中断 SETB IT0 ;选择边沿触发方式 SETB EA ;CPU开中断 HERE:SJMP HERE ;等待中断

INSER:JNB P1.0, L1 ;查询中断源,(P1.O)=O,转L1

SETB P1.1 ;是P1.O引起的中断,使相应的二极管亮 L1:JNB P1.2, L2 ;继续查询 SETB P1.3 ;

L2:JNB P1.4, L3 SETB P1.5

L3:JNB P1.6, L4 SETB P1.7

L4: RETI ;中断返回 END

例13:设计一电子钟,要求满1s则秒位32H单元内容加1,满60s则分位31H单元内容加1,满60min则时位30H单元内容加1,满24h则将30H,31H,32H的内容全部清0。

解:由题意,中断服务程序流程图如图所示。 ORG O000H

AJMP MAIN ;上电,转向主程序 ORG 001BH ;Tl的中断入口地址 AJMP SERVE ;转向中断服务程序

MAIN: MOV TMOD, #10H ;设T1工作于方式1 MOV 20H, #OAH ;设中断次数 CLR A

MOV 30H, A ;时单元清零

11

MOV 31H, A ;分单元清零 MOV 32H, A ;秒单元清零 SETB ETl ;允许T1中断 SETB EA ;允许CPU中断 MOV THO, #3CH

MOV TLO, #OB0H ;赋计数值

SETB TRl ;启动定时器T1 SJMP $ ;等待中断 SERVE: PUSH PSW

RETUNT:

PUSH ACC ;保护现场 MOV THO, #3CH

MOV TLO, #OBOH ;重新赋计数值 DJNZ 20H, RETUNT ;1s未到,返回 MOV 20H, #OAH ;重置中断次数 MOV A, #01H

ADD A, 32H ;秒位加1 DA A

MOV 32H, A ;转换为BCD码 CJNE A, #60H, RETUNT

;未计满60s,返回 MOV 32H, #OOH ;计满60s,秒位清0 MOV A, #01H

ADD A, 31H ;分位加1 DA A

MOV 31H, A ;转换为BCD码 CJNE A, #60H, RETUNT

;未计满60min,返回 MOV 31H, #00H ;计满60min,分位清0 MOV A, #01H

ADD A, 30H ;时位加1 DA A

MOV 30H, A ;转换为BCD码 CJNE A, #24H, RETUNT

;未计满24h,返回 MOV 30H, #00H_ ;计满24h,时位清0 POP ACC

POP PSW ;恢复现场 RETI ;中断返回 END 12

以下例题选自西电出版社潘永雄 《新编单片机原理与应用》

P128~P135

例4.4 假设晶振频率为12MHz,试利用定时/计数器TO的方式2,在P1.7引脚输出周期为200μs的方波。

分析:定时器工作方式2的最长定时时间为256μs,而方波周期为200μs,即方波高、低电平时间只有200μs /2,即100μs,可令TO工作于方式2,定时时间设为100μs,定时时间到对P1.7引脚锁存器取反,即获得周期为200μs的方波。

定时器TO初值M为:

8

M=2一(12/12)×100=156=9CH

参考程序如下:

ORG 0000H

LJMP MAIN :跳到主程序入口 ORG 000BH LJMP CTC0 ;定时器T0中断入口地址

ORG 1000H

MAIN: MOV SP, #4FH ;初始化堆栈指针SP

MOV A, TMOD ;为了不影响定时/计数

;T1的工作状态,先读出

TMOD

ANL A, #0FOH ;与FOH相与,使高4位不

;变,低4位清零

ORL A, #000000l0B ;由TRO控制计数器开和

关,GATE位为O ;定时状态,即C/T位为 O,M1M0为10,即方式2

MOV TMOD,A ;将工作方式控制字写入TMOD

13

MOV TLO, #9CH :送初值 MOV TH0, #9CH ;送重装初值 SETB ET0 ;允许定时器T0中断 SETB EA ;开中断

SETB TR0 :启动定时器T0

HERE:SJMP HERE ;循环等待,相当于虚拟主程序 ;定时器T0的中断服务程序 CTC0:

CPL Pl.7 RETI

例4.5 假设晶振频率为12 MHz,试编写一程序,在P1.7引脚输出周期为2s的方波。

分析:本例表面上与上例区别不大,只是方波周期长了,但我们知道当系统晶振频率为12MHz时,即使定时/计数器工作在方式1,最长定时时间也不过65.536 ms,而目前需要

P1.7引脚上输出周期为2 s(高低电平时间为l s)的方波,属于超长定时问题,除了使用定时器功能外,还要使用软件计数方法。

要获得1s(即1000 ms)的定时时间,可使用定时器TO方式1,定时时间可设为51ms,软件计数器初值为20。定时器TO溢出时,软件计数器减1,当软件计数器减到0时,就获得了1s的时间。具体程序如下:

参考程序如下:

TIMECON DATA 28H ;把28H单元作为软件计数器

ORG 0000H LJMP MAIN ;跳到主程序入口 ORG 000BH

LIMP CTC0 ;定时器T0中断入口地址

ORG 1000H

MAIN:

MOV SP, #4FH ;初始化堆栈指针SP

MOV A, TMOD ;为了不影响定时/计数器Tl

14

;的工作状态,先读出TMOD

ANL A, #0FOH;与FOH相与,使高4位不变,

低4位清零

ORL A, #00000001B:由TR0控制计数器开和关,

GATE位为O,定时状态,即C/T位为O,M1M0为01, 即方式1

MOV TMOD, A :将工作方式控制字写入TMOD MOV TL0, #0BOH ;定时时间为50ms(即50000

μs),初值为3CBOH

MOV TH0, #3CH SETB ET0 :允许定时器TO中断 SETB EA :开中断 SETB TR0 :启动定时器T0

MOV TIMECON,#14H;软件计数器初值为14H(即20)

HERE: SJMP HERE:循环等待,相当于虚拟主程序 ;定时器T0的中断服务程序 CTC0:

MOV TL0, #0BOH :重装定时器初值 MOV TH0, #3CH :为了减少定时误差,进入中

断服务后,先重装定时器初值

DJNZ TIMECON,NEXT:软件计数器减1,不等于O,

就返回

MOV TIMECON,#14H:重装软件计数器初值 CPL P1.7 :对P1.7取反 NEXT:

RETI

例4.6 系统晶振频率为12 MHz,试利用定时器TO在P1.6引脚上输出频率为1400 Hz的方波(持续时间为60 ms),然后不断检测P1.7引脚状态,当P1.7引脚上存在负脉冲时,在负脉冲过后立即在P1.6引脚输出频率为2300 Hz的

15

方波(持续时间也是60 ms),否则3 s后在P1.6引脚上输出频率为1400 Hz的方波(持续时间为60 ms)。 分析:本例涉及定时器重复使用问题,有一定的代表性。在单片机应用系统中往往需要多段长短不一的定时时间,而CPU内定时/计数器的个数有限,如MCS-51系列只有2个定时器。如果两个或两个以上的定时时间没有重叠,原则上就可以利用同一定时器实现 (重新设置工作方式和定时器初值)。

方波频率为1400Hz,则方波周期为l/1400 Hz,即714.28 μs,高低电平时间为357.14μs。当TO工作于方式2(自动重装初值的8位定时/计数器)时,最长定时时间为256μs,小于1400 Hz方波要求的定时时间,必须使用软件计数器。因此,可将定时时间设为119μs,软件计数器初值设为3,于是可获得3×119(即357μs)的延迟时间,即方波周期为714μs,频率为1400.56 Hz,与实际值非常接近。 对于频率为2300 Hz的方波来说,周期为1/2300 Hz,即434.782μs,高低电平时间为217.39l us,小于方式2的最长定时时间256μs。因此,将定时时间设为217μs时,即可获得周期为434μs的方波(频率为1/434μs,2304.147 Hz),误差也不大。

至于持续时间,可用软件延迟方式获得。

在检测P1.7引脚状态期间,不能用软件延迟方式,需要重新初始化定时/计数器TO的工作方式,作为16位定时器使用。

参考程序如下: X TIME DATA 2AH ;延迟时间参数x Y TIME DATA 2BH ;延迟时间参数Y;这两个单

元确定的延迟时间为t

TIME DATA 2CH ;延迟时间计数器,总的延迟

时间为Time×t

SINCON DATA 2DH :送1400 Hz时的计数器 SINl400 BIT 00H ;位地址OOH作为1400 HZ方

波标志,当SIN1400为1时, 发1400 Hz:反之,发2300

16

Hz MAIN:

ORG 0000H

LJMP MAIN ;跳到主程序入口 ORG 000BH

LJMP CTC0 ;定时器T0中断入口地址 0RG 1000H

MOV SP, #4FH ;初始化堆栈指针SP MOV A, TMOD;初始化定时器T0(工作在方式2) ANL A, #0FOH ;为了不影响定时/计数器Tl

的工作状态,先读出TMOD 与FOH相与,使高4位不变, 低4位清零

ORL A, #000000lOB ;由TRO控制计数器开和

关,GATE位为0, 定时状态,即C/T位为O,MlM0为10,即方式2

MOV TMOD, A ;将工作方式控制字写入TM0D

;发送1400Hz方波时定时器TO的初始化命令 MOV TLO, #89H ;送初值 MOV TH0, #89H ;送重装初值,定时时间为

119μs,初值为89H,计

器初值为3

MOV SINCON,#03H ;用SlNCON单元存放计数

初值(119×3=357μs),实际频率为1400.56

Hz

SETB SINl400

SETB ET0 ;允许定时器T0中断 SETB EA ;开中断 SETB TRO :启动T0 :延迟60 ms

MOV TIME, #06H

17

LOOPl:

MOV X TIME,#109 MOV Y_TIME,#45

LCALL DELAY :延迟10 ms DJNZ TIME, LOOPl

CLR TR0 ;延迟60 ms后停止 CLR Pl.6 ;将P1.6引脚置低电平 :重新初始化定时/计数器T0

MOV A, TMOD ;为了不影响定时/计数器

Tl的工作状态,先读出TMOD

ANL A, #0FOH ;与FOH相与,使高4位不变,

低4位清零

ORL A, #00000001H ;由TIm控制计数器开和关,

GATE位为0, 定时状态,即C/T位为0,M1M0为01,即方式1

MOV TMOD, A

MOV TL0, #3CH ;送初值高位,定时器初值为

3CBO,即定时时间为50 ms

MOV TH0, #0BOH CLR ETO CLR TF0 SETB TR0 MOV TIME, #3CH LOOP2:

JNB P1.7, MPLUS JNB TFO, LOOP2 MOV TLO, #3CH MOV THO, #0BOH CLR TFO DJNZ TIME, LOOP2 :软件计数器减 SJMP OUTl400 MPLUS:

JB P1.7,OUT2300 JNB TFO, MPLUS

18

MOV TL0, #3CH MOV THO, #0B0H CLR TF0 DJNZ TIME, MPLUS SJMP OUT1400 OUTl400:

MOV A, TMOD ANL A, #0F0H

ORL A, #00000010B

MOV TMOD, A MOV TLO, #89H MOV THO, #89H MOV SINCON, #03H

SETB SINl400 SETB ET0 ;允许定时器T0中断 SETB TRO :启动TO SJMP ST0P OUT2300:

;发送2300 Hz方波时定时器哟的初始化命令 MOV A, TMOD ;

ANL A, #0FOH ; ORL A, #00000010B ; MOV TMOD,A MOV TL0, #27H ;送初值 MOV THO, #27H ;送重装初值,定时时间为

217μs,初值为27H,

际频率为2304 Hz

CLR SINl400

SETB TR0 STOP:

:延迟60 ms MOV TIME, #06H

19

LOOP3:

MOV X TIME,#109 MOV Y TlME,#45

LCALL DELAY :延迟10 ms DJNZ TIME, LOOP3

CLR TRO ;延迟60 ms后停止 CLR ETO CLR EA

END

;定时器T0中断服务程序(产生1400,2300 Hz正弦波) CTCO:

JNB SINl400, SIN2300 ;如果特征位为O,

说明要发2300 Hz

DJNZ SINCON, CTCEND MOV SINCON, #03H CPL Pl.6 SJMP CTCEND SIN2300:

CPL P1.6 CTCEND:

RETI

:※※※※※※通用延迟子程序※※※※※※※※※※ ;延迟时间参数在2AH(Y)、2BH(X)单元中,总的延迟时间t ;t=(4y+2xy+10)T,其中T是机器周期。当晶振频率为12 MHz时,T=1μs

;典型参数I:X=198,y=250时,延迟时间t=100 010μs,即近似100 ms

;典型参数II:x=109,y=45时,延迟时间t=10 ms ;子程序名称:Delay Delay:

20

PUSH PSW CLR RSO SETB RSl :使用2区

MOV R7, Y-TIME ;取延迟时间参数Y DLOOPl:

MOV R6, X TIME ;取延迟时间参数x DL00P2:

DJNZ R6, DLOOP2 DJNZ R7, DLOOP1 POP PSW RET

例4.7 利用定时/计数器T1门控信号GATE功能,测量/INTl引脚上正脉冲信号的宽度(单位为机器周期)。

从定时/计数器T1结构可以看出:当GATE位为l时,计数脉冲开关状态由TRl和/INT1(即P3.3)引脚控制。因此,可令定时/计数器T1工作在方式1,并处于定时状态(即用 频率稳定的时钟信号度量/INTl引脚上正脉冲宽度),参考程序如下:

ORG 0000H LJMP MAIN 0RG 1000H MAIN:

MOV SP, #4FH

MOV A, TMOD ANL A, #0FH

0RL A, #10010000B

MOV TMOD, A MOV TLl, #00H MOV THl, #00H WAITL:

JB P3.3, WAITL ;等P3.3引脚为低电平 SETB TRl ;当P3.3引脚为低电平,

21

即可启动计数器

WAITH:

JNB P3.3, WAITH ;等待P3.3引脚变高电平

WAITHL:

JB P3.3,WAITHL ;等待P3.3引脚正脉冲的下降沿

CLR TRl ;关闭计数器T1

至此,P3.3引脚脉冲宽度就出现在T1计数器中。

例4.8 利用软件定时方式测量P3.3引脚脉冲信号的频率。

当被测脉冲信号频率较高(如数十kHz)时,不能通过测量信号周期方式求出信号频率(如例4.7所示),否则误差将很大。为此,可令定时器处于计数状态,结合软件定时方式,在指定时间内对外脉冲计数(被测脉冲信号从P3.3引脚输入)。

参考程序如下: X TIME DATA 2AH ;延迟时间参数x Y_TIME DATA 2BH ;延迟时间参数Y;这两个单

元确定的延迟时间为t

TIME DATA 2CH ;延迟时间计数器,总的延迟

时间为Time×t

ORG 0000H LJMP MAIN ORG 1000H MAIN:

MOV SP, #4FH

MOV A, TMOD ;初始化定时器T1(工作在方式1)

22

ANL A, #0FH

ORL A, #01010000B MOV TMOD, A

MOV TLl, #0OH ;计数器初值为O MOV THl, #00H

CLR ET1 ;用软件查询 MOV TIME, #5 ;每10 ms计数一次,共进行5次 LOOPl:

MOV X TIME,#109 ;初始化软件延迟时间参数 MOV Y TIME,#45 SETB TRl ;启动计数器T1 LCALL DEIAY ;延迟10 ms CLR TRl ;停止计数 DJNZ TIME, L00P1

至此,T1中的计数值就是50 ms内的脉冲个数。

23

本文来源:https://www.bwwdw.com/article/hwzf.html

Top