目录
周期:
振荡周期:时钟周期也称为振荡周期,定义为时钟频率的倒数。12MHz晶振的时钟周期就是1/12 us、1MHz就是1us。
状态周期:2个振荡周期为1个状态周期。
机器周期:1个机器周期含6个状态周期,12个时钟周期。指令周期是取出一条指令并执行这条指令的时间。12MHz晶振的机器周期就是12*1/12us=1us。
指令周期:完成一条指令所需的时间就是指令周期,不同的指令,指令周期也不一样。它是指CPU完成一条操作的所需的全部时间。
机器周期=6状态周期=12振荡周期
一个nop指令占用一个机器周期,也就是12个时钟周期。
调用函数需要两个机器周期,结束函数需要两个机器周期。
void delay(unsigned int t)//10us
{
while(t--);
}
void Delay10us() //@12.000MHz STC工具生成
{
unsigned char i;
_nop_();
i = 2;
while (--i);
}
//这两个函数分别掉调用时的真正时间
delay(1);//422-449 20
delay(2);//486 40
delay(3);//532 50
delay(4);//589 60
delay(5);//655 70
delay(6);//731 80
delay(7);//817 80
delay(8);//912 100
delay(9);//1017 100
delay(10);//1132 100
delay(100);//2126 1000
Delay10us();//2137 10 可见STC自动生成的函数还是非常准确的
---------------------------------------------------------------------------------------------------------------------------------
-------------------------以下是用来算STC工具自动生成的延时函数的时间计算方法--------------------------
while语句:
while(--x);
如果条件成立然后执行一次空语句,如果条件不成立,则执行下一指令。
时间公式为[2*x-1]us。
void Delay512us()//2us //@12.000MHz
{
unsigned char i;//1us
_nop_();//1us
i = 253;//1us
while (--i);//2*253-1=505us
}//2us
do while语句:
do
{
while (--j);
} while (--i);
不管什么条件先执行花括号里面的程序:while、空程序
do执行一遍占用1us
花括号内时间公式为约2*x-1us。
然后执行花括号外的while,如果为真,则执行空程序然后再执行一遍do,假则不执行。
当i>1,j=0时,在执行一遍do,这时j溢出变为从255开减。
花括号外的时间公式也为2*x-1us。
void Delay519us()//2us //@12.000MHz
{
unsigned char i, j;//1us
_nop_();//1us
i = 1;//1us
j = 255;//1us
do//1us
{
while (--j);//2*255-1=509us
} while (--i);//1us
}//2us
void Delay520us()//2us //@12.000MHz
{
unsigned char i, j;//1us
i = 1;//1us
j = 0;//1us
do//1us
{ //刚开始j=0,0--溢出为255,然后从255开始减,越等于从256开始减
while (--j);//2*256-1=511us
} while (--i);//1us
}//2us
void Delay522us()//2us //522us和524us延时函数一样有误差,加起来为523us @12.000MHz
{
unsigned char i, j;//1us
i = 2;//1us
j = 1;//1us
do//i=2,运行两边2*1=2us
{ //先再1开始执行一遍用1us,执行第一遍的时候1-到0了
while (--j);//第二遍先空指令然后0到255,再从255开始减,约等于从256开始2*256-1=511us
} while (--i);//第一遍2到1执行空程序然后在执行一遍,第二遍1到0不再往后执行了,2*2-1=3us
}//2us
void Delay526us()//2us //@12.000MHz
{
unsigned char i, j;//1us
i = 2;//1us
j = 2;//1us
do//i=2,运行两边2*1=2us
{ //第一遍从2开始 2*2-1=3us
while (--j);//第二遍约等于从256开始2*256-1=511us
} while (--i);//第一遍2到1执行空程序然后在执行一遍,第二遍1到0不再往后执行了,3us
}//2us
void Delay1ms()//2us //@12.000MHz
{
unsigned char i, j;//1us
i = 2;//1us
j = 239;//1us
do//i=2,运行两边2*1=2us
{ //第一遍从239开始2*239-1=477us
while (--j);//第二遍约等于从256开始2*256-1=511us
} while (--i);//第一遍2到1执行空程序然后在执行一遍,第二遍1到0不再往后执行了,3us
}//2us
void Delay1040us()//2us //@12.000MHz
{
unsigned char i, j;//1us
i = 3;//1us
j = 2;//1us
do//3*1=3us
{ //第一遍从2开始2*(2-1)+1=3us,第二遍第三遍从256开始2*2*(256-1)+1=1022us
while (--j);//1022+3=1025us
} while (--i);//2*(3-1)+1=5us
}//2us
void Delay132ms()//2us //@12.000MHz
{
unsigned char i, j, k;//1us
_nop_();//1us
i = 2;//1us
j = 1;//1us
k = 201;//1us
do//i=2,2us
{
do //第一遍先执行一遍循环do-while-while 1+2*(201-1)+1+1=403us然后i=1了
{ //第二遍jk都为0了,从256开始
while (--k);//k执行一遍需要511us,但是j=256,所以要256*511=130816us do也要执行256遍 +256us
} while (--j);//2*(256-1)+1=511us
} while (--i);//2*(2-1)+1=3us
}//2us