AT89C51定时器

AT89C51定时器_第1张图片



GATE0 为定时器控制器,当置1时,只有在外部中断INT0引脚为高电平及TR0控制位置1时,才打开定时或计数,GATE1同理

C/T :定时或计数

M1 M0 定时器/计数器模式选择


若工作在定时器0:(不采用外部中断,且不采用计时,而采用定时,定时器模式选择:00:模式0,01:模式1)

TMOD &= 0xf0;

TMOD |= 0x01;


定时时间计算:

若定时1ms,晶振FOSC为11.0592MHz ,也就是11059200Hz,则晶振周期为1/11059200

一个单指令的时间是12个晶振周期,也就是1/11059200*12,若要定时1ms,则(1/1000)/(1/11059200*12),也就是11059200/12/1000

当m1为0,m0为1时,既模式1,它是16位定时器,也就是最大值为2^16等于65536,也就是TH0和TL0的最大值为65536

65536是定时器的溢出值,当定时器达到这个 值时就产生中断,表示时间到。

所以要产生1ms的定时,就定义:

#define FOSC 11059200L          (这是晶振频率)

#define TIMES (65536-FOSC/12/1000)         (这是定时时间器定时1ms,定时器所对应 的初值)

下面是定时器中断函数:定时1秒

bit time_1_s;

uint8 cnt=0;

void timer0_isr() interrupt 1 using 1

{

TL0 = TIMES;

TH0 = TIMES>>4 ;

if (++cnt == 1000)

{

cnt = 0;

time_1_s = 1;

}

}

初始化定时器:

void timer0_init(void)

{

TMOD = 0x01;

TL0 = TIMES;

TH0 = TIMES>>4;

TR0 = 1;            /*定时器0,start running*/

ET0 = 1;            /*ENABLE timer0 interrupt*/

}

interrupt 0  指明是外部中断0;
interrupt 1 指明是定时器中断0;
interrupt 2 指明是外部中断1;
interrupt 3 指明是定时器中断1;
interrupt 4 指明是串行口中断;

using 0 是第0组寄存器;
using 1 是第1组寄存器;
using 2 是第2组寄存器;
using 3 是第3组寄存器;

R0-R7在数据存储器里的实际地址是由特殊功能寄存器PSW里的RS1、RS0位决定的。

using 0时设置 RS1=0,RS0 =0,用第0组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(00H)....R7(07H)

using 1时设置 RS1=0,RS0 =1,用第1组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(08H)....R7(0FH)

using 2时设置 RS1=1,RS0 =0,用第2组寄存器,R0--R7的在数据存储区里的实际地址是08H-0FH。R0(10H)....R7(17H)

using 3时设置 RS1=1,RS0 =1,用第3组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(18H)....R7(1FH)


下面对应驱动程序:

if (time_1_s==1)

{

time_1_s = 0;

LED = ! LED;

}

在主函数中要初始化定时器:

void main(void)

{

timer0_init();

EA = 1;     /*打开定时器中断总开关*/

}

你可能感兴趣的:(c51)