例5-6:利用T0方式0产生1ms的定时,在P1.0引脚上输出周期为2ms的方波。设单片机晶振频率fOSC=12MHz。
解:要在P1.0输出周期为2ms的方波,需要使P1.0每隔1ms取反一次输出即可。
(1)确定工作方式字
T0为方式0,定时工作状态,GATE=0,不受控制,T1不用全部取0值,故TMOD=00H。
(2)计算1ms定时初值N
方式0为13位计数方式(见表5-7),取M=213。
机器周期T=(1/fOSC)×12=[1/(12×106)]×12μs=1μs。
计算初值N=213-1×103/T=213-1×103/1=8192-1000=(7192)D=(1110000011000)B
表5-7 工作方式的初值
TH0=E0H,TL0=18H,故TH0初值为E0H,TL0初值为18H。
(3)采用查询TF0的状态来控制P1.0输出
其程序如下:
MOV TMOD,#00H;置T0为方式0
MOV TL0,#18H;送计数初值
MOV TH0,#0E0H
SETB TR0;启动T0
LOOP:JBC TF0,NEXT;查询定时时间到,转NEXT,同时清TF0
SJMP LOOP
NEXT:MOV TL0,#18H;重赋计数初值
MOV TH0,#0E0H
CPL P1.0;输出取反
SJMP LOOP;重复循环
END
例5-7:方式0、1的应用
设单片机系统晶振频率fOSC=6MHz,要在P1.0引脚上输出1个周期为2ms、占空比为50%的方波信号,如图5-8所示。
图5-8 P1.0引脚上输出方波
解:(1)计算初值
单片机工作在12T模式,有
机器周期T=(1/fOSC)×12=[1/(6×106)]×12μs=2μs=2×10-6s,T0工作方式0。
定时1ms计数次数为
选择工作方式0,则N=13。定时计数初值:(x)补=213-500=7692=1E0CH;x=(1111000001100)B;则TH0=F0H,TL0=0CH。
(2)初始化程序
工作方式控制字(TMOD)的设置;TMOD=00H,定时方式0。计数初值装入THx、TLx;TH0=F0H,TL0=0CH。中断允许位ET0=1、EA=1,使主机开放中断;启/停位TRx设置TR0=1。
方法1:中断方式
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0P
ORG 0100H
MOV TMOD,#00H;T0为定时、方式0、门控GATE0=0
MOV TL0,#0CH;装载计数初值
MOV TH0,#0F0H
SETB TR0;启动定时器0计数
SETB ET0;允许定时器0中断
SETB EA;允许CPU中断
HERE:AJMP HERE;踏步等待
/**********中断服务子程序**********/
T0P:MOV TL0,#0CH;重装载计数初值
MOV TH0,#0FEH
CPL P1.0;P1.0输出求反
RETI
END
方法2:软件查询
计算初值:机器周期为2μs=2×10-6s,T0工作方式1。(x)补=216—=65536-500=65036=FEOCH,则THO=OFEH,TLO=OCH。
程序段如下:
ORG 0000H
START:MOV SP,#60H;设置堆栈区
MOV TMOD,#01H;T0定时方式1门控GATE0=0
SETB TR0;启动定时器0计数
L1:MOV TH0,#0FEH;装载计数初值
MOV TL0,#0CH
LOOP1:JNB TF0,LOOP1;判计数溢出?没有,踏步等待
CLR TF0;溢出,清溢出标志位
CPL P1.0;P1.0输出求反
SJMP L1
END
图5-9 负跳变触发输出一个周期为1ms的方波
例5-8:方式2的应用
设单片机系统晶振频率fOSC=6MHz,将T0(P3.4)引脚上发生负跳变信号作为P1.0引脚产生方波的启动信号。要求P1.0脚上输出周期为1ms的方波,如图5-9所示。
解:1)T0方式2计数,计数初值:TH0=0FFH,TL0=0FFH。
T1方式2定时,定时初值:
2)程序如下:
ORG 0000H
LJMP MAIN;跳向主程序MAIN
ORG 000BH;T0的中断入口
LJMP T0XINT;T0中断服务程序
ORG 001BH;T1的中断入口
LJMP T1TIME;T1中断服务程序
ORG 0030H;主程序入口
MAIN:MOV SP,#60H;设堆栈区
MOV TMOD,#26H;T0方式2计数,T1方式2定时
MOV TL0,#0FFH;T0置初值,计1个脉冲
MOV TH0,#0FFH
SETB ET0;允许T0中断
MOV TL1,#06H;T1置初值
MOV TH1,#06H
SETB ET1;允许T1产生定时中断
SETB EA;总中断允许
SETB TR0;启动T0计数
HERE:AJMP HERE
/**********T0中断服务子程序**********/
T0XINT:CLR TR0;停止T0计数
SETB TR1;启动T1定时
RETI
/**********T1中断服务子程序**********/
T1TIME:CPL P1.0;P1.0取反
RETI
END
图5-10 定时器P1.0输出的方波信号
例5-9:方式3的应用
假设某单片机应用系统的2个外部中断源已被占用,设置定时器T1工作在方式0,作波特率发生器用,现要求增加1个外部中断源,并控制P1.0引脚输出1个频率5kHz(周期为200μs)的方波,晶振频率fOSC=12MHz,如图5-10所示。
解:T0工作于方式3。
1)初值计算:TL0计一个脉冲,TH0定时100μs。
定时初值:
则TH0=9CH,TL0=0FFH。
2)程序如下:
ORG 0000H
LJMP MAIN
ORG 000BH;TL0中断入口地址
LJMP TL0INT;跳向TL0中断服务子程序,
ORG 001BH;TH0占用T1的中断资源
LJMP TH0INT;跳向TH0中断服务子程序
ORG 0100H;主程序入口
MAIN:MOV TMOD,#07H;T0方式3,T1方式0定时
MOV TL0,#0FFH;设置TL0计数初值
MOV TH0,#9CH;设置TH0定时初值
SETB TR0;启动T0计数
MOV IE,#8AH;设置各中断允许,CPU允许
HERE:AJMP HERE;循环等待
TL0INT:MOV TL0,#0FFH;重装TL0计数初值
SETB TR1;启动TH0定时
RETI
TH0INT:MOV TH0,#9CH;重装TH0定时初值
CPL P1.0;P1.0输出求反
RETI
END
例5-10:采用定时/计数器0及其中断实现LED亮点由低位到高位的循环流动,每个亮点亮1s,fOSC=12MHz。
解:问题分析,定时时间到了以后并不进行亮点流动的操作,而是将中断溢出计数器中的内容加1,如果此计数器计到了20,就进行亮点流动的操作,并清除此计数器中的值;否则直接返回。如此一来,就变成了20次定时中断为1s的定时,因此定时时间就成了20×50ms即1000ms,即1s。
程序设计如下:
ORG 0000H
AJMP STAR
ORG 000BH;定时器0的中断向量地址
SJMP T0F;跳转到定时器程序处
STAR:MOV P1,#0FFH;关所有的灯
MOV 30H,#00H;软件计数器预清0
MOV TMOD,#00000001B;定时/计数器0工作于方式1
MOV TH0,#3CH;装入定时初值
MOV TL0,#0B0H;15536的十六进制
SETB EA;开总中断允许
SETB ET0;开定时/计数器0允许
SETB TR0;定时/计数器0开始运行
MOV P1,#0FEH
SJMP $
T0F:INC 30H;定时器0的中断处理程序
MOV A,30H
CJNE A,#20,T_RET;30H单元中的值到了20了吗?
MOV A,P1;到了,亮点流动
RL A
MOV P1,A
MOV 30H,#0;清软件计数器
T_RET:MOV TH0,#3CH
MOV TL0,#0B0H;重置定时常数
RETI
END
例5-11:已知fOSC=6MHz,检测T0引脚上的脉冲数,并将1s内的脉冲数保存在内RAM的30H及31H单元中(设1s内脉冲数≤65536个)。
解:问题分析,根据题意,可选定时/计数器0(T0)作为计数器,定时/计数器1(T1)作为定时器。因fOSC=6MHz,所以机器周期0=(12/fOSC)×106μs=2μs。因要求定时1s,故T1取工作方式1为宜。这时定时最大值约为131ms,取定时值为100ms来计算初值,定时中断10次,便可实现1s的定时。因1s内脉冲计数不大于65536个,故T0取工作方式1为宜,且T0不会溢出。所以,程序中不开T0计数中断。程序中使用工作寄存器R7,其初值R7=10,为定时中断的次数,递减10次后为0便是定时1s时间到。
1)计算定时初值:初值=216-100000μs/2μs=65536-50000=15536=3CB0H。
所以:TH1=3CH,TL1=B0H。
2)设置TMOD:无关位为0,所以TMOD=15H。
3)程序设计如下:
ORG 0000H
SJMP STAR;转主程序
ORG 001BH;T1中断入口地址
LJMP T1F;转T1中断服务程序(www.xing528.com)
ORG 0020H;主程序起始地址
STAR:MOV SP,#60H;置堆栈
MOV R7,#10;计时1s
MOV TMOD,#15H;置T0计数方式1,T1定时方式1
MOV TH0,#00H;置T0计数初值
MOV TL0,#00H
MOV TH1,#3CH;置T1定时初值
MOV TL1,#0B0H
SETB PT1;置T1为高优先级
MOV IE,#10001101B;T0、串行接口不开中,其余开中
SETB TR0;T0运行
SETB TR1;T1运行
MOV R7,#10;置100ms溢出计数初值
SJMP $;等待T1中断
T1F:MOV TH1,#3CH;重置T1定时初值
MOV TL1,#0B0H
DJNZ R7,RTN
CLR TR1
MOV 30H,TH0
MOV 31H,TL0
RTN:RETI
END;程序结束
例5-12:要求在P1.0引脚输出周期为400μs的方波。设fOSC=12MHz。使用T1,分别在方式0、方式1和方式2下的设计程序。
解:这是定时/计数器用于定时的例子。按要求输出周期为400μs的脉冲方波,即使P1.0状态(高电平或低电平)每200μs翻转一次。这样,问题变为200μs定时溢出时P1.0状态取反的问题。因fOSC=12MHz,所以机器周期=(12/fOSC)×106μs=1μs。
如图5-11和图5-12所示分别为程序的主程序流程图、定时200μs中断服务程序流程图。
图5-11 主程序流程图
图5-12 定时200μs中断服务程序流程图
1 工作方式0
1)计算定时初值:初值=213-200μs/1μs=8192-200=7992=1F38H。
1F38H=0001111100111000B=000 ;(TH1:8位,TL1:5位)
所以TH1=F9H,TL1=18H。
2)设置TMOD:无关位为0,所以TMOD=0。
3)程序设计如下:
ORG 0000H
LJMP STAR;转主程序
ORG 001BH;T1中断入口地址
AJMP T1F;转T1中断服务程序
ORG 0100H;主程序起始地址
STAR:MOV TMOD,#00000000B;置T1为定时器,工作方式0
MOV TH1,#0F9H;置T1定时初值
MOV TL1,#18H
MOV IP,#00001000B;置T1为高优先级
MOV IE,#0FFH;全部开中断
SETB TR1;T1运行
SJMP $;等待T1中断
ORG 0200H;中断服务程序起始地址
T1F:CPL P1.0;输出波形取反
MOV TH1,#0F9H;重装T1定时初值
MOV TL1,#18H
RETI;中断返回
END;程序结束
2 工作方式1
1)计算定时初值:216-200μs/1μs=65536-200=65336=FF38H,TH1=FFH,TL1=38H。
2)设置TMOD:无关位为0,所以TMOD=10H。
3)程序设计如下:
ORG 0000H
LJMP STAR;转主程序
ORG 001BH;T1中断入口地址
AJMP T1F;转T1中断服务程序
ORG 0100H;主程序起始地址
STAR:MOV TMOD,#00010000B;置T1为方式1
MOV TH1,#0FFH;置T1定时初值
MOV TL1,#38H;
MOV IP,#00001000B;置T1为高优先级
MOV IE,#0FFH;全部开中断
SETB TR1;T1运行
SJMP $;等待T1中断
ORG 0200H;中断服务程序起始地址
T1F:CPL P1.0;输出波形取反
MOV TH1,#0FFH;重装T1定时初值
MOV TL1,#38H
RETI;中断返回
END;程序结束
3 工作方式2
1)计算定时初值:28-200μs/1μs=256-200=56=38H,所以TH1=38H,TL1=38H。
2)设置TMOD:无关位为0,所以TMOD=20H。
3)程序设计如下:
ORG 0000H
LJMP STAR;转主程序
ORG 001BH;T1中断入口地址
LJMP T1F;转T1中断服务程序
ORG 0100H;主程序起始地址
STAR:MOV TMOD,#0010000B;置T1为方式2
MOV TH1,#038H;置T1定时初值
MOV TL1,#38H
MOV IP,#00001000B;置T1为高优先级
MOV IE,#0FFH;全部开中断
SETB TR1;T1运行
SJMP $;等待T1中断
ORG 0200H;中断服务程序起始地址
T1F:CPL P1.0;输出波形取反
RETI;中断返回
END;程序结束
从以上三种方式可以看到:方式0与方式1除定时初值及TMOD值不同外,其余相同。方式2与方式0、方式1相比,优点是定时初值不需重装。
图5-13 测引脚P3.3上正脉冲宽度
例5-13:脉冲宽度测试
门控GATE1使定时/计数器T1启动计数受控。当GATE1为1,TR1为1时,只有引脚输入高电平,T1才被允许计数,故可测引脚P3.3上正脉冲宽度(机器周期数),如图5-13所示。
解:门控为1,定时器启动计数受外部输入电平的影响,可测外部输入脉冲宽度。
被测脉冲输入引脚P3.3,T1为定时方式。当GATE=1时,若TR1=1,=1,计数开始;若TR1=0或INT1=0,计数停止。
1)建立被测脉冲:设置定时/计数器0定时、工作方式2,门控GATE0=0,定时溢出使P3.0引脚求反,从而输出周期为1ms方波作为被测脉冲,P3.0输出信号连接到P3.3引脚。
3)计数初值的计算:计算定时器0工作方式2。
定时/计数器1设置为定时工作方式1,计片内脉冲,从0开始计数,初值为0000H,即TH1=00H,TL1=00H。
T0计数初值为
4)程序如下:
方法1:查询方式的汇编程序
ORG 0000H
RESET:AJMP MAIN;复位入口转主程序
ORG 000BH
CPL P3.0
RETI
ORG 0030H;主程序入口
MAIN:MOV SP,#60H
MOV TMOD,#92H;T0方式2定时,T1为方式1定时,门控为1
MOV TL1,#00H
MOV TH1,#00H
MOV TL0,#06H
MOV TH0,#06H
SETB TR0
SETB ET0
SETB EA
LOOP0:JB P3.3,LOOP0;等待为低电平
SETB TR1;如为低电平,设置TR1=1
LOOP1:JNB P3.3,LOOP1;等待升高电平
LOOP2:JB P3.3,LOOP2;=1,启动T1计数
CLR TR1;INT1=0,停止T1计数
CLR TR0
MOV P2,TH1;T1计数值送显示器
MOV P1,TL1
AJMP LOOP0
END
执行以上程序,使引脚上出现的正脉冲宽度以机器周期数的形式显示在数码管上,TH0=00H,TL0=FBH,则脉冲宽度TW=FBH×2μs=502μs,理论值为500μs。
方法2:中断方式
从图5-13中可知,外部中断1引脚P3.3第1次下降沿信号,产生第1次中断触发,在中断服务程序中设置TR1=1,由于此时不能启动定时器1工作,当脉冲信号出现P3.3上升沿时,自动启动定时器1计数,而当脉冲信号出现P3.3第2次下降沿,即降为0,自动停止定时器1计数,则在中断服务程序中使TR1=0,从启动T1计数到停止T1计数所记录的计数值乘以机器周期值就是正脉冲的宽度。
ORG 0000H
RESET:AJMP MAIN;复位入口地址,转主程序
ORG 000BH
AJMP T0TIME
ORG 0013H
AJMP INT1INT
ORG 0030H;主程序入口地址
MAIN:MOV SP,#60H;设置堆栈指针
MOV TMOD,#92H;T1为方式1定时,GATE1=1,T0方式2定时
MOV TL1,#00H;设置T1定时初值
MOV TH1,#00H
MOV TL0,#06H;设置T0定时初值
MOV TH0,#06H
SETB TR0;启动T0计数
SETB ET0;允许T0中断
SETB IT1;设置外部中断1下降沿触发中断
SETB EX1;允许外部中断1的中断请求
SETB EA;允许CPU总中断
CLR 00H;设置中断标志,该位为0,中断1次;为1,中断2次
LOOP0:MOV P2,TH1;T1计数值送显示器
MOV P1,TL1
AJMP LOOP0
T0TIME:CPL P3.0;P3.0输出求反
RETI
INT1INT:JB 00H,INT12;第2次中断?是,转INT12
SETB TR1;第1次,启动定时器1计数
SETB 00H;建立中断标志
RETI
INT12:CLR TR1;第2次中断,禁止定时器计数
RETI
END
执行以上程序,使引脚上出现的正脉冲宽度以机器周期数的形式显示在数码管上,TH0=00H,TL0=F9H,则脉冲宽度为:TW=F9H×2μs=249×2μs=498μs,理论值为500μs。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。