#include <STC89C5xRC.H>
typedef unsigned char u8;
typedef unsigned int u16;
sbit led = P2^0;
bit f,m; //bit类型的变量取值只有0、1两种情况 通常作为标志位使用
u8 Count5ms;
void Delay10ms(void)//翻转一次 两倍时间
{
while(m);
while(!m);
}
void Delay1s(void)
{
while(f);
while(!f);
}
void Timer0Init() //基准1ms
{
TMOD|=0X01;
TH0=(65536-5000)>>8;
TL0=(unsigned char )(65536-5000);
ET0=1;
EA=1;
TR0=1;
}
void main()
{
Timer0Init();
while(1)
{
led=!led;
Delay1s();
}
}
//定时器服务函数
void Timer0() interrupt 1 //5ms为基准
{
TH0=(65536-5000)>>8; //TH0=(65536-5000)/256;
TL0=(unsigned char )(65536-5000); //TL0=(65536-5000)%256;
Count5ms++;
m=~m;
if (Count5ms == 100)
{
Count=0;
f=~f;
}
}
--------------------------------------------------------------------------------------
关于定时器初值的计算
1、时钟周期,也称为振荡周期:定义为时钟脉冲的倒数,在单片机中也就等于晶振的倒数。
51单片机中把一个时钟周期定义为一个节拍(用P表示),2个节拍定义为状态周期(用S表示)
时钟周期是单片机中最小的时间单位。
eg:12M晶振的单片机,时钟周期=振荡周期=1/12 us。
2、机器周期:定义为完成一项基本操作所需要的时间,称为机器周期。
在计算机中,为了方便管理,把一条指令的执行过程分为若干个阶段,每个阶段去执行一项基本操作。
如:取指令,存储器读,存储器写等。
在51单片机中1个机器周期由6个状态周期组成,也就是12个时钟周期=12 x 1/12 us =1 us
定义机器周期是因为时钟周期时间太短,根本做不了什么。
3、指令周期:定义为执行一条指令所需的时间。
通常,包含一个机器周期的指令称为单周期指令,比如 MOV指令,CLR指令等。
包含两个机器周期的指令称为双周期指令。
另外还有四周期指令。
不要慌,其实我们这节课要用到的就一句话—— 在51单片机中1个机器周期由6个状态周期组成,也就是12个时钟周期=12 x 1/12 us =1 us
这里我们知道了一个机器周期的时间是1us,所以如果我们要延时1ms就是1000个机器周期;
可能大家我们刚开始了解定时器的时候都会与疑惑,为什么要用定时器这么麻烦的东西,自己用delay()慢慢调一个合适的参数就可以了。 其实如果深入了解定时器真的比delay() 强大太多我先列举几点:
1.就如上面所说用定时器定时1ms,这里就要注意了,这个1ms不是和delay延时1ms一样哦,这个1ms是精确的1ms哦,越往后学需要的定时就要求越高,所以定时器是一定要搞定的。
2.相比于delay计时,delay是要直接让单片机做空循环,死等。而定时器则是利用定时器的溢出间隔,如果时间上不够,可以在溢出中断中配合软件计数器来实现。 前者浪费cpu,后者更高效。
言归正传,现在来计算初值了,直接用例子说明,就比如用定时器0延时50ms
一言不合,先上代码
void main()
{
TOMD|=0x01; //设置TMOD工作方式寄存器的M0M1为01,对照表格即为定时器/计数器的4种模式中的16位定时器/计数器模式
TH0=(65536-46080)/256; //装初值11.0592M晶振定时50ms数为46080
TL0=(65536-46080)%256;
EA=1; //中断总开关
ET0=1; //开启定时器/计数器的中断允许位置为1
TR0=1; //
return 0;
}
void T0_time() interrupt 1
{
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;
num++;
if(num==20)
{
num=0;
}
}
首先一个机器周期=12一个时钟周期=12(1/晶振) 一般的51晶振频率为11.0592M
则一个机器周期= 1.085069444444444 us 单位是微秒
所以如果要定时50ms 则要50 000/1.085069444444444~=46080个机器周期
又因为TOMD|=0x01选择了16位的模式,就是TH0高八位 TL0低八位,所以最大到溢出就是65536
故初值设为65536-46080即程序运行了大约46080个机器周期即50ms
而后面的/256 %256就是划分低八位和高八位的