单片机(c语言版)定时器计数器_第1页
单片机(c语言版)定时器计数器_第2页
单片机(c语言版)定时器计数器_第3页
单片机(c语言版)定时器计数器_第4页
单片机(c语言版)定时器计数器_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章AT89S51单片机的

定时器/计数器

内容概要:介绍AT89S51单片机片内定时器/计数器的结构与功能,两种工作模式和4种工作方式,以及与其相关的两个特殊功能寄存器TMOD和TCON各位的定义及其编程,最后介绍定时器/计数器的C51编程及应用实例。2021/5/916.1定时器/计数器的结构定时/计数器的实质是加1计数器(16位),由高8位THX(X=0或1)和低8位TLX两个寄存器组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。

外部脉冲2021/5/92图6-1AT89S51单片机的定时器/计数器结构框图2021/5/936.1.1工作方式控制寄存器TMODAT89S51定时器工作方式寄存器TMOD用于选择工作模式和工作方式,字节地址为89H,不能位寻址。8位分为两组,高4位控制T1,低4位控制T0。(1)GATE—门控位GATE=0时,仅由运行控制位TRx(x

=

0,1)来控制定时器运行GATE=1时,用外中断引脚INT0*(或INT1*)上的电平与运行控制位TRx共同控制定时器运行。图6-2寄存器TMOD格式2021/5/94(2)M1、M0—工作方式选择位M1、M0的4种编码,对应于4种工作方式的选择。(3)C/T*—计数器模式和定时器模式选择位C/T*=0,为定时器工作模式,对单片机的晶体振荡器12分频后的脉冲进行计数。C/T*=1,为计数器工作模式,计数器对外部输入引脚T0(P3.4)或T1(P3.5)的外部脉冲(负跳变)计数。2021/5/956.1.2定时器/计数器控制寄存器TCONTCON字节地址为88H,可位寻址,位地址为88H~8FH。(1)TF1、TF0—计数溢出标志位。当计数器计数溢出时,该位置“1”。使用查询方式时,应注意查询有效后,使用软件及时将该位清“0”。使用中断方式时,中断请求标志位在进入中断服务程序后由硬件自动清“0”。(2)TR1、TR0—计数运行控制位。TR1位(或TR0位)=1,启动定时器工作。TR1位(或TR0位)=0,停止定时器工作。该位可由软件置“1”或清“0”。图6-3TCON格式2021/5/966.2定时器/计数器的4种工作方式6.2.1方式0——M1M0=00方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。2021/5/97图6-4定时器/计数器方式0逻辑结构框图C/T*位决定定时器/计数器的两种工作模式(1)C/T*=0,T1(或T0)为定时器工作模式,把时钟振荡器12分频后的脉冲作为计数信号。(2)C/T*=1,T1(或T0)为计数器工作模式,计数脉冲为P3.4(或P3.5)引脚上的外部输入脉冲,当引脚上发生负跳变时,计数器加1。2021/5/98GATE位决定定时器的运行控制取决于TRx一个条件,还是取决于TRx和INTX*(x=0,1)引脚状态这两个条件。(1)GATE=0时,仅由TR0控制与门的开启。与门输出1时,控制开关接通,计数开始;(2)GATE=1时,由外中断引脚信号控制或门的输出,此时控制与门的开启由外中断引脚信号和TR0共同控制。当TR0=1时,外中断引脚信号引脚的高电平启动计数,外中断引脚信号引脚的低电平停止计数。这种方式常用来测量外中断引脚上正脉冲的宽度。定时器模式时有:N=t/Tcy计数初值计算的公式为:2021/5/99

6.2.2方式1——M1M0=01方式1的计数位数是16位,由TLX作为低8位、THX作为高8位,组成了16位加1计数器。计数个数与计数初值的关系为:

2021/5/910

6.2.3方式2——M1M0=10方式2为自动重装初值的8位计数方式。

工作方式2特别适合于用作较精确的脉冲信号发生器。

计数个数与计数初值的关系为:

工作过程

2021/5/911

T0分成两个8位定时/计数器TL0和TH0;

TL0:既可计数也可定时,是一个8位定时/计数器。占用了T0

所有控制位:C/T,TR0,GATE,TF0和INT0、T0引脚;

TH0:只能作为定时器,因为T0已被TL0占用,TH0用T1的控制位:TR1、TF1;6.2.4方式3——M1M0=112021/5/91213T0在方式3时T1的工作模式T1只能工作在0、1、2方式,作为串行口的波特率发生器使用。因为T1的运行控制位TR1及计数溢出标志位TF1已被定时/计数器T0借用。当作为波特率发生器使用时,只需要设置好工作方式,便可自动运行。如要停止工作,只需送入一个把T1设置为方式3的方式控制字。因为定时/计数器T1不能在方式3下工作,因为T1处于方式3时相当于TR1

=

0,停止计数。2021/5/9136.3对外部输入的计数信号的要求当定时器/计数器工作在计数器模式时,计数脉冲来自外部输入引脚T0或T1。当输入信号产生由1至0的跳变(即负跳变)时,计数器值增1。由于确认一次负跳变花2个机器周期,即24个振荡周期,因此外部输入的计数脉冲的最高频率为系统振荡器频率的1/24。图6-12

对外部计数输入信号的要求例如,选用6MHz频率的晶体,允许输入的脉冲频率最高为250kHz。如果选用12MHz频率的晶体,则可输入最高频率为500kHz的外部脉冲。2021/5/914156.3对外部输入的计数信号的要求当定时器/计数器工作在计数器模式时,计数脉冲来自外部输入引脚T0或T1。当输入信号产生由1至0的跳变(即负跳变)时,计数器值增1。由于确认一次负跳变花2个机器周期,即24个振荡周期,因此外部输入计数脉冲的最高频率为系统振荡器频率的1/24。图6-12

对外部计数输入信号的要求例如,选用6MHz频率的晶体,允许输入的脉冲频率最高为250kHz。如果选用12MHz频率的晶体,则可输入最高频率为500kHz的外部脉冲。2021/5/915时间常数的计算时间常数:定时器/计数器T0或T1的初始计数值,在T0或T1被启动后,每个机器周期使计数器中的计数值加1,计数器产生溢出后。定时时间:计数器溢出时间,时间常数越大,定时时间就越短;时间常数越小,定时时间就越长。时钟的频率越高,定时时间越短;时钟的频率越低,定时时间越长。2021/5/916设系统时钟的频率为fosc,计数器的初始值为N,定时器工作于方式1,则定时时间:

T=(216-N)×12/fosc(1)

如果定时器工作于方式2或方式3,定时时间为:

T=(28-N)×12/fosc(2)

当初始值N=0时,如果fosc=12MHZ,最大定时时间为:方式1为:Tmax=216×12/fosc=65536us=65.536ms

方式2、方式3为:Tmax=28×12/fosc=256us根据定时时间T,及公式(1)、(2)分别可以求出初值N为:方式1:

N=216-T×fosc/12(3)方式2、方式3:N=28-T×fosc/12(4)如果fosc=12MHZ,以上公式可简化为方式1:N=216-T

方式2、方式3:N=28-T2021/5/917

例如:系统的时钟频率是12MHz,在方式1下,如果希望定时器/计数器T0的定时时间T为10ms,则初值N=216-T=65536-10000=55536

如何将55536给两个8位寄存器TH0、TL0赋值呢?可将十进制数55536转换成四位十六进制数,将高2位送TH0,低2位送TL0。

更简单的方法是:对于16位计数器来讲,216等效为0,对于8位计数器,28等效为0,这样公式(3)、(4)可简化为N=-T,直接用下面两条语句就可以完成计数器初值的设置:

TH0=-10000/256;//取-N的高8位

TL0=-10000%256;//取-N的低8位

例如:设系统的时钟频率是12MHz,定时器工作于方式2,定时时间200us。根据前面分析,N=-T=-200,可直接用以下语句实现:

TH0=-200;TL0=-200;2021/5/918MCS-51单片机的定时器是可编程的,但在进行定时或计数之前要对程序进行初始化,具体步骤如下:(1)确定工作方式字:对TMOD寄存器正确赋值;(2)确定定时初值:计算初值,直接将初值写入寄存器的TH0、TL0或TH1、TL1; 初值计算:设计数器的最大值为M,则置入的初值X为: 计数方式:X=M-计数值 定时方式:由(M-X)T=定时值,得X=M-定时值/T T为计数周期,是单片机的机器周期。 (模式0-M为213,模式1-M为216,模式2和3-M为28)(3)根据需要,对IE置初值,开放定时器中断;(4)启动定时/计数器,对TCON寄存器中的TR0或TR1置位,置位以后,计数器即按规定的工作模式和初值进行计数或开始定时。6.4定时器/计数器的编程和应用2021/5/9196.4.1P1口外接的8只LED每0.5s闪亮一次。【例6-1】在AT89S51单片机的P1口上接有8只LED(电路见图4-7)。下面采用定时器T0的方式1的定时中断方式,使P1口外接的8只LED每0.5s闪亮一次。(1)设置TMOD寄存器方式1;计时工作模式;仅由TR0来控制;T1不使用。TMOD寄存器应初始化为0x01=00000001B2021/5/920(2)计算T0计数初值设定时时间5ms(即5000µs),设定时器T0的计数初值为X,假设晶振的频率为11.0592MHz,则定时时间为:定时时间=(216−X)

12/晶振频率则5000=(216

−X)

12/11.0592得:X=60928,转换成16进制后为:0xee00,其中0xee装入TH0,0x00装入TL0。(3)设置IE寄存器本例由于采用定时器T0中断,因此需将IE寄存器中的EA、ET0位置1。(4)启动和停止定时器T0将定时器控制寄存器TCON中的TR0=1,则启动定时器T0;TR0=0,则停止定时器T0定时。2021/5/921#include<reg51.h>Chari=100;/*给变量i赋初值,定时0.5S,每次定时中断5MS,需要中断100次*/voidmain(){ TMOD=0x01; /*设置定时器T0为方式1*/ TH0=0xee; /*向TH0写入初值的高8位*/ TL0=0x00; /*向TL0写入初值的低8位*/ P1=0x00; /*P1口8只LED点亮*/ EA=1; /*总中断允许*/ ET0=1; /*定时器T0中断允许*/ TR0=1; /*启动定时器T0*/ while(1); /*无穷循环,等待定时中断*/}2021/5/922/*以下为定时器T0的中断服务程序*/voidT0_int(void)interrupt1

{ TH0=0xee;/*给T0装入16位初值,计4608个数后,T0溢出 TL0=0x00; i--;/*循环次数减1*/ if(i<=0) { P1=~P1; /*P1口按位取反*/ i=100; /*重新设置循环次数*/ }}2021/5/923

[案例2]如图所示,P0口接8只发光二极管,编程使发光管轮流点亮,点亮时间为500ms,要求使用定时器T0来控制,设晶振为12MHz。2021/5/924

设计思想

我们可将P0口的初值设置为0xFE,对应于发光管D1亮,每隔500ms将P0的值循环左移一位,这一周期性的定时作业用T0来完成。当时钟频率为12MHZ时,在定时器的4种工作方式中,方式1的最大溢出时间最长,但即使在方式1,最大的溢出时间也只有65.536ms,所以我们不能在每次中断时都执行上述移位操作。可以这样处理:将定时器T0的溢出时间设定为50ms,累计满10次中断正好500ms,才允许程序执行1次移位动作。2021/5/925

主函数ucharcount=0;//50ms定时中断次数计数器voidmain(void){led=0xfe;TMOD=0x01;//T0工作于方式1TH0=-50000/256;//定时时间为50msTL0=-50000%256;ET0=1;//允许T0中断

TR0=1;//启动T0定时

EA=1;//CPU开中断

while(1);}2021/5/926voidtime0(void)interrupt1{TH0=-50000/256;TL0=-50000%256;count++;if(count==10){count=0;led=_crol_(led,1);P0=led;}}定时器T0中断服务程序重新装入时间常数每中断一次,计数器加110次中断为0.5秒满10次变量led左移1位送P0口2021/5/9276.4.2计数器的应用【例6-2】

采用定时器T1的方式1的中断计数方式,如图6-13所示,计数输入引脚T1(P3.5)上外接开关K1,作为计数信号输入。按4次K1后,P1口的8只LED闪烁不停。(1)设置TMOD寄存器T1工作在方式1,应使TMOD的M1、M0=01;设置计数器工作模式C/T*=1;对T0的运行控制仅由TR0来控制,应使GATE0=0。定时器T0不使用,各相关位均设为0。所以,TMOD寄存器应初始化为0x50。图6-132021/5/928(2)计算T1计数初值由于每按4次K1,计数一次,因此计数器的初值为65536-4=65532,将其转换成16进制后为:0xfffc,因此,TH0=0xff,TL0=0xfc。(3)设置IE寄存器本例由于采用定时器T1中断,因此需将IE寄存器中的EA、ET1位置1。(4)启动和停止定时器T1将定时器控制寄存器TCON中的TR1=1,则启动定时器T1计数;TR1=0,则停止定时器T1计数。参考程序如下:2021/5/929#include<reg51.h>/*定义延时函数Delay(),i是形式参数,不能赋初值*/voidDelay(unsignedinti){ unsignedintj; /*变量i由实际参数传入一个值,因此i不能赋初值*/ for(;i>0;i--) for(j=0;j<125;j++) {;} /*空函数*/}voidmain() /*主函数*/{ TMOD=0x50; /*设置定时器T1为方式1计数*/ TH0=0xff; /*向TH0写入初值的高8位*/2021/5/930 TL0=0xfc; /*向TL0写入初值低8位*/ EA=1; /*总中断允许*/ ET1=1; /*T1中断允许*/ TR1=1; /*启动T1*/ while(1); /*无穷循环,等待定时中断*/}/*以下为定时器T1的中断服务程序*/voidT1_int(void)interrupt3{ for(;;) /*无限循环*/ { P1=0xff; /*8位LED全灭*/ Delay(500); /*延时500ms*/ P1=0; /*8位LED全亮*/ Delay(500); /*延时500ms*/ }}2021/5/931[案例4]用定时器来控制数码管的动态显示。

用定时器控制数码管动态显示的方法:设定时器的定时时间为1ms,每次产生溢出中断,就根据位选变量bsel(主程序中将其初值设置为0xfe)送位选口,点亮一位数码管,并将bsel左移一位,为下一位的显示做好准备,4次定时中断分别完成4位数码管的显示,之后将bsel的值再次初始化为0xfe,准备下一轮显示。

因此这种显示方式由定时中断自动完成,无需在主程序中调用2021/5/932主程序ucharbsel,n;voidmain(void){n=0;bsel=0xfe;//首先显示数码管的最低位

TMOD=0x01;//T0工作于定时方式2TH0=-1000/256;//T0的定时时间为1000usTL0=-1000%256;ET0=1;//允许T0中断

TR0=1;//启动定时

EA=1;//开中断

while(1);}ucharcodesegtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x8c};uchardbuf[4]={4,3,2,1};

字符0~F的字形码表显示缓存,存放要显示字符2021/5/933voidtime0(void)interrupt1{TH0=-1000/256;TL0=-1000%256;P0=0xff;P2=bsel;P0=segtab[dbuf[n]];bsel=_crol_(bsel,1);n++; if(n==4) {n=0; bsel=0xfe; }}重新装入时间常数定时器T0中断服务程序熄灭数码管,防止上一位字符在当前位置显示出来。点亮当前位根据显示缓存查字段码准备显示下一位指向下一位要显示的数据如果四位已显示完,重新从最低位开始2021/5/9346.4.3扩展一个外部中断源方式2可自动重新装载初值。此方式可省去用户程序中重新装初值的指令。当某个定时器/计数器不使用时,可为AT89S51扩展一个负跳沿触发的外部中断源。

基本思想:把定时器溢出中断做成外部中断,然后把计数输入信号接到定时器的相应引脚上T0脚(或T1脚),并把定时器被设置为方式2(自动装入常数方式)计数工作模式,计数器TH0、TL0初值均为0FFH,并允许T0中断,总中断开放。当检测到T0脚(或T1脚)引脚电平发生负跳变时,计数器TF0(或TF1)溢出,这时将产生一个中断请求。【例6-3】扩展一个负跳沿触发的外部中断源,把定时器T0计数输入引脚作为外部中断请求信号的输入端。2021/5/935#include<reg51.h>voidmain(){……… TMOD=0x06; /*设置定时器T0为方式2计数*/ TH0=0xff; /*给T0装入初值*/ TL0=0xff;/*给T0装入初值*/ ET0=1; /*允许T0中断*/ EA=1; /*总中断开*/ TF0=0; /*T0中断溢出标志位清0*/ TR0=1 /*接通T0计数*/ while(1) /*无限循环等待*/}/*以下为定时器T0的中断服务程序*/voidT0_int(void)interrupt1using0{┉┉} /*外中断处理部分*/2021/5/9366.4.4P1.0上产生周期为2ms的方波【例6-4】系统时钟为12MHz,编程实现从P1.0引脚上输出一个周期为2ms的方波,如图6-14所示。基本思想:要在P1.0上产生周期为2ms的方波,定时器应产生1ms的周期性的定时,定时对P1.0求反。选择定时器T0,方式1定时,采用中断方式,GATE不起作用。图6-14

定时器控制P1.0输出一个周期为2ms的方波2021/5/937计算T0的初值计算:设T0的初值为X,则

(216

X)

1

10−6

=

1

10−3=

65536−X

=1000则初值为:65536−1000=64536,因此TH0=(65536

−1000)

/256,TL0=(65536

−1000)

%256。参考程序如下:2021/5/938#include<reg51.h>sbitP1_0=P1^0;voidmain(void){ TMOD=0x01; /*设置定时器T0为方式2计数*/ P1_0=0; TH0=(65536

−1000)

/256; /*给T0装入初值*/ TL0=(65536

−1000)

%256; /*给T0装入初值*/ ET0=1; /*允许T0中断*/ EA=1; /*总中断开*/ TR0=1 /*接通T0计数*/ do{} while(1); /*无限循环等待*/}voidT0_int(void)interrupt1using1{ P1_0=!P1_0; TH0=(65536

−1000)

/256; TL0=(65536

−1000)

%256;}2021/5/9396.4.5P1.1上产生周期为1s的方波【例6-5】假设系统时钟为12MHz,编程实现从P1.1引脚上输出一个周期为1s的方波。基本思想:要在P1.0上产生周期为1s的方波,定时器应产生500ms的周期性定时,定时到则对P1.0求反。由于定时时间较长,用定时器不能直接实现,直接定时时间最长的就是方式1,仅为65ms(系统时钟12MHz)多一点。

实现:T0定为10ms定时,每10ms对P1.0求反一次,P1.0输出的脉冲加到定时器T1的计数输入脚P3.5(T1脚),作为计数输入,定时500ms需计数50次。T1设为方式2计数,初值X为:28−X=50,则X=206,2021/5/940所以TH1=TL1=206。T0设为方式1定时,则控制字为61H。定时器T0和T1均采用中断方式工作。参考程序如下:#include<reg51.h>sbitP1_0=P1^0;sbitP1_1=P1^1;voidmain(void){TMOD=0x61; /*设置定时器T0为方式1定时,T1为方式2计数*/P1_0=0;TH0=(65536

−10000)

/256; /*给T0装初值*/TL0=(65536

−10000)

%256;TH1=206; /*给T1装初值*/TL1=206;2021/5/941EA=1; /*总中断开*/ET0=1; /*允许T0中断*/ET1=1; /*允许T1中断*/TR0=1;TR1=1;while(1); }voidT0_int(void)interrupt1{ TH0=(65536

−1000)

/256;TL0=(65536

−1000)

%256;P1_0=!P1_0;}voidT1_int(void)interrupt3{P1_1=!P1_1; }; /*P1.1脚产生1s的方波*/。2021/5/9426.4.6T1控制发出1KHz的音频信号【例6-6】

利用定时器T1的中断来控制蜂鸣器发出1KHz的音频信号,电路图见图6-15。假设系统时钟为11.0592MHz,则每个脉冲的周期为12/11.0592=1.085µs。1KHz的音频信号周期为1ms,因此要计数的脉冲数为1000/1.085=921次。所以T1的初值:

TH1=(65536

−921)

/256;TL1=(65536

−921)

%256参考程序如下:#include<reg51.h>sbitsound=P1^7;2021/5/943

voidmain(void) { EA=1; /*总中断开*/ ET1=1; /*

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论