|
原程序:
这是一段
static int delayLoopCount=400;
void Delay(int time)
// time=0: adjust the Delay function by WatchDog timer.
// time>0: the number of loop time
// 100us resolution.
{
int i,adjust=0;
if(time==0)
{
time=200;
adjust=1;
delayLoopCount=400;
rWTCON=((MCLK/1000000-1)<<8)|(2<<3); // 1M/64,Watch-dog,nRESET,interrupt disable
rWTDAT=0xffff;
rWTCNT=0xffff;
rWTCON=((MCLK/1000000-1)<<8)|(2<<3)|(1<<5); // 1M/64,Watch-dog enable,nRESET,interrupt disable
}
for(;time>0;time--)
for(i=0;i<delayLoopCount;i++);
if(adjust==1)
{
rWTCON=((MCLK/1000000-1)<<8)|(2<<3);
i=0xffff-rWTCNT; // 1count/16us?????????
delayLoopCount=8000000/(i*64); //400*100/(i*64/200)
}
}
分析: 这是一段使用看门狗来准确定时的程序,在time==0时进行校准。
当time为0时,进入如下程序中进行设置,
time=200;
adjust=1;
delayLoopCount=400;
rWTCON=((MCLK/1000000-1)<<8)|(2<<3); // 1M/64,Watch-dog,nRESET,interrupt disable
rWTDAT=0xffff;
rWTCNT=0xffff;
rWTCON=((MCLK/1000000-1)<<8)|(2<<3)|(1<<5); // 1M/64,Watch-dog enable,nRESET,interrupt disable
这一小段主要是是设置看门狗的寄存器
看门狗的时钟频率为t=1/(MCLK/(prescaler value+1)/division_factor)
prescaler value为WTCON的高8位。
rWTCON=((MCLK/1000000-1)<<8) 即设t=1/1000000/ division_factor
division_factoro为WTCON的第[4:3]位的值
rWTCON=((MCLK/1000000-1)<<8)|(2<<3)即设division_factor=1/64
t=64/1000000
rWTCON=((MCLK/1000000-1)<<8)|(2<<3)|(1<<5) 表示看门狗开始计时
经历了200个time,400个delayLoopCount
for(;time>0;time--)
for(i=0;i<delayLoopCount;i++);
这么多的时间后,使用
rWTCON=((MCLK/1000000-1)<<8)|(2<<3);
i=0xffff-rWTCNT; // 1count/16us?????????
delayLoopCount=8000000/(i*64); //400*100/(i*64/200)
来计算上面循环的时间
然后计算delayLoopCount的准备值。
1count=t=64/1000000 s
一共经历i个conunt.
i*64/1000000/200(time)/400(delayloopCount)=t_delayloopcount(一个循环时间)
当time=1时,要使T(for(i=0;i<delayLoopCount;i++))= 100us
则delayLoopCount * t_delayloopcount = 100us
Delysloopcount = 8000000/(i*64);
通过这种方式来校准时间,可以使这个延时比较准确。
此处要注意三点:
1、s3c44b0x看门狗定时器模块在作为定时器使用时计数器是倒计时的
2、1us=10^-6s
3、在main()函数开始的语句中应先设置Delay(0);以后在用到Dealy(int time)时time的值便是延时time个100us的时间 |
|