这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 设计工具 » STC89C52定时器使用方法

共1条 1/1 1 跳转至

STC89C52定时器使用方法

高工
2013-10-25 15:27:23     打赏

定时器/计数器0 和定时器/计数器1 都可以在方式0、方式1、方式2 工作,而方式3 只有前者才能工作。

1. 方式 0

当TMOD 中M1、M0 都为0 时,T/C 工作在方式0。

方式0 为13 位的T/C,由TH 提供高8 位,TL 提供低5 位,注意TL 的高3 位是无效的,计数溢出值为2 的13 次方=8192,启动该计数器需要设置好计数初值。

当C/-- T该位为0 时,T/C 为定时器,振荡源12 分频的信号作为计数脉冲;当C/-- T该位为1 时,T/C为计数器,对外部脉冲输入端的T0 或T1 引脚进行脉冲计数。

计数脉冲能否加到计数器上,受启动信号的控制。当GATE=0 时,只要TR=1,则T/C 启动;当GATE=1时,启动信号受到TR 与INT 的双重控制。T/C 启动后立即加1 计数,当13 位计数满时,TH 向高位进位。此进位将中断溢出标志TF 置位即TF=1,产生中断请求,表示定时时间或计数次数到达。若T/C 开中断(ET=1)且CPU 开中断(EA=1),则当CPU 自动转向中断服务函数时,TF 自动清零,不需要人工软件清零。

2. 方式 1

当TMOD 中M1、M0 为0、1 时,T/C 工作在方式1。方式1 与方式0 基本相同,唯一不同的是方式0 是13 位计数方式,方式1 是16 位计数方式,TH 和TL 都同时提供8 位(方式0 时TL 只提供低5 位,高3 位无效),计数溢出值为2 的16 次方=65536。

3. 方式 2

当TMOD 中M1、M0 为1、0 时,T/C 工作在方式2。方式2 是8 位的可自动重装载的T/C,满计数值为2 的8 次方=256。在方式0 和方式1 中,当计数满后,若要进行下一次定时/计数,必须通过软件向TH 和TL 重新装载预置计数值。方式2 中TH 和TL 被当作两个8 位计数器。技术过程中,TH 寄存8 位初值并保持不变,由TL 进行8 位计数。计数溢出时,除产生溢出中断请求外,还自动将TH 中初值重装到TL,即重装载。除此之外,方式2 也同方式0。

4. 方式 3

方式3 只适合于T/C0。当T/C0 工作在方式3 时,TH0 和TL0 成为两个独立的计数器。这时,TL0可作定时器/计数器,占用T/C0 在TCON 和TMOD 寄存器中的控制位和标志位;而TH0 只能作定时器使用,占用T/C1 的资源TR1 和TF1。在这种情况下,T/C1 仍可用于方式0/1/2,当不能够使用中断方式。只有将T/C1 用作串行口的波特率方式器时,T/C0 才工作在方式3,以便增加一个定时器。

5. T/C2的工作方式

定时器/计数器2 包含一个16 位重载方式,T/C2 在计数溢出后,自动在瞬间重装载(像8 位自动重载方式2)。自动重载可由外部引脚T2EX 的负跳变开始,这样外部引脚用于产生和其他硬件计数器的同步信号。T/C2 可以看作看门狗或定时溢出的定时器。T/C2 还有捕获方式。把瞬时计数值传到另外的CPU 可读取的寄存器对(RCAP2H、RCAP2L)。

这样,在读的过程中,两个字节的计数值无波动的危险。对于快速变化的计数,比如计数值在读取高字节时是16FF时,到读取低字节时已变到1700,结果却得到1600。若16FF 瞬间捕获到另外的寄存器,则可以在CPU空闲的时候取到16 和FF。

#include stc.h //加载stc.h 头文件

unsigned char i=0; //声明变量i

void main(void) //主函数,程序是在这里运行的

{

TH0=(65536-50000)/256; //计数寄存器高8 位

TL0=(65536-50000)%6; //计数寄存器低8 位

TMOD=0x01; //工作方式为16 位定时器

ET0=0x01; //允许T/C0 中断

EA=1; // 全部中断允许

TR0=1; // 启动T/C0 运行

while(1) // 进入死循环

{

if(i>7)i=0; //若i>7,则i=0

}

}

void Timer0IRQ(void) interrupt 1 //中断服务函数

{

TH0=(65536-50000)/256; //计数寄存器高8 位重新载入

TL0=(65536-50000)%6; //计数寄存器低8 位重新载入

84

P2=1

i++; //i 自加1

}

分析:

T/C0 的初始化在main 函数中进行,在while(1)死循环当中,只有对i 变量检测,对LED 灯进行操作主要放置在T/C0 的中断服务函数Timer0IRQ,即P2=1很奇怪,main()函数里面基本对单片机的操作什么都没有,只有对变量i 的检测操作,几乎是空载运作,但是为什么流水灯还是能够运行呢?那么答案只能有一个,Timer0IRQ()中断服务函数能够脱离主函数独立运行。

大家很自然地想到为什么Timer0IRQ()函数独立于main()函数还能够运行,联系到在PC 机的C 语言的编程是根本不可能的事,因为所有的运行都必选在main()函数体中运行。只能告诉大家不同的平台自然有所不同,它们之间的不同必然会有各自的优点,还有例如AVR、ARM单片机编程同样是“主程序+中断服务函数”组合的架构,更何况是8051 系列单片机编程。当然我们学会了8051 系列单片机的编程,自然而然在AVR、ARM 或者更加多的单片机中的编程中得心应手,感觉就是以不变应万变。




关键词: datasheet中文资料     datasheet p    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]