单片机程序用软件延时来进行时间控制是经常的,比如让LED按一定的规律闪动。过去我用IAP15W4K58S4单片机时,我采用STC官网上下载的STC15实验箱范例程序的延时程序,其延时函数的定义为:
void delay_ms(u8 ms){
u16 i;
do{
i = MAIN_Fosc / 13000;
while(--i) ; //14T per loop
}while(--ms);
}
其中计算每毫秒做空循环次数的公式为:“i = MAIN_Fosc / 13000
”。
我实际进行测量,挺准的,在主频为22118400赫兹的情况下,延时1秒钟,实际为1001毫秒。
最近STC官网上又给出了STC8实验箱范例程序,其中的延时函数和STC15实验箱的一摸一样。处于好奇,我用STC8G1K12-20做了测试,结果在主频为22118400赫兹的情况下,延时1秒钟,实际只有768毫秒,整整少了232毫秒。
我怀疑是不是我的芯片有什么问题,于是用STC8A8K64S4单片机做了测量,结果仍然是一样的。也就是说STC8G和STC8A的实际运行速度比理论值快了近25%,这显然不是简单的误差可以解释的,一定是出现系统的偏差。
然后我用一款STC15W4K48S4单片机进行验证,结果在主频为22118400赫兹的情况下,延时1秒钟,实际为920毫秒,少了80毫秒。比同系列的IAP15W4K58S4单片机快了8%,也不像是简单的误差可以解释的,很可能是出现了系统的偏差。
同为1T周期的单片机,为什么有如此大的差别,秘密应该就在1T单片机内核使用的流水线结构上。STC官方芯片手册上提到STC8系列单片机内核采用了4级流水线结构,在STC ISP软件上称为“STC-Y6”结构。部分STC15系列单片机的内核也采用了4级流水线结构,称为“STC-Y5”结构,比如STC15Wxx系列。其余部分STC15系列单片机的内核采用的流水线结构不同,称为“STC-Y3”结构。
传统的12T周期STC单片机,没有流水线结构,称为“STC-Y1”结构,比如STC89xx和STC90xx系列。
我经过实际测试,STC不同内核结构的经验延时公式如下:
对于STC-Y6结构, 每毫秒做空循环次数的公式为:i = MAIN_Fosc / 10000
对于STC-Y5结构, 每毫秒做空循环次数的公式为:i = MAIN_Fosc / 119000
对于STC-Y3结构, 每毫秒做空循环次数的公式为:i = MAIN_Fosc / 13000
对于STC-Y1结构, 每毫秒做空循环次数的公式为:i = MAIN_Fosc / 96000
用C语言写软件延时函数,同样的程序,不同编译器编译出来的结果可能不同。这些经验公式是在使用Keil的C51编译器,在small模式和C语言8级优化的编译环境下测试得到的。当然同一个编译器对于不同的模式和优化方法,产生的延时也不一定相同。
要避免这种C语言程序延时效果依赖编译模式和优化方法的缺点,软件延时函数应该用汇编语言来写。
转载自:子牙篇(1)软件延时程序—STC8单片机隐藏的秘密
链接:https://m.weibo.cn/status/4524911408654095
作者:微博:单片机大哥
标签:Fosc,单片机,STC,STC8H,延时,软件,毫秒,MAIN From: https://www.cnblogs.com/FBsharl/p/18526969