6.3 定时器/计数器的应用 6.3.1 初始化 初始化的内容如下: 6.3 定时器/计数器的应用 6.3.1 初始化 初始化的内容如下: (1) 根据设计需要先确定定时器/计数器的工作模式及工作方式,然后将相应的控制字送入TMOD寄存器中。
(2) 计算出计数初始值并写入TH0、TL0、TH1、TL1中。 (3) 通过对中断优先级寄存器IP和中断允许寄存器IE的设置,确定计数器的中断优先级和是否开放中断。 (4) 给定时器控制寄存器TCON送命令字,控制定时器/计数器的启动和停止。
6.3.2 初值的计算 定时器/计数器T0、T1不论是工作在计数器模式还是定时器模式下,都是加1计数器,因而写入计数器的初始值和实际计数值并不相同,两者的换算关系如下:设实际计数值为C,计数最大值为M,计数初始值为X,则X=M-C。其中计数最大值在不同工作方式下的值不同,具体如下:
(1) 工作方式0:M=213=8192。 (2) 工作方式1:M=216=65 536。 (3) 工作方式2:M=28=256。 (4) 工作方式3:M=28=256。 这样,在计数器模式和定时器模式下,计数初值都是X=M-C(十六进制数)。 定时器模式下对应的定时时间为 T=C·T机=(M-X)T机 式中,T机为单片机的机器周期(T机为晶振时钟周期的12倍)。
6.3.3 应用举例 [例6.1] 单片机晶振fosc=6 MHz,利用定时器T1定时中断方法产生周期为4 ms的方波,并由P1.0端输出。 时间常数2 ms对应的计数初值X为 T机=12/fosc=(12/6)×10-6 s=2 μs X=M-T/T机=213-2×10-3/(2×10-6)=7192 转化为十六进制为 X=1C18H=11100000011000B
主程序及中断服务程序如下: ORG 0000H AJMP INITZ ;转主程序 NOP ORG 001BH ;T1中断入口 MOV TL1, #18H ;中断服务程序送定时初值 MOV TH1,#0E0H
CPL P1.0 ;R1.0取反 RETI ;中断返回 ORG 0052H INITZ: MOV SP,#15H ;建立堆栈指针 MOV TMOD,#00H ;设置T1工作方式 MOV TL1,#18H ;置T1初值
MOV TH1, #0E0H SETB EA ;CPU开中断 SETB ET1 ;允许T1中断 SETB TR1 ;启动T1 AD1:MOV A,#00H AJMP AD1
[例6.2] 单片机晶振fosc=12 MHZ,利用定时器T0、T1产生周期为200 ms的方波,并由P1.0端输出。 方法1:由要求可知,只要使P1.0每隔100 ms取反一次即得周期为200 ms的方波信号。这样就需要一个100 ms的定时器。
当fosc=12 MHZ时,T0(或T1)在工作方式1下的最大定时时间为65 当fosc=12 MHZ时,T0(或T1)在工作方式1下的最大定时时间为65.536 ms,所以一个定时器不能满足需要,采用T0、T1各定时50 ms,顺序定时的方法可达到100 ms的要求,因而我们选T0、T1为定时器模式,工作在方式1下,启/停控制由TR0、TR1完成。GATE=0,这样TMOD的控制字为11H。对应50 ms计数初值X为 即TL0=TL1=0B0H,TH0=TH1=3CH。
T0、T1顺序定时可采用中断方法实现,也可采用查询方式实现,这里假定CPU不做其它工作,采用查询法编写程序如下: ORG 0052H STI:MOV TMOD,#11H ;设置T0、T1为定时器,方式1工作 AD1:MOV TL0,#0B0H ;送T0初值 MOV TH0,#3CH
SETB TR0 ;启动T0进行50 ms定时 AD2: JBC TF0,AD3 ;查询TF0是否溢出 SJMP AD2 AD3: CLR TR0 ;停止T0定时 CLR TF0 MOV TL1,#0B0H ;送T1定时初值(50 ms) MOV TH1,#3CH
SETB TR1 ;启动T1 AD4:JBC TF1,AD5 STMP AD4 AD5: CLR TR1 ;停止T1 CLR TF1 ;清溢出标志 CPL P1.0 ; P1.0取反 AJMP AD1
方法2:用一个定时器T0(或T1),通过软件控制完成。即将定时器T0定时50 ms,定时器溢出两次,P1.0被取反一次。 ORG 0052H MOV R7, #02H STI: MOV TM0D,#01H ;设置T0、T1为定时器,方式1工作 AD1: MOV TL0,#0B0H ;送T0初值 MOV TH0,#3CH
SETB TR0 ;启动T0进行50 ms定时 AD2: JBC TF0,AD3 ;查询TF0是否溢出 SJMP AD2 AD3:DJNZ R7,AD1 CLR TR0 ;停止T0定时 CPL P1.0 ;P1.0取反 MOV R7,#02H AJMP AD1
[例6.3] 单片机晶振fosc=12 MHZ,利用定时器/计数器测量某一外部脉冲信号频率,要求连续测量五次,取其平均值作为实测值。 主程序及中断服务程序如下: ORG 0000H AJMP MAINT ORG 000BH AJMP INTZ1 ORG 0100H MAINT: MOV SP,#15H
MOV TMOD,#16H MOV TH0,#0F5H MOV TL0,#0F5H MOV R2, #05H MOV R1, #20H SETB EA SETB ET0 ORL TCON,#50H ;启动T0,T1
AD1: MOV A, R2 JNZ AD2 计算频率值并输出显示 AD2: STMP AD1 ORG 0052H INTZ1: ANL TCON,#0AFH ;停止T0,T1
MOV @R1, TL1 INC R1 MOV @R1,TH1 MOV TL1,#00H MOV TH1,#00H DJNZ R2, L1 RETI L1: ORL TCON,#50H
[例6. 4] 单片机晶振fosc=6 MHz,设定时器T0工作在方式3,利用TL0和TH0两个独立的定时器在P1 [例6.4] 单片机晶振fosc=6 MHz,设定时器T0工作在方式3,利用TL0和TH0两个独立的定时器在P1.0端产生一个占空比为200 μs/400 μs的矩形脉冲波。 根据题意,让TL0和TH0分别定时200 μs和400 μs,采用中断方式交替启动TL0和TH0定时,并对P1.0端交替取反就可实现题中要求。
因fosc=6 MHz,则200 μs定时初值为9CH,400 μs定时初值为38H。TH0的启/停由TR1控制,溢出标志为TF1。主程序和中断服务程序如下: ORG 0000H AJMP ZCXK1 ;转主程序 ORG 000BH AJMP ZD0 ;转TL0中断程序
ORG 001BH AJMP ZD1 ;转TH0中断程序 ORG 0100H ZCXK1: MOV SP,#70H ;置堆栈栈底 MOV TMOD,#03H ;设T0工作方式 MOV TL0,#9CH ;置TL0、TH0初值 MOV TH0,#38H CLR P1.0 ;P1.0 端清零 SETB ET0 ;开T0中断
SETB ET1 ;开T1中断 SETB EA ;开总中断 SETB TR1 ;启动TH0定时开始 DENG1: AJMP DENG1 ;等待中断 ZD0:SETB TR0 ;启动TL0定时 CLR TR1 ;关闭TH0定时 CPL P1.0 ;P1.0取反 MOV TH0,#38H ;重装TH0初值 RETI ;中断返回
ZD1:SETB TR1 ;启动TH0定时 CLR TR0 ;关闭TL0定时 CPL P1.0 ;P1.0取反 MOV TL0,#9CH ;重装TL0初值 RETI ;中断返回