一、计算方法
都以6MHz晶振,定时20ms为例:
1. 方法1:
公式:N=65536-(Fosc/FD/(Freq))
N: 定时器16位计数器
Fosc: 晶振频率,系统频率
FD: 分频 (Frequency division),通过分频可增大计数器的定时范围。
Freq : 频率 (Freq=1000000(微秒)/TIME(微秒),TIME:所定时间)
1、先算出计算所需要定时器的时间对应的频率Freq,如定时20ms,对应的Freq为(1000000/20000)=50Hz。
2、通过单片机晶振频率计算单片机定时器需要计数的值:(Fosc/12/Freq)=( 6000000Hz/12/50)=10000【这里使用12分频】,所以定时器计数10000次才能达到时间20ms。(这里是12T和传统的89C52一样,计数一次所以要除以12)
3、定时器16位,最多可计数65536次,溢出为中断,所以用(65536-10000)=55536为定时器里面的初值。
2、方法2:
这里STC设置定时器T0为12T,和传统的51单片机一样
1、6MHz说明单片机每秒振荡6000 000次,每1毫秒振荡6000次。
2、单片机12个振荡时钟定时器计一次,我们需要定时20ms,单片机每1ms计数总量为:6000/12=500,则说明单片机每1ms进行500次计数,我们需要定时20ms所以定时器总的计数为500*20=10000次。
3、我们已经得出定时器定时20ms需要的计数值,因为定时器为计数到65536才中断,所以需要赋初值为65536-10000=55536;
二、C语言使用
方法1:
#define FOSC 6000000L //系统频率
#define T0_TIM (65536-(Fosc/12/50))
union VarS16{
U16 mU16;
U8 mU8[2];
};
void main()
{
union VarS16 tmp;
tmp.U16 = TO_TIM;
TMOD = 0x00;
//高位在前
TL0 = tmp.mU8[1];
TH0 = tmp.mU8[0];
TR0 = 1; //T0开始计数
ET0 = 1; //使能T0中断
EA = 1; //开启总中断
while(1)
{
;
}
}
void tm0_isr() interrupt 1 using 1
{
/*写入中断需要执行的代码*/
}
方法2:
#define FREQ_KHZ 6000L //系统频率
union VarS16{
U16 mU16;
U8 mU8[2];
};
void main()
{
union VarS16 tmp;
tmp.mU16 = (FREQ_KHZ/12L) * 20; //
tmp.mU16 = (~tmp.mU16) + 1; //取反 +1 相当于 ( 2^16 - tmp.mU16 )
TMOD = 0x00;
//高位在前
TL0 = tmp.mU8[1];
TH0 = tmp.mU8[0];
TR0 = 1; //T0开始计数
ET0 = 1; //使能T0中断
EA = 1; //开启总中断
while(1)
{
;
}
}
void tm0_isr() interrupt 1 using 1
{
/*写入中断需要执行的代码*/
}