230 likes | 441 Views
4.4 定时/计数器. 一、定时/计数器结构及工作原理. 89 C51 片内有两个16位可 编程定时/计数器 T0、T1. 定时: 对片内振荡器的 f0/12( 机器周期)进行计数。 定时时间=(2 n - 初值)×机器 周期. 计数: 计 T0/T1 端下降沿 。检测一个1至0的跳变需要两个机器周期,故最高计数频率为振荡频率的1/24。同时,高电平至少保持 一个完整的机器周期。. 特点: 定时或计数时,都不占用 CPU 时间。除非定时/计数器溢出,才可能中断 CPU 的当前操作。.
E N D
4.4 定时/计数器 一、定时/计数器结构及工作原理 89C51片内有两个16位可 编程定时/计数器T0、T1 定时:对片内振荡器的f0/12(机器周期)进行计数。 定时时间=(2n-初值)×机器 周期 计数:计T0/T1端下降沿 。检测一个1至0的跳变需要两个机器周期,故最高计数频率为振荡频率的1/24。同时,高电平至少保持 一个完整的机器周期。 特点:定时或计数时,都不占用CPU时间。除非定时/计数器溢出,才可能中断CPU的当前操作。
注:GATE决定对定时器的启动控制 1-外部INT选通 0-内选通 INT0、INT1引脚“1”且TR0、TR1置1,则启动定时器。 只需TR0、TR1置1就启动定时器。 二、控制字和工作方式 定时/计数器工作方式由控制字TMOD、TCON来决定 1. TMOD(89H)——工作方式寄存器 (注意:TMOD不能以位寻址)
TCON(88H) TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 2. TCON(88H)——控制和标志寄存器 (注意:除了可字节寻址外,还可位寻址) SETB TR0 SETB TR1
图6-7 ① 按13位加法计数器工作 8 5 TF0 TH0 TL0 当加至TH0溢出,则TF0置位,并申请中断。 TL0高3位未用 三、工作方式 定时/计数器0 可以工作在模式 0~3 定时/计数器1 可以工作在模式 0~2 1. 模式0 M1 M0 0 0
② C/ T C/T=0,T0对机器周期计数,定时工作。定时时间: t =(213-T0初值)×振荡周期×12 C/T=1,T0对外部事件(P3.4)计数,下降沿到来则计数器加1。 T1对外部事件(P3.5)计数,下降沿到来则计数器加1。 ③ GATE 一般不用,但是当GATE=0时,禁止INTi。 2. 模式1:16位 , 其他同方式0 。 (初值=216-t / 机器周期) 3. 模式2:8位 ,时间常数可以自动装载 , 其余同方式0。 初始化时,TH0TL0,具有相同的初值。 t = (28-TH0初值)×机器周期 P136,例6-2,模式2的应用。
P136, 例6-2 P3.4 P1.0 500us 500us 外部计数方式 定时方式 外部计数方式 定时方式 START:MOV TMOD,#06H ;设置T0为模式2,外部计数方式 MOV TH0,#0FFH ;T0计数器初值255 MOV TL0,#0FFH SETB TR0 ;启动T0计数 LOOP1:JBC TF0,PTF01 ;查询T0溢出标志,TF0=1转移,且TF0=0. SJMP LOOP1 PTF01: CLR TR0 ;停止计数 MOV TMOD,#02H ;设置T0为模式2,定时方式 MOV TH0,#06H ;T0定时500us MOV TL0,#06H CLR P1.0 ;p1.0清0 SETB TR0 ;启动定时500us LOOP2:JBC TF0,PTF02 ;查询溢出标志,定时到TF0=1转移,且TF0=0. SJMP LOOP2 PTF02: SETB P1.0 ;P1.0置1 CLR TR0 ;停止计数 SJMP START
① TL0除仅用8位Reg外,其余同模式0、 1。可工作在定时或计数方式。 这时,TL0用原来T0的各控制位、引脚和中断源:C/T, GATE, TR0, TF0和T0(P3.4)、INT0(P3.2)。 • 模式3:仅对定时/计数器0有效 T0TH0+TL0 • 对定时/计数器1,停止计数。 将定时/计数器0分成两个独立的8位计数器TH0、TL0。 ② TH0占用T1的控制位TR1和中断标志位TF1,仅能工作在定时方式,其启动和关闭仅受TR1的控制。 ③定时/计数器1不能工作在方式3,若要其工作在方式3,就会立即停止计数,即保持住原有的计数值。
但T1仍可工作在方式 0~2。 这时:由于TR1、TF1被T0占用,仅用T1控制位C/T切换其定时器或计数器工作方式就可使T1工作。 计数器溢出时(13、 16或 8 bit时),只能将输出送入串口或用于不需要中断的场合。 当T1需要用作串行口波特率发生器时,T0才设置为工作方式3,这时,常将T1设置为工作方式2。 TMOD 四、举例 能正确设置 TCON 定时/计数器的应用编程需注意 会计算时间常数 通常,写入控制字的次序为: 1. 把工作方式控制字写入TMOD 2. 把定时、计数初值装入TLx、THx(x=0、1) 3. 置位EA使CPU开放中断 4. 置位ETx允许定时/计数器中断(需要时) 5. 置位TRx以启动计数
因为是加1计数器,所以当计数值为X时,装入定时/计数器的初值应为 2n-X: 方式0, n=13 • 方式1, n=16 • 方式2、3, n=8 当工作于定时状态时,由于定时/计数器是计数机器周期,每个机器周期包括12个振荡周期,则有: 1个机器周期 = 2us(6MHz) 或 = 1us(12MHz) 例1:设单片机的fosc=6MHz ,T0工作在方式0 : ① 求T0的最大定时时间T; ②产生1ms定时的T0初值; ③ 1ms定时在P1.0引脚输出周期为2ms的方波。 t = (213-初值)×机器周期 (12 / (6×106)) t = (213-初值)×2us ①T0最大定时时间对应于初值0,所以有: tmax=213×12 / (6×106)=16384 us =16 .384ms
当 t = 1ms 时,有:1000=2×( 213-初值) ② 初值= 213-500=7692=0001111000001100B TH0 TL0 ③ 对以上要求编程如下(以定时1ms中断方式控制P1.0输出方波): ORG 0000H RESET: AJMP MAIN ORG 000BH AJMP IT0P ORG 0100H MAIN: MOV SP,#60H ACALL PT0MD HERE: AJMP HERE PT0MD: MOV TMOD, #00H MOV TL0, #0CH MOV TH0, #0F0H SETB EA SETB ET0 SETB TR0 RET ORG 0120H IT0P: MOV TL0, #0CH MOV TH0, #0F0H CPL P1.0 RETI
例2: 用方式1在P1.0输出脉冲 1ms 1ms 1ms 设fosc=6MHz, 可通过定时/计数器定时1ms申请中断, 在中断程序中让 P1.0 输出1 或 0实现。 当fosc=6MHz时,振荡周期=1/6 us 机器周期=12×1/6 us=2us 所以,定时时间常数为:1ms/2us=500。 方式0时计数器为13位, 计数常数=213-500=7692=1E0CH 若用方式1,计数器为16位,计数常数=216-500=65036 =FE0CH 程序: ① 以中断方式: ORG 0000H AJMP MAIN ;转主程序 ORG 000BH ;到中断服务程序 AJMP TOINT
ORG 0100H MAIN: MOV SP ,#60H MOV TMOD ,#00 ; MOV TL0,#0CH ; MOV TH0 ,#0F0H ; SETB EA ;CPU开中断 SETB ET0 ;允许定时器0中断 SETB TR0 ;启动定时器0工作 HERE : AJMP HERE ;或用 SJMP $ ORG 0200H ;中断服务程序 TOINT : MOV TL0 , #0CH ;重新装入时间常数 MOV TH0 , #0F0H CPL P1.0 ;在P1.0脚得到方波 RETI 方式0 方式1 MOV TM0D ,#01H MOV TL0 , #0CH MOV TH0 , #0FEH
② 以查询方式 ORG 0000H AJMP MAIN ORG 2000H MAIN: MOV TMOD, #01 ;定时器0工作在方式1 MOV TL0 , #0CH MOV TH0, #0FEH SETB TR0 ;启动定时器0工作 LOOP: JNB TF0 ,$ ;查询TF0,若计数器未溢出,原地等待 CLR TF0 CPL P1.0 ;得到方波 MOV TL0,#0CH MOV TH0,#0FEH ;装入16位时间常数 SJMP LOOP
例3:设定时/计数器T0工作于方式2。要求其500us定时中断, 在中断服务程序中把累加器A的内容减1,然后送P1口。设晶 振频率为6MHz,程序如下: ORG 0000H AJMP MN ORG 000BH DEC A MOV P1 , A RETI MN: MOV SP ,#53H MOV TMOD , #02H MOV TL0 , #06H ; 送500us MOV TH0 , #06H ; 时间常数 SETB EA ; CPU开中断 SETB ET0 ; 允许T0中断 SETB TR0 ; 启动T0计数 SJMP $ ; 等待 ③ 用方式2做。定时时间为:t=(28-TL0初值)×机器周期。 所以,仅当定时时间不超过tmax方可用方式2。 这时,TL0、TH0赋予相同的值,一旦TL0溢出,置位TF0,并将TH0中的初值自动装入TL0,继续计数,循环往复。
例4:脉冲宽度的测量——TMOD中GATE =1的一个应用 当GATE=1时,若TRX=1,只有INTX引脚输入高电平时,TX才被允许计数。 利用GATE的这一功能,可测试INTX引脚上正脉冲的宽度(机器周期数)。其方法如图所示: ③ ② T0停止计数 读T0的值。 对T0初始化编程 GATE=1. INTX ④ X T0从0开始计数 ① 程序: ORG 4000H ; T0 初始化 MOV TMOD,#09H ; T0工作于方式1, 定时, GATE=1 MOV TL0 , # 00H MOV TH0 , # 00H ; 置最大时间常数 JNB P3.2 , $ ; ①P3.2低电平,原地不动 SETB TR0 ; ②P3.2高,设置TR0 JB P3.2 ,$ ; ③P3.2高,原地不动 CLR TR0 ; ④P3.2低,清TR0 ,读TL0, TH0 MOV A , TL0 MOV B , TH0 脉宽=计数值×Tp(机器周期)
例5:设定时/计数器T0工作于方式3,TL0和TH0作为两个独立例5:设定时/计数器T0工作于方式3,TL0和TH0作为两个独立 的8位定时/计数器分别产生250us和500us的定时中断,使 P1.1和P1.2 产生500us和1000us的方波(晶振频率为6MHz )。 设晶振频率为6MHZ,程序如下: ORG 0000H AJMP MAIN ;转主程序 ORG 000BH ;T0中断首地址 MOV TL0 , #131 ;TL0装入时间常数(256-125) CPL P1.1 ;P1.1口得到方波 RETI ORG 001BH ;T1中断处理程序首地址 MOV TH0 , #06H ;TH0装入时间常数(256-250) CPL P1.2 ;P1.2口得到方波 RETI MAIN: MOV TMOD , #03H ;T0工作于方式3、定时 MOV TL0 , #131
MOV TH0 , #06H ;送时间常数 SETB EA ;CPU开中断 SETB ET0 ;允许中断 SETB ET1 SETB TR0 ;启动定时 SETB TR1 SJMP $ ;等待 方式3时,由于只能是8位计数器,所以可以在中断程序中辅以软件计数,实现较长时间定时。 注意: 当一个定时器的最大定时时间仍不能满足定时要求,如: 6MHZ时钟时, 一个机器周期为2us, 最大定时时间 65536×2=131072us=131ms=0.13s 若希望定时 0.2s=200ms,则不可能用一个定时器来完成。 这时可以对定时器进行级联。
300Ω P1.7 5V CTC0定时 P1.0 40ms P3.5 CTC1计数 例6:如上述,希望定时200ms。时间到时,发光二极管或明或暗。 设定时器0 定时 20ms, 在软件中查询定时器0定时是否到20ms?若到,用一个口位(P1.0)输出方波,周期为40ms,将此方波加到T1(定时器T1的外部输入),并设置T1的计数常数为5,则可实现200ms定时: 定时器0 :方式1,定时 定时器1 :方式2,计数(5个) 时钟 6MHZ 时, 20ms/2us=10000,时间常数: 65536-10000=55536
TL0 可工作在定时或计数方式,使用原T0的各控制位、引脚和中断源。 • 使T0工作在方式3,此时,TL0、TH0为两个独立的8位计数器 TH0 仅可用于定时,且占据了T1的TR1和TF1。 T0:TL0作计数用,初值FFH,当T0引脚电平有变化则产生中断 TH0作为8位定时器,控制P1.0输出5KHz的方波。 T1: 工作在方式2,定时,溢出信号作串行口波特率发生器。 TMOD 0 0 1 0 0 1 1 1 启动T0、T1 设置INT0 INT1 申请中断 TCON 0 1 0 1 0 1 0 1 例: P139 6-4 要求:①用T0扩展外部中断源; ②P1.0引脚输出一个5KHz(周期200us)的方波。 这时,T1可工作在方式 0~2,仅用C/T即可切换其运行在定时或计数工作方式(本题中要求T1用于串行口波特率发生器)。
程序: MOV TMOD,#27H ;T0为模式3,T1为模式2, MOV TL0,#0FFH ;置TL0计数初值。 MOV TH0,#156 ;置TH0计数初值 (定时100us) MOV TH1,#data ;data是根据波特率要求设 ;置的常数(即初值) MOV TL1,#data MOV TCON,#55H ;外中断0,外中断1边沿触 ;发,启动T0,T1 MOV IE , #9FH ;开放全部中断 …… TL0INT: MOV TL0,#0FFH ;TL0重赋初值 …… RETI TH0INT: MOV TH0,#156 ;TH0重赋初值 CPL P1.0 ;P1.0取反输出 RETI
例:P141 6-6 设计实时钟程序. ( fosc=6MHz,一个机器周期2us) 定时器各种工作方式的最大定时时间见P140。 用T1产生1s定时(方式1,100ms定时中断,每中断一次软件计数器+1,10次则1s。),分与时则通过对秒的软件计数来实现。 源程序:ORG 0000H AJMP MAIN ;上电,转向主程序 ORG 001BH ;T1的中断入口地址 AJMP SERVE ;转向中断服务程序 MAIN:MOV TMOD,#10H ;设T1工作于模式1 MOV 20H,#0AH ;装入中断次数 CLR A MOV 30H,A ;时单元清0 MOV 31H,A ;分单元清0 MOV 32H,A ;秒单元清0 SETB ET1 ;允许T1中断 SETB EA ;允许CPU中断
MOV TH1,#3CH MOV TL1,#0B0H ;赋计数初值 SETB TR1 ;启动定时器T1 SJMP $ ;等待中断(可反复调用显示) SERVE: PUSH PSW PUSH ACC ;保护现场 MOV TH0,#3CH MOV TL0,#0B0H ;重新赋计数初值 DJNZ 20H,RETUNT;1s未到,返回 MOV 20H,#0AH ;重置中断次数 MOV A,#01H ADD A,32H ;秒位加1 DA A MOV 32H,A ;转换为BCD码 CJNE A,#60H,RETURN ;未满60秒,返回 MOV 32H,#00H ;记满60秒,秒位清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 ;未记满24小时,返回 MOV 30H,#00H ;记满24小时,时位清0 RETUNT: POP ACC POP PSW ;恢复现场 RETI ;中断返回 END