整理STC延时函数时遇到的玄学问题

void Delay  
{  
    unsigned char i, j;  
    i = 11;  
    j = 190;  
    do  
    {  
        while (--j);  
    } while (--i);  
}  
  
  
  
void Delay  
{  
    unsigned char i, j;  
    i = 11;  
    j = 190;  
    while(i--)  
    {  
        while (--j);  
    }  
}  

以上两段代码,第一段为STCISP提供的1ms延时函数,第二段为改编版。按照个人对C语言的理解,这两种写法所得到的结果应该是一致的,最起码在Dev-C++上以下两端代码输出结果相同,均为2739:

int main(int argc, char *argv[]) 
{
    unsigned char i, j;
    int num = 0;
    i = 11;
    j = 190;
    while(i--)
    {
        while (--j)
        {
            num++;
        }
    }
    printf("num=%d\n",num); 
    return 0;
}



int main(int argc, char *argv[]) 
{
    unsigned char i, j;
    int num = 0;
    i = 11;
    j = 190;
    do
    {
        while (--j)
        {
            num++;
        }
    } while (--i);
    printf("num=%d\n",num); 
    return 0;
}

但开头提到的两段代码,在STC15F104(11.0592M)单片机上跑起来其延时结果却截然不同。实测在预设延时500ms时(即重复运行上述函数500次),第一段代码比较符合实际,第二段要比第一段要慢一倍左右,即将第二段代码中的11改为6后可以得到大体相同的延时结果。

造成这种现象的原因,到现在也没搞清楚,我发表在开源电子网的提问贴截止到目前也没有收到合理的解释。我不打算再耗下去,只能强行解释一波了:

造成延时结果不同的原因是单片机在执行 while()...; 和 do...while(); 时的效率不同。

 

 

这解释很有道理,因为在 while()...; 和 do...while(); 在汇编代码中的长度的确相差一倍左右。但仍不能很好解释延时结果相差之大。因为无论是 while()...; 和 do...while(); ,在延时函数中仅仅执行了11次而已,真正起决定性作用的应该是中间那段 while (--j); ,在如此大基数的循环下, while()...; 和 do...while();  相差的那点时间应该显得微不足道才对啊。

算了,这件事告一段落了,不打算再在这上面浪费时间了。下面附上 while()...; 和 do...while(); 的汇编代码。代码来源于网络,其实我也不懂。

/**** while 语句 pseudo-code ********/ 
while ( condition ) 
{  
  body of loop; 
} 
/****while 语句 assembly language *******/ 
while: 
; code to set FLAGS based on condition
jxx   endwhile 
; body of loop 
jmp while 
endwhile:
/****while 语句 assembly language (end) ***/  

/**** Do while 语句 pseudo-code ********/ 
do
{
  body of loop; 
}while ( condition ) 
/****Do while 语句 assembly language *******/ 
do_while: 
; body of loop 
; code to set FLAGS based on condition 
jxx   do_while
/****Do while 语句 assembly language (end) ***/

 

posted @ 2018-12-03 18:48  路合华  阅读(331)  评论(0编辑  收藏  举报