在我看单片机相关延时问题看到一段代码,想不明白这个延时时间如何算出来的。
给出的代码如下:
void delay()
{
unsigned char i, j, k; //延时200ms @11.0592MHz
_nop_();
_nop_();
i = 9;
j = 104;
k = 139;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
我的想法是先执行最中间的 while (--k); 语句,执行139次之后,k变为0退出该循环;
接下来执行外面的do while循环,又执行255104次;
再执行最外面的do while 循环,执行2552559次;
次数相加乘以机器周期,即
(139+255104+2552559+6)*12/11059200=0.664s
和0.2s差十万八千里。
难道k、j变成0之后再减1的值不是255?
我又试了下127比较接近答案。可是为什么呢?我以为的是unsigned char 的值域是0~255。
还是说我的思路根本就是错的呢?
恳请各位的的解答。谢谢!
这种方式没法精确计算延时
首先C语言在不同的优化模式下,最终生成的机器代码是不一样的,即使你要计算,也要根据反汇编代码计算。
然后,现在的单片机很多都带流水线,已经不是以前那种12个时钟一个指令周期了,但也不会完像现在厂家宣传的那样一个时钟一个指令周期,这个取决于具体的指令顺序。比如正常顺序执行的时候,可能就是执行一条指令的时候,下一条就已经预先取好,基本是一个时钟一个指令周期,但假如出现了跳转,流水线就乱了,又要重新取。C语言的循环里就正好有这种跳转。
再次,假如系统有中断,那就更没法计算了。
如果你想用这种方式进行延时,建议先写个大概框架,然后测试一下延时与参数的关系,然后做一下调整。
如果楼上说的,学校里的方法是软件DEBUG看汇编指令数量,然后根据时钟大小来算
实际这样不行,都是用示波器或者逻辑分析仪去测量的,这样更可靠