单片机定时器-单片机定时器、中断试验

一 : 单片机定时器、中断试验

我们在学单片机时我们第一个例程就是灯的闪烁,那是用延时程序做的,现在回想起来,这样做不很恰当,为什么呢?我们的主程序做了灯的闪烁,就不能再干其它的事了,难道单片机只能这样工作吗?当然不是,我们能用定时器来实现灯的闪烁的功能。[www.loach.net.cn]

例1:查询方式

ORG 0000H

AJMP START

ORG 30H

START:

MOV P1,#0FFH ;关所 灯

MOV TMOD,#00000001B ;定时/计数器0工作于方式1

MOV TH0,#15H

MOV TL0,#0A0H ;即数5536

SETB TR0 ;定时/计数器0开始运行

LOOP:JBC TF0,NEXT ;如果TF0等于1,则清TF0并转NEXT处

AJMP LOOP ;不然跳转到LOOP处运行

NEXT:CPL P1.0

MOV TH0,#15H

MOV TL0,#9FH;重置定时/计数器的初值

AJMP LOOP

END AJMP LOOP

END

键入程序,看到了什么?灯在闪烁了,这可是用定时器做的,不再是主程序的循环了。简单地分析一下程序,为什么用JBC呢?TF0是定时/计数器0的溢出标记位,当定时器产生溢出后,该位由0变1,所以查询该位就可知宇时时间是否已到。该位为1后,要用软件将标记位清0,以便下一次定时是间到时该位由0变1,所以用了JBC指令,该指位在判1转移的同时,还将该位清0。

以上程序是能实现灯的闪烁了,可是主程序除了让灯闪烁外,还是不能做其他的事啊!不,不对,我们能在LOOP:……和AJMP LOOP指令之间插入一些指令来做其他的事情,只要保证执行这些指令的时间少于定时时间就行了。那我们在用软件延时程序的时候不是也能用一些指令来替代DJNZ吗?是的,但是那就要求你精确计算所用指令的时间,然后再减去对应的DJNZ循环次数,很不方便,而现在只要求所用指令的时间少于定时时间就行,显然要求低了。当然,这样的办法还是不好,所以我们常用以下的办法来实现。

程序2:用中断实现

ORG 0000H ,http://www.51hei.com

AJMP START

ORG 000BH ;定时器0的中断向量地址

AJMP TIME0 ;跳转到真正的定时器程序处

ORG 30H

START:

MOV P1,#0FFH ;关所 灯

MOV TMOD,#00000001B ;定时/计数器0工作于方式1

MOV TH0,#15H

MOV TL0,#0A0H ;即数5536

SETB EA ;开总中断允许

SETB ET0 ;开定时/计数器0允许

SETB TR0 ;定时/计数器0开始运行

LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

TIME0: ;定时器0的中断处理程序

PUSH ACC

PUSH PSW ;将PSW和ACC推入堆栈保护

CPL P1.0

MOV TH0,#15H

MOV TL0,#0A0H ;重置定时常数

POP PSW

POP ACC

RETI

END

上面的例程中,定时时间一到,TF0由0变1,就会引发中断,CPU将自动转至000B处寻找程序并执行,由于留给定时器中断的空间只有8个字节,显然不足以写下所有有中断处理程序,所以在000B处安排一条跳转指令,转到实际处理中断的程序处,这样,中断程序能写在任意地方,也能写任意长度了。进入定时中断后,首先要保存当前的一些状态,程序中只演示了保存存ACC和PSW,实际工作中应该根据需要将可能会改变的单元的值都推入堆栈进行保护(本程序中实际不需保存护任何值,这里只作个演示)。

上面的两个单片机程序运行后,我们发现灯的闪烁非常快,根本分辨不出来,只是视觉上感到灯有些晃动而已,为什么呢?我们能计算一下,定时器中预置的数是5536,所以每计60000个脉冲就是定时时间到,这60000个脉冲的时间是多少呢?我们的晶体震荡器是12M,所以就是60000微秒,即60毫秒,因此速度是非常快的。如果我想实现一个1S的定时,该怎么办呢?在该晶体震荡器濒率下,最长的定时也就是65。536个毫秒啊!上面给出一个例程。

ORG 0000H

AJMP START

ORG 000BH ;定时器0的中断向量地址

AJMP TIME0 ;跳转到真正的定时器程序处

ORG 30H

START:

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开始运行

LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

TIME0: ;定时器0的中断处理程序

PUSH ACC

PUSH PSW ;将PSW和ACC推入堆栈保护

INC 30H

MOV A,30H

CJNE A,#20,T_RET ;30H单元中的值到了20了吗?

T_L1: CPL P1.0 ;到了,取反P10

MOV 30H,#0 ;清软件计数器

T_RET:

MOV TH0,#15H

MOV TL0,#9FH ;重置定时常数

POP PSW

POP ACC

RETI

END

先自己分析一下,看看是怎么实现的?这里采用了软件计数器的概念,思路是这样的,先用定时/计数器0做一个50毫秒的定时器,定时是间到了以后并不是立即取反P10,而是将软件计数器中的值加1,如果软件计数器计到了20,就取反P10,并清掉软件计数器中的值,不然直接返回,这样,就变成了20次定时中断才取反一次P10,因此定时时间就延长了成了20*50即1000毫秒了。

这个思路在工程中是非常有用的,有的时候我们需要若干个定时器,可51中总共才有2个,怎么办呢?其实,只要这几个定时的时间有一定的公约数,我们就能用软件定时器加以实现,如我要实现P10口所接灯按1S每次,而P11口所接灯按2S每次闪烁,怎么实现呢?对了我们用两个计数器,一个在它计到20时,取反P10,并清零,就如上面所示,另一个计到40取反P11,然后清0,不就行了吗?这部份的程序如下

ORG 0000H

AJMP START

ORG 000BH ;定时器0的中断向量地址

AJMP TIME0 ;跳转到真正的定时器程序处

ORG 30H

START:

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开始运行

LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

TIME0: ;定时器0的中断处理程序

PUSH ACC

PUSH PSW ;将PSW和ACC推入堆栈保护

INC 30H

INC 31H ;两个计数器都加1

MOV A,30H

CJNE A,#20,T_NEXT ;30H单元中的值到了20了吗?

T_L1: CPL P1.0 ;到了,取反P10

MOV 30H,#0 ;清软件计数器

T_NEXT:

MOV A,31H

CJNE A,#40,T_RET ;31h单元中的值到40了吗?

T_L2:

CPL P1.1

MOV 31H,#0 ;到了,取反P11,清计数器,返回

T_RET:

MOV TH0,#15H

MOV TL0,#9FH ;重置定时常数

POP PSW

POP ACC

RETI

END

二 : STC89C52单片机定时器2的使用

52单片机有3个定时器,T2是一个16位自动重载的,像T0和T1的方式2一样,只不过它是16位重载,如果作为计数器或定时用,中断用的是5,就是interrupt 5,T2的引脚是P1.0口。P1.0作为I/O口用了以后T2计数是不行了,不过定时或是作为串口时钟还是可以的。???? T2CON(T2的控制寄存器),字节地址0C8H:

0CFH 0CEH 0CDH 0CCH 0CBH 0CAH 0C9H 0C8H TF2 EXF2 RCLK TCLK EXEN2 TR2 C/T2 CP/RT2 各位的定义如下:

TF2:定时/计数器2溢出标志,T2溢出时置位,并申请中断。只能用软件清除,

但T2作为波特率发生器使用的时候,(即RCLK=1或TCLK=1),T2溢出时不对TF2置位。

EXF2:当EXEN2=1时,且T2EX引脚(P1.0)出现负跳变而造成T2的捕获或重装

的时候,EXF2置位并申请中断。EXF2也是只能通过软件来清除的。 RCLK:串行接收时钟标志,只能通过软件的置位或清除;用来选择T1(RCLK=0)

还是T2(RCLK=1)来作为串行接收的波特率产生器

TCLK:串行发送时钟标志,只能通过软件的置位或清除;用来选择T1(TCLK=0)

还是T2(TCLK=1)来作为串行发送的波特率产生器

EXEN2:T2的外部允许标志,只能通过软件的置位或清除;EXEN2=0:禁止外部

时钟触发T2;EXEN2=1:当T2未用作串行波特率发生器时,允许外部时钟触发T2,当T2EX引脚输入一个负跳变的时候,将引起T2的捕获或重装,并置位EXF2,申请中断。

TR2:T2的启动控制标志;TR2=0:停止T2;TR2=1:启动T2

C/T2:T2的定时方式或计数方式选择位。只能通过软件的置位或清除;C/T2=0:

选择T2为定时器方式;C/T2=1:选择T2为计数器方式,下降沿触发。 CP/RT2:捕获/重装载标志,只能通过软件的置位或清除。CP/RT2=0时,选择重装载方式,这时若T2溢出(EXEN2=0时)或者T2EX引脚(P1.0)出现负跳变

(EXEN2=1时),将会引起T2重装载;CP/RT2=1时,选择捕获方式,这时若T2EX引脚(P1.0)出现负跳变(EXEN2=1时),将会引起T2捕获操作。但是如果RCLK=1或TCLK=1时,CP/RT2控制位不起作用的,被强制工作于定时器溢出自动重装载模式。

对应郭天祥老师的52单片机板子!

/***********************************

程序编著院校 南昌航空大学

晶振 11.0592MHZ

T2CON(0XC8)的说明 定时器2可以产生两个中断TF2和EXF2,这两个中断通过逻辑或共享一个端口

定时器2溢出时 TF2置位 如果定时器工作在重装模式 RCAP2H和RCAP2L的值会自动装入TH2和TL2 TR2启动

TF2和TL2必须软件清零

T2MOD 必须定义sfr T2MOD= 0xC9;

扩展 RCLK TCLK其中一个为高电平 定时器2做波特率发生器

***********************************/

#include<reg52.h>

#include<intrins.h> // _nop_();

#define uchar unsigned char

#define uint unsigned int

sfr T2MOD = 0xC9;

sbit dula=P2^6;

sbit wela=P2^7;

sbit led=P1^7;

uchar timer2_ctr,num;

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, //数码管编码

0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //11.0592MHZ延时函数

void delay(uint ms)

{

uint x;

while(ms--)

{

for(x=125;x>0;x--);

}

}

//初始化主函数

void init()

{

dula=wela=0; //关闭数码管显示

RCAP2H=(0XFFFF-50000)/256;

RCAP2L=(0XFFFF-50000)%256;

//TH2=RCAP2H; //会自动重装 //TL2=RCAP2L;

T2CON=0;

T2MOD=0;

IE=0XA0; //开总中断和定时器2中断 TR2=1; //启动

}

void display(uchar num)

{

uchar gw,sw,bw;

bw=num/100;

sw=num%100/10;

gw=num%10;

P0=0xfe;

wela=1;

_nop_();_nop_();

wela=0;

P0=table[bw];

dula=1;

_nop_();_nop_();

dula=0;

delay(3);

P0=0xfd;

wela=1;

_nop_();_nop_();

wela=0;

P0=table[sw];

dula=1;

_nop_();_nop_();

dula=0;

delay(3);

P0=0xfb;

wela=1;

_nop_();_nop_();

wela=0;

P0=table[gw];

dula=1;

_nop_();_nop_();

dula=0;

delay(3); //显示个 十 百

}

void main()

{

init();

while(1)

{

display(num);

}

}

void timer2() interrupt 5

{

TF2=0; //注意!定时器2必须由软件对溢出标志位清零,硬件不能清零,这里与定时器0和定时器1不同!!!

timer2_ctr++;

if(timer2_ctr>=20) //定时50ms×20=1000ms即1秒钟,这里模拟一个60秒秒表

{

timer2_ctr=0;

led=~led;

num++;

if(num>=256)

{

num=0;

}

}

}

现象是:数码管显示0-256,

程序很简单!朋友们可以自己试试!

不明白问我739141300!

祝你学成!

三 : STC89C52单片机定时器2的使用

52单片机有3个定时器,T2是一个16位自动重载的,像T0和T1的方式2一样,只不过它是16位重载,如果作为计数器或定时用,中断用的是5,就是interrupt 5,T2的引脚是P1.0口。[www.loach.net.cn]P1.0作为I/O口用了以后T2计数是不行了,不过定时或是作为串口时钟还是可以的。???? T2CON(T2的控制寄存器),字节地址0C8H:

0CFH 0CEH 0CDH 0CCH 0CBH 0CAH 0C9H 0C8H TF2 EXF2 RCLK TCLK EXEN2 TR2 C/T2 CP/RT2 各位的定义如下:

TF2:定时/计数器2溢出标志,T2溢出时置位,并申请中断。只能用软件清除,

但T2作为波特率发生器使用的时候,(即RCLK=1或TCLK=1),T2溢出时不对TF2置位。

EXF2:当EXEN2=1时,且T2EX引脚(P1.0)出现负跳变而造成T2的捕获或重装

的时候,EXF2置位并申请中断。EXF2也是只能通过软件来清除的。 RCLK:串行接收时钟标志,只能通过软件的置位或清除;用来选择T1(RCLK=0)

还是T2(RCLK=1)来作为串行接收的波特率产生器

TCLK:串行发送时钟标志,只能通过软件的置位或清除;用来选择T1(TCLK=0)

还是T2(TCLK=1)来作为串行发送的波特率产生器

EXEN2:T2的外部允许标志,只能通过软件的置位或清除;EXEN2=0:禁止外部

时钟触发T2;EXEN2=1:当T2未用作串行波特率发生器时,允许外部时钟触发T2,当T2EX引脚输入一个负跳变的时候,将引起T2的捕获或重装,并置位EXF2,申请中断。

TR2:T2的启动控制标志;TR2=0:停止T2;TR2=1:启动T2

C/T2:T2的定时方式或计数方式选择位。只能通过软件的置位或清除;C/T2=0:

选择T2为定时器方式;C/T2=1:选择T2为计数器方式,下降沿触发。 CP/RT2:捕获/重装载标志,只能通过软件的置位或清除。CP/RT2=0时,选择重装载方式,这时若T2溢出(EXEN2=0时)或者T2EX引脚(P1.0)出现负跳变

定时器2 STC89C52单片机定时器2的使用

(EXEN2=1时),将会引起T2重装载;CP/RT2=1时,选择捕获方式,这时若T2EX引脚(P1.0)出现负跳变(EXEN2=1时),将会引起T2捕获操作。[www.loach.net.cn)但是如果RCLK=1或TCLK=1时,CP/RT2控制位不起作用的,被强制工作于定时器溢出自动重装载模式。

对应郭天祥老师的52单片机板子!

/***********************************

程序编著院校 南昌航空大学

晶振 11.0592MHZ

T2CON(0XC8)的说明 定时器2可以产生两个中断TF2和EXF2,这两个中断通过逻辑或共享一个端口

定时器2溢出时 TF2置位 如果定时器工作在重装模式 RCAP2H和RCAP2L的值会自动装入TH2和TL2 TR2启动

TF2和TL2必须软件清零

T2MOD 必须定义sfr T2MOD= 0xC9;

扩展 RCLK TCLK其中一个为高电平 定时器2做波特率发生器

***********************************/

#include<reg52.h>

#include<intrins.h> // _nop_();

#define uchar unsigned char

#define uint unsigned int

sfr T2MOD = 0xC9;

sbit dula=P2^6;

sbit wela=P2^7;

sbit led=P1^7;

uchar timer2_ctr,num;

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, //数码管编码

0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //11.0592MHZ延时函数

void delay(uint ms)

{

uint x;

while(ms--)

{

for(x=125;x>0;x--);

}

}

//初始化主函数

void init()

{

dula=wela=0; //关闭数码管显示

定时器2 STC89C52单片机定时器2的使用

RCAP2H=(0XFFFF-50000)/256;

RCAP2L=(0XFFFF-50000)%256;

//TH2=RCAP2H; //会自动重装 //TL2=RCAP2L;

T2CON=0;

T2MOD=0;

IE=0XA0; //开总中断和定时器2中断 TR2=1; //启动

}

void display(uchar num)

{

uchar gw,sw,bw;

bw=num/100;

sw=num%100/10;

gw=num%10;

P0=0xfe;

wela=1;

_nop_();_nop_();

wela=0;

P0=table[bw];

dula=1;

_nop_();_nop_();

dula=0;

delay(3);

P0=0xfd;

wela=1;

_nop_();_nop_();

wela=0;

P0=table[sw];

dula=1;

_nop_();_nop_();

dula=0;

delay(3);

P0=0xfb;

wela=1;

_nop_();_nop_();

wela=0;

P0=table[gw];

dula=1;

_nop_();_nop_();

dula=0;

定时器2 STC89C52单片机定时器2的使用

delay(3); //显示个 十 百

}

void main()

{

init();

while(1)

{

display(num);

}

}

void timer2() interrupt 5

{

TF2=0; //注意!定时器2必须由软件对溢出标志位清零,硬件不能清零,这里与定时器0和定时器1不同!!!

timer2_ctr++;

if(timer2_ctr>=20) //定时50ms×20=1000ms即1秒钟,这里模拟一个60秒秒表

{

timer2_ctr=0;

led=~led;

num++;

if(num>=256)

{

num=0;

}

}

}

现象是:数码管显示0-256,

程序很简单!朋友们可以自己试试!

不明白问我739141300!

祝你学成!

扩展:stc89c52定时器 / stc89c52定时器2 / stc89c52有几个定时器

四 : 单片机定时器2使用

定时器T2

reg52.h没有T2MOD寄存器

regx55.h有T2MOD寄存器而且sbit已经定义

概述

定时器2是一个16位通用计数器,其具有两种操作模式:16位自动重载模式和16位捕获模式。(www.loach.net.cn)

如果预分频功能被禁止,定时器2工作时,16位通用加法计数器以12分频的周期脉冲计数,每个周期16位通用加法计数器加1或减1。

定时器2由T2MOD寄存器、T2CON存器、功能存器TH2、TL2、RC2H、RC2L等电路构成。

TH2、TL2构成16位通用计数器。

RC2H、RC2L作为16位寄存器,在自动重载模式中RC2H、RC2L作为16位通用计数器的16位初值寄存器

捕捉模式中,当引脚T2EX上出现下降沿跳变时,把TH2、TL2的当前值捕捉到RC2H、RC2L中去。

  1.控制寄存器T2CON

T2CON(T2的控制寄存器),字节地址0C8H:

位地址   0CFH    0CEH   0CDH   0CCH   0CBH   0CAH   0C9H   0C8H

符  号   TF2     EXF2   RCLK   TCLK   EXEN2  TR2    C/T2   CP/RT2

各位的定义如下:

TF2:定时/计数器2溢出标志,T2溢出时置位,并申请中断。只能用软件清除,但T2作为波特率发生器使用的时候,(即RCLK=1或TCLK=1),T2溢出时不对TF2置位。

EXF2:当EXEN2=1时,且T2EX引脚(P1.0)出现负跳变而造成T2的捕获或重装的时候,EXF2置位并申请中断。EXF2也是只能通过软件来清除的。

RCLK:串行接收时钟标志,只能通过软件的置位或清除;用来选择T1(RCLK=0)还是T2(RCLK=1)来作为串行接收的波特率产生器

TCLK:串行发送时钟标志,只能通过软件的置位或清除;用来选择T1(TCLK=0)还是T2(TCLK=1)来作为串行发送的波特率产生器

EXEN2:T2的外部允许标志,只能通过软件的置位或清除;EXEN2=0:禁止外部时钟触发T2;EXEN2=1:当T2未用作串行波特率发生器时,允许外部时钟触发T2,当T2EX引脚输入一个负跳变的时候,将引起T2的捕获或重装,并置位EXF2,申请中断。

TR2:T2的启动控制标志;TR2=0:停止T2;TR2=1:启动T2

C/T2:T2的定时方式或计数方式选择位。只能通过软件的置位或清除;C/T2=0:选择T2为定时器方式;C/T2=1:选择T2为计数器方式,下降沿触发。

CP/RT2:捕获/重装载标志,只能通过软件的置位或清除。CP/RT2=0时,选择重装载方式,这时若T2溢出(EXEN2=0时)或者T2EX引脚(P1.0)出现负跳变(EXEN2=1时),将会引起T2重装载;CP/RT2=1时,选择捕获方式,这时若T2EX引脚(P1.0)出现负跳变(EXEN2=1时),将会引起T2捕获操作。但是如果RCLK=1或TCLK=1时,CP/RT2控制位不起作用的,被强制工作于定时器溢出自动重装载模式。

 2.模式寄存器T2MOD

寄存器T2MOD用来选择定时器2的工作模式。其组成如图8-8所示。

T2MOD(方式寄存器),字节地址0C9H:

D7     D6     D5     D4     D3     D2     D1     D0

--      --      --      --       --      --      T2OE   DCEN

T2OE:T2输出允许位,当T2OE=1的时候,允许时钟输出到P1.0。(仅对80C54/80C58有效)

DCEN:向下计数允许位。DCEN=1是允许T2向下计数,否则向上计数。

T2的数据寄存器TH2、TL2和T0、T1的用法一样,而捕获寄存器RCAP2H、RCAP2L只是在捕获方式下,产生捕获操作时自动保存TH2、TL2的值。

    以上是T2的相关寄存器的描述,其实用法上跟T0、T1是差不多的,只是功能增强了,设置的东西多了而已。

定时/计数器2其实用到最多的就是T2CON这个寄存器啦,它设定的定时和计数的方式。有三种工作方式,捕获,自动重装,波特率发生器

定时器T2工作模式

波特率发生器:

当T2CON(表3)中的TCLK 和RCLK 置位时,定时/计数器2 作为波特率发生器使用。如果定时/计数器2 作为发送器或接收器,其发送和接收的波特率可以是不同的,定时器1 用于其它功能,如图7 所示。若RCLK 和TCLK 置位,则定时器2工作于波特率发生器方式。

波特率发生器的方式与自动重装载方式相仿,在此方式下,TH2 翻转使定时器2 的寄存器用RCAP2H 和RCAP2L 中的16位数值重新装载,该数值由软件设置。

在方式1 和方式3 中,波特率由定时器2 的溢出速率根据下式确定:

方式1和3的波特率=定时器的溢出率/16

定时器既能工作于定时方式也能工作于计数方式,在大多数的应用中,是工作在定时方式(C/T2=0)。定时器2 作为波特率发生器时,与作为定时器的操作是不同的,通常作为定时器时,在每个机器周期(1/12 振荡频率)寄存器的值加1,而作为波特率发生器使用时,在每个状态时间(1/2 振荡频率)寄存器的值加1。波特率的计算公式如下:

方式1和3的波特率=振荡频率/{32*[65536-(RCP2H,RCP2L)]}式中(RCAP2H,RCAP2L)是RCAP2H和RCAP2L中的16 位无符号数。

定时器2 作为波特率发生器使用的电路如图7 所示。T2CON 中的RCLK 或TCLK=1 时,波特率工作方式才有效。在波特率发生器工作方式中,TH2 翻转不能使TF2 置位,故而不产生中断。但若EXEN2 置位,且T2EX 端产生由1 至0 的负跳变,则会使EXF2 置位,此时并不能将(RCAP2H,RCAP2L)的内容重新装入TH2 和TL2 中。所以,当定时器2 作为波特率发生器使用时,T2EX 可作为附加的外部中断源来使用。需要注意的是,当定时器2 工作于波特率器时,作为定时器运行(TR2=1)时,并不能访问TH2 和TL2。因为此时每个状态时间定时器都会加1,对其读写将得到一个不确定的数值。

然而,对RCAP2 则可读而不可写,因为写入操作将是重新装载,写入操作可能令写和/或重装载出错。在访问定时器2或RCAP2 寄存器之前,应将定时器关闭(清除TR2)。

产生11.0592MHz, 9600bps

void Inituart(void)//11.0592MHz,9600bps

{TH2=RCAP2H=0Xff;
 TL2=RCAP2L=0XDC;
 T2MOD=0;//reg52没有
T2CON=0X34;

}

2.自动重载模式

控制寄存器T2CON中的     置“0”时,定时器2被选择为自动重载模式。

该模式下,定时器2计数至溢出时,将寄存器RC2H、RC2L中的16位初始值重新装入定时器的TH2、TL2寄存器中,开始新一轮计数循环。

并置位寄存器T2CON的TF2位表示计数溢出,从而向CPU发送中断请求信号。

溢出标志TF2必须由程序清零。根据控制寄存器T2MOD中DCEN控制位的设置,自动重载模式可进一步分为两种类型。

1)禁止递增/递减计数模式

若DCEN = 0,则递增/递减计数选择被禁止,此时定时器只能递增计数。工作原理如图8-10所示。

定时器2寄存器:寄存器T2CON和T2MOD包含定时器2的控制位和状态位(如表2和表3所示),寄存器对RCAP2H和RCAP2L是定时器2的捕捉/自动重载寄存器。中断寄存器:各中断允许位在IE寄存器中,六个中断源的两个优先级也可在IE中设置。

若EXEN2 = 0,置位TR2定时器开始递增计数,计数至最大值FFFFH后溢出并置位TF2,同时将寄存器RC2中的16位重载值重新装入定时器寄存器。

重载值由软件预先设置。新一轮计数循环开始,定时器同上一轮计数循环一样,从重载值开始递增计数。

若EXEN2 = 1,置位TR2定时器开始递增计数至最大值FFFFH。计数溢出或输入引脚T2EX的负/正跳变(由寄存器T2MOD的位EDGESEL选择)均会引起16位重载,将寄存器RC2的内容重新装入定时器寄存器。

中断标志位:

若由溢出引起重载,溢出标志TF2置位。

若由引脚T2EX的负/正跳变引起重载,寄存器T2CON中的EXF2置位。

这两种情况均产生中断,定时器进入下一轮计数循环。EXF2标志和TF2一样必须由软件清零。

允许硬件启动时(T2RHEN=1)

T2EX第一个上升沿/下降沿触发TR2=1启动T2;

上升沿/下降沿的选择由T2REGS选择;

如果使能外部控制(EXEN2=1),引脚T2EX的边沿跳变完成两个任务:(由T2REGS选择上升沿/下降沿)

启动T2

EXF2置位

2)以递增或递减计数。

引脚T2EX的逻辑电平为1时

定时器2递增计数,因此定时器递增计数,计数至最大值FFFFH后溢出并置位TF2,RC2寄存器的16位重载值重新装入定时器寄存器。

引脚T2EX的逻辑电平为0时

定时器2递减计数。定时器递减计数并当THL2的值和寄存器RC2中的值相等时发生下溢。下溢后置位TF2,并将值FFFFH重新载入定时器寄存器THL2中

若允许硬件启动T2(当T2RHEN=1)时,根据T2EX输入的是上升沿/下降沿可将T2设置为递增、递减计数

T2由上升沿启动,T2只能工作于递增模式

T2由下降沿启动,T2只能工作于递减模式

定时250us产生2kHz方波

void Inittimer2 (void)//12MHz,2kHz

{TH2=RCAP2H=0Xff;
 TL2=RCAP2L=0XDC;
 T2MOD=0;//reg52没有

IE=0XA0;

T2CON=0X04;

}

void timer2(void) interrupt 5 using 2
{ TF2=0;
    P1_2=!P1_2;
}

main()
{ inittimer2();
 while(1);

}

3.捕获模式

控制寄存器T2CON中的     及EXEN2置位时,定时器进入16位捕获模式。

此模式下,递减计数功能必须禁止。16位计数器始终递增计数,计数至最大值FFFFH后溢出,TF2置位并将0000H重新载入定时器寄存器TH2、TL2中。

溢出后TF2置位,则定时器向CPU发送中断请求。

在引脚T2EX的下降沿/上升沿(由T2MOD.EDGESEL选择),将定时器寄存器(THL2)的值捕获到寄存器RC2中。如果在计数器加1时检测到捕获信号,计数器先加1然后执行捕获操作,从而确保总能捕获到定时计数器的最新值。执行完捕获操作,EXF2置位、可用来产生中断请求

若允许硬件启动T2(当T2RHEN=1)时,引脚T2EX输入的第一个下降沿/上升沿(由T2MOD.EDGESEL选择)启动T2

在启动T2的同时,置位EXF2。

在下一个下降沿/上升沿到来时,将进行捕获操

引脚号第二功能 P1.0 T2(定时器/计数器T2的外部计数输入),时钟输出

 P1.1 T2EX(定时器/计数器T2的捕捉/重载触发信号和方向控制)

五 : 单片机的定时器问题?单片机的定时器,初始化做好之后就开始走了然后

单片机的定时器问题?

的定时器,初始化做好之后就开始走了然后进中断了吗?


不是,单片机每隔一个机器周期去检验有没有中断信号产生,如果有就进入中断程序

希望能给你帮助。

下页更精彩: 1 2 3
上一篇: 清香木的养殖方法-龙须木的养殖方法 下一篇: 智能手机出货量排名-谷歌收购大量智能手表域名 将推新品Tacto?

优秀文章