找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5851|回复: 22
收起左侧

你还在浪费时间去计算单片机延时程序delay的循环次数?

  [复制链接]
ID:390416 发表于 2021-3-26 11:16 | 显示全部楼层 |阅读模式
本帖最后由 人人学会单片机 于 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的代码执行效率,是很有必要的!
“什么是单片机?咱玩的就是时间!”

WQX-15开发板02  模块功能展示.jpg WQX-15开发板03 核心板.jpg WQX-15开发板01  高配全亮.jpg



回复

使用道具 举报

ID:884042 发表于 2021-3-26 20:37 | 显示全部楼层
好东西啊!
回复

使用道具 举报

ID:881715 发表于 2021-4-20 19:24 来自手机 | 显示全部楼层
为什么第二种情况多加了一层死循环延时时闸反而会更短呢请老师指教
回复

使用道具 举报

ID:457221 发表于 2021-4-22 17:22 | 显示全部楼层
说半天,都不知想表达什么
回复

使用道具 举报

ID:910171 发表于 2021-4-24 16:37 来自手机 | 显示全部楼层
不知所云呀。
回复

使用道具 举报

ID:106977 发表于 2021-4-26 16:56 | 显示全部楼层
现在的51单片机资源也多了。可以利用T1做精确定时器。
回复

使用道具 举报

ID:912593 发表于 2021-4-26 17:59 来自手机 | 显示全部楼层
初学也是看不懂,谢谢大大们分享
回复

使用道具 举报

ID:390416 发表于 2021-4-30 22:23 | 显示全部楼层
创造生活 发表于 2021-4-20 19:24
为什么第二种情况多加了一层死循环延时时闸反而会更短呢请老师指教

你们不要去看懂这些延迟,因为根本没什么卵用,我文章的主题思想 就是告诉你们不要用delay来做长延迟或者精准延迟。
回复

使用道具 举报

ID:390416 发表于 2021-4-30 22:24 | 显示全部楼层
winson007 发表于 2021-4-22 17:22
说半天,都不知想表达什么

你们不要去看懂这些延迟,因为根本没什么卵用,我文章的主题思想 就是告诉你们不要用delay来做长延迟或者精准延迟。
回复

使用道具 举报

ID:390416 发表于 2021-4-30 22:28 | 显示全部楼层

你们不要去看懂这些延迟,因为根本没什么卵用,我文章的主题思想 就是告诉你们不要用delay来做长延迟或者精准延迟。
回复

使用道具 举报

ID:383215 发表于 2021-5-1 17:12 | 显示全部楼层
人人学会单片机 发表于 2021-4-30 22:23
你们不要去看懂这些延迟,因为根本没什么卵用,我文章的主题思想 就是告诉你们不要用delay来做长延迟或者 ...

你说的非常非常的正确,这些延时程序根本没什么卵用,我从来不计算任何程序的时间,都是设计电路的时候多预留一个I/O口,就用这个口靠示波器测量,什么18B20、HX711、红外接收之类的程序延时,就是用示波器测量着编出来的。我把单片机延时程序定为普通精度、高精度和超高精度三个档次,每种精度我都有办法实现。我编的所有单片机程序除了程序入口处,其它地方超过100微秒的延时程序根本就没有,几百微秒以上的延时程序用其它方法都解决了。
回复

使用道具 举报

ID:951974 发表于 2022-12-21 14:15 | 显示全部楼层
说了半天都是有道理的,但是等于又什么都没有说。。。。。。。
楼主真是高手啊
回复

使用道具 举报

ID:673920 发表于 2022-12-21 23:03 来自手机 | 显示全部楼层
我初学一般情况是把时间收/放一下,再用示波器或用秒表验证
回复

使用道具 举报

ID:1064915 发表于 2023-12-27 09:19 | 显示全部楼层
18B20、HX711、红外接收
不用delay,有什么方法
回复

使用道具 举报

ID:383215 发表于 2023-12-27 15:25 | 显示全部楼层
joyb 发表于 2023-12-27 09:19
18B20、HX711、红外接收
不用delay,有什么方法

不是18B20、HX711、红外接收不用delay,是18B20、HX711、红外接收的这些程序,几十μS到100μS以内的延时只能用软件延时,至少51单片机100μS以内没有必要安排其它程序,100μS以内的延时精度要求较高,误差太大就会导致单总线器件的读写不正常,几百μS以上的长延时不能用软件延时,会造成CPU代码执行效率降低,单总线器件的长延时对精度要求并不高,可以用中断完成,不用中断还可以用循环周期。楼主最后说的是重点:“学会提高CPU的代码执行效率,是很有必要的!”重点中的重点是最后一句:“什么是单片机?咱玩的就是时间!”可惜很多人不理解。
回复

使用道具 举报

ID:433219 发表于 2023-12-28 14:21 | 显示全部楼层
示波器,是干什么用的???
现在各种mcu的内核速度不一样,靠数几个_nop_之类的,绞尽脑汁去计算,不如示波器卡一下时间,一目了然!!!
回复

使用道具 举报

ID:120219 发表于 2023-12-28 14:57 | 显示全部楼层
winson007 发表于 2021-4-22 17:22
说半天,都不知想表达什么

广告才是关键
回复

使用道具 举报

ID:1085441 发表于 2023-12-28 17:21 | 显示全部楼层
延时程序我也是用示波器来测量,因为各种原因,计算的都不准。
回复

使用道具 举报

ID:458247 发表于 2023-12-28 17:50 | 显示全部楼层
wkman 发表于 2023-12-28 14:21
示波器,是干什么用的???
现在各种mcu的内核速度不一样,靠数几个_nop_之类的,绞尽脑汁去计算,不如示 ...

如果是STM32的单片机,建议用dwt功能进行计时,免去接硬件的繁琐,直接在软件里就可以计算运行时长
回复

使用道具 举报

ID:145357 发表于 2024-1-11 23:16 来自手机 | 显示全部楼层
cnfloatleaf 发表于 2023-12-28 17:21
延时程序我也是用示波器来测量,因为各种原因,计算的都不准。

给个教程怎么搞的?
回复

使用道具 举报

ID:804975 发表于 2024-1-14 23:10 | 显示全部楼层
一般8位机,尽量避免阻塞式延时,这种方式,会让定时器要求高,开两个定时都会有函数超时的问题的可能。
回复

使用道具 举报

ID:804975 发表于 2024-1-14 23:17 | 显示全部楼层
阻塞式延时,最大的问题在函数的运行的时间很长,后面的语句要等待,说个例子,IIC的工作里面就有大量的延时操作,完成一个动作,等待10MS再操作其他的动作,程序都停止等待这个10MS的结束。这个等待会影响到其他的操作,好象按键输入,AD输入等等,小程序还好,大一点的程序就有麻烦了。
回复

使用道具 举报

ID:1108782 发表于 2024-1-16 11:13 | 显示全部楼层
解决办法也很简单,占用一个定时器,用定时器计算精确时间。不过如果没有加晶振的话时间也不准的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表