标题: 关于STC 51单片机不同指令集的(Y1-Y3-Y5-Y6)软件延时函数,如何才能更精确? [打印本页]

作者: DTY拾光    时间: 2022-5-1 04:43
标题: 关于STC 51单片机不同指令集的(Y1-Y3-Y5-Y6)软件延时函数,如何才能更精确?
关于STC 51单片机不同指令集的,Y1-Y3-Y5-Y6软件延时函数,大家都是怎么写的呢?
本人,以前学了几天STC89**的,通过STC-ISP生成延时函数改造一直使用着,没觉得误差有多大:如下
  1. //延时n毫秒 @11.0592MHz _STC89C52RC
  2. void delay_ms(unsigned int n)
  3. {
  4.     unsigned int i,j;
  5.     for(i=n;i>0;i–)
  6.     for(y=114;y>0;y–);
  7. }
复制代码
之前就学了点,对于51单片机了解的也不多,就没再研究过其他型号。直到前几天一个同学要做东西,问我会不会51,一想,这玩意我会呀,学STM32之前学过几天,所以就答应帮他看程序,但当他把单片机拿过来,烧好我写的程序时,怎么都跑不正确,有关延时的全部跑飞了。。。。。。。。。。
于是我就去查了资料,原来51分不同指令集,不同的型号指令执行周期不同,而我拿到同学的是个STC12C5A系列的,属于Y3指令集,它的一个振荡周期=一个机器周期,管他一条指令消耗几个状态周期,这玩意儿速度自然比89系列(一个12个振荡周期=一个机器周期)的快了10倍左右吧。
  1. void delay_ms(unsigned int k){
  2.         unsigned char i, j;
  3.         for(k; k>0; k--){        
  4.                 _nop_();
  5.                 i = 11,j = 190;
  6.                 do
  7.                 {
  8.                         while (--j);
  9.                 } while (--i);
  10.         }
  11. }
复制代码
于是呢:我又在STC-ISP软件生成了一个1ms的延时函数,然后循环N次执行,表面虽然解决了,但是呢每次循环,还有首次循环赋值消耗的时间呢?
这中间得有至少2个以上周期了,那么时间长了误差不就越来越来了吗,所以大家平时都是怎么控制延时的呢?


作者: 人人学会单片机    时间: 2022-5-1 11:45
1、假设在同一个硬件上做测试,单片机CPU指令周期是一致的。那么 变量i、K,存放在data跟存放在XDATA,读写速度能一样?精确计算有意义吗?
2、假设都存放在data,延迟1ms只需要char类型的变量即可完成,但是,延迟100ms必须16位变量,那么执行时间还能照着公式去套算?
3、假设上述条件都一样,计算好的延迟时间是1ms并且误差1%,打开中断之后,延迟时间变成了5毫秒了。误差500%了,精确计算有意义吗?
4、假设上述条件不影响延迟时间,那么,编译器呢?谁敢说编译器不同的优化等级不影响delay的延迟时间?
5、还有硬件不同的情况,就需要重新计算了。比如晶振频率不同,CPU内核速度不同,STC8H单片机就比STC15快了很多了比89系列快了十几倍了。
实例说明:
作者: Y_G_G    时间: 2022-5-1 12:09
void Delay_ms(unsigned int a)                //@12.000MHz,1mS延时函数,代码从STC下载器复制来
{
        unsigned char i, j;
        for(a;a>0;a--)
            {
                i = 16;
                j = 147;
                do
                {
                        while (--j);
                }         while (--i);
          }
}
从1mS到1秒,我都是用这个
误差肯定是有的,但这重要吗?
误差不会很大的,不会是1S延时变成2S或者50S的,误差肯定是在可以接受的范围内的
你都用软件来进行延时了,对精度本身就不会太大的要求了,你想软件延时10S,误差只有几uS的,那得在这上面耗上多少精力?直接用定时器不就行了
高精度延时用软件延时,这就是把好钢用在刀把上
高精度时间控制,都是用定时器完成的
延时很短的,直接用空指令
作者: jinsha_linux    时间: 2022-5-1 12:40
这边基本都是基于定时器0 进行高精度延时的
作者: lkc8210    时间: 2022-5-1 14:05
毫秒级延时直接用定时器
作者: 高高的白杨    时间: 2022-5-1 15:25
直接使用STC出的stc-isp软件中的软件延时计算器,计算可选项区分Y1、Y3、Y5及Y6,可以满足楼主的需求。
作者: huangjingjie    时间: 2022-5-1 17:58
我理解的延时函数是满足硬件指令间时间间隔的要求或是大概的延时要求用的,和时间精准没有因果关系。
作者: 啤酒瓶子老大    时间: 2022-5-1 22:50
我感觉还要用外接晶振的。不要用内部晶振的。内部的晶振每次烧录时会有误差。
作者: man1234567    时间: 2022-5-1 23:22
1、用定时器定时
2、用示波器校准




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1