static int delayLoopCount=400;
void Delay(int time)
{
int i,adjust=0;
if(time==0)//校准
{
time=200;
adjust=1;
delayLoopCount=400;
rWTCON=((MCLK/1000000-1)<8)|(2<3);//MCLK/1M,Watch-dog disable,1/64,interrupt disable,reset disable
rWTDAT=0xffff;//for first update
rWTCNT=0xffff;//resolution=64us@any MCLK
rWTCON=((MCLK/1000000-1)<8)|(2<3)|(1<5); //Watch-dog timer start
}
for(;time>0;time--)
for(i=0;i
if(adjust==1)
{
rWTCON=((MCLK/1000000-1)<8)|(2<3);//Watch-dog timer stop
i=0xffff-rWTCNT;//1count->64us, 200*400 cycle runtime = 64*i us
delayLoopCount=8000000/(i*64);//200*400:64*i=1*x:100 -> x=80000*100/(64*i)
}
}
初看这个函数时有问题的,花了很长时间才搞懂,很经典的一段程序。
(1)这个函数在使用前必须先运行一下Delay(0),这个是关键。它主要完成的是delayLoopCount变量的计算,即100uS的校准。
(2)假设MCLK=66M,
rWTCON=((MCLK/1000000-1)<8)|(2<3);经过预分频,输出频率1M,即1us计时;时钟除数因子=1/64,即看门狗定时器对1M的64分频计数, 计数一次是64us,每64usWTCON减1。
(3)for(i=0;i
(4)用此函数前,先用Delay(0)校准,一个是两个for循环延时。for循环延时同时,定时器计数。
200*400个循环对应------看门狗计数次数i(i=0xffff-rWTCNT,计数一次是64us),延时64*i个us;(200*400)/64i是每个us循环的个数, 100us对应的循环个数,(200*400)*100/64i;
delayLoopCount=8000000/(i*64);就是100us的for循环个数