本帖最后由 人人学会单片机 于 2021-4-4 19:08 编辑
好久没有发贴子了,最近都在51hei论坛上回答网友问题。我发现很多个网友都有提问同样的问题,如何精确的计算delay 里面多少个循环是1ms 。或者说for循环的语句时间多少,循环一次多少时间???比如这样的一个单片机延时代码:
void delay_ms(unsigned char ms)
{
unsigned char i,k;
for(i=0;i<ms;i++)
for(k=0;k<110;k++);
}
我今天发这个贴子,并不是告诉小白们如何去计算这种参数,因为真正搞工程项目设计的,压根就不去计算这种参数的。理由如下:
1、假设在同一个硬件上做测试,单片机CPU指令周期是一致的。那么 变量i、K,存放在data跟存放在XDATA,读写速度能一样?精确计算有意义吗?
2、假设都存放在data,延迟1ms只需要char类型的变量即可完成,但是,延迟100ms必须16位变量,那么执行时间还能照着公式去套算?
3、假设上述条件都一样,计算好的延迟时间是1ms并且误差1%,打开中断之后,延迟时间变成了5毫秒了。误差500%了,精确计算有意义吗?
4、假设上述条件不影响延迟时间,那么,编译器呢?谁敢说编译器不同的优化等级不影响delay的延迟时间?
5、还有硬件不同的情况,就需要重新计算了。比如晶振频率不同,CPU内核速度不同,STC8H单片机就比STC15快了很多了比89系列快了十几倍了。
实例说明:
下面的代码,都是使用STC8H8K单片机测试,晶振频率24M(既FOSC=24000000UL),并且没有使用任何中断资源。但是使用了其他函数。
第一种情况,函数延迟时间是1.004ms。
#define FOSC 24000000UL
void TFT_Delay1ms(u8 x)
{
u16 data i;
i=FOSC/10000;
while(i--);
}
第二种情况,给x赋值200,延迟时间是0.1807秒=180.7ms,嘿嘿,多写一层while死循环,居然少于200ms。
#define FOSC 24000000UL
void TFT_Delay1ms(u8 x)
{
u16 data i;
i=FOSC/10000;
while(i--)
{
while(x--);
}
}
第三种情况,也给x赋值200,变量先减后判,延迟时间是0.1547秒=154.7ms。比上面两种情况都快。
#define FOSC 24000000UL
void TFT_Delay1ms(u8 x)
{
u16 data i;
i=FOSC/10000;
while(--i)
{
while(--x);
}
}
所以,不要去精确的计算delay 延迟了多少时间,毕竟单片机的运行情况有很多变数。学会提高CPU的代码执行效率,是很有必要的!
“什么是单片机?咱玩的就是时间!”
|