51定时器
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uint SysTime;
void Timer0() interrupt 1
{
TH0 = (65536 - 1000) / 256;
TL0 = (65536 - 1000) % 256;
SysTime++;
}
void InitTimer()
{
TMOD = 0x01; //16位计数器
TH0 = (65536 - 1000) / 256;
TL0 = (65536 - 1000) % 256;
TF0 = 0; //计数到时TF0为1,即当TH0 = 0xff;TL0 = 0xff;再运行一步TF0 = 1;
TR0 = 1; //开始计数,从这时起,每运行一步TH0和TL0都会增加,直到TH0 = 0xff;TL0 = 0xff;
ET0 = 1; //允许定时器0中断
EA = 1; //开启全局中断
}
void main()
{
InitTimer();
P2=0x01;
while(1)
{
if(SysTime==1000)
{
P2 = _crol_(P2,1);
SysTime = 0;
}
}
}
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uint SysTime;
void Timer0() interrupt 1
{
TH0 = (65536 - 1000) / 256;
TL0 = (65536 - 1000) % 256;
SysTime++;
}
void InitTimer()
{
TMOD = 0x01; //16位计数器
TH0 = (65536 - 1000) / 256;
TL0 = (65536 - 1000) % 256;
TF0 = 0; //计数到时TF0为1,即当TH0 = 0xff;TL0 = 0xff;再运行一步TF0 = 1;
TR0 = 1; //开始计数,从这时起,每运行一步TH0和TL0都会增加,直到TH0 = 0xff;TL0 = 0xff;
ET0 = 1; //允许定时器0中断
EA = 1; //开启全局中断
}
void main()
{
InitTimer();
P2=0x01;
while(1)
{
if(SysTime==1000)
{
P2 = _crol_(P2,1);
SysTime = 0;
}
}
}
一次定时需要几次机器周期:
计算公式:定时秒数/机器周期
比如我要定时1秒, 1/(12/11059200)= 921600次,16位计数器最大可计数65536次,921600次早就溢出了。我们可以每次定时10 ms,循环
100次就可以定时1秒了,1 s缩小100百倍就是10 ms, 也就是每次需要计数9216次。
确定计数器初始值:
定时10 ms时,如果计数器从0开始计数,我们就不知道什么时候到了9216次。所以应该计数了9216次,16位计数器最多计数95536次,然后就溢出,一溢出TCON的TF位就会置1,我们只要经常检测TF位就可以知道什么时候完成10ms的定时了。
计算公式:计数器初始值=最大计数次数 - 需要计数次数
如果定时10 ms,计数器的初始值就是 65536 - 9216
计算计数器的高位和低位:
16位的计数器,也就是两个8位组成,8位的最大计数次数是256。所以:
计数器高位 = 初始值/256
计数器低位 = 初始值%256
释疑:void Timer0() interrupt 1 using 1:
Timer0 是函数名,随便取的
interrupt xx using y
跟在interrupt 后面的xx 值得是中断号,就是说这个函数对应第几个中断端口,一般在51中
0 外部中断0
1 定时器0
2 外部中断1
3 定时器1
4 串行中断
实际上编译的时候就是把你这个函数的入口地址方到这个对应中断的跳转地址
using y 这个y是说这个中断函数使用的那个寄存器组,51里面一般有4组 r0 -- r7寄存器,一共有32个,如果你的终端函数和别的程序用的不是同一个寄存器组则进入中断的时候就不会将寄存器组压入堆栈返回时也不会谈出来节省代码和时间