打印

一种被妖魔化的延时程序的写法

[复制链接]
7002|40
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zcw9911|  楼主 | 2012-9-9 13:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在论坛里看到如果谁的程序里延时程序里用的是使用这种for(i=0;i<DelayCnt;++);这种死等的的方法,就会很多人来指出,这种做法太没有效率了,太没有实时性了,太没有水平了,应该使用中断+标志位的方法等等这种做法就真的那么不堪吗?其实很多人都是人云亦云而已,对单片机系统没有真正的深入了解,单片机一般都是
完成控制功能,实时性真的很重要吗?对个别系统来说实时性可能很重要,但是对更多的系统来说实时性并不重要,但是不管任何系统的稳定性和可靠性都是最重要的,而这种循环方式的可靠性是高于采用中断方式的,中断方式数据要进栈,要出栈,程序计数器要跳转,其操作过程用受到干扰概率大大增加,在IEC61508标准里面就推荐尽量减少中断的使用,采用中断的方式还有一个缺点,就是程序的执行时间不是那么很可控,这个程序的执行时间宽度可能会很大,有可能这次需要1ms,下次就需要5ms,如果每个子程序都是这样的话,就会使整个程序的时间变得不可控,很难计算,很多人会问,运行时间不可控又有什么关系呢?在很多重要的控制系统中,常用的做法就是使程序运行时间是固定的,然后系统通过顺序逻辑监视的方法检测程序运行是否正常,其基本原理就是依靠程序的运行时间来判断某个程序是否在运行。所以说在程序中使用这种方法并不丢人,反而是一种返璞归真。

相关帖子

沙发
NE5532| | 2012-9-9 14:10 | 只看该作者
绝大部分吵架都是源于不讲应用环境就说自己的东西好。

使用特权

评论回复
评分
参与人数 3威望 +3 收起 理由
cool_coder + 1
shizaigaole + 1
chhg616 + 1
板凳
gsky| | 2012-9-9 14:10 | 只看该作者
大大说得很有道理

使用特权

评论回复
地板
受不了了| | 2012-9-9 14:55 | 只看该作者
呵呵,你没有开任何中断?不知道没有任何中断的控制能做什么。设计单片机的人不傻,不可靠的中断功能人家设计来干啥。有些东西也是死等不来的,不是你等了它就必然发生

使用特权

评论回复
5
harleyzeng| | 2012-9-9 15:35 | 只看该作者
很有道理,系统的稳固和控制的可靠是最重要的!

使用特权

评论回复
6
logokfu| | 2012-9-9 16:50 | 只看该作者
定时器一定要用好啊

使用特权

评论回复
7
chenbb8| | 2012-9-9 17:12 | 只看该作者
本帖最后由 chenbb8 于 2012-9-9 17:19 编辑

除开实时还有低功耗的作用呢,休眠加中断,低功耗可以防止发热,这在智能传感器上的MCU比较重要
休眠还可以抵御部分干扰,如果你的系统99.9%的时间都是需要延时的,那么在休眠中等待定时器中断和将这99.9%的时间都用于软件延时 哪个效果好我不清楚,因为我所在的公司里没有EMC的设备:loveliness:
不过看一些单片机的书里,这种休眠抗干扰的做法也是靠谱的。

使用特权

评论回复
8
diweo| | 2012-9-9 17:54 | 只看该作者
在很多重要的控制系统中,常用的做法就是使程序运行时间是固定的,然后系统通过顺序逻辑监视的方法检测程序运行是否正常,其基本原理就是依靠程序的运行时间来判断某个程序是否在运行。

能不能详细说明一下?

使用特权

评论回复
9
zcw9911|  楼主 | 2012-9-9 18:52 | 只看该作者
低功耗系统肯定都是中断触发的,这个是毫无疑问的,但是电池供电的设备毕竟是少数,所以要具体问题具体分析,我的意思是说这种循环的方式并不是那么不堪而已,至于中断在功能安全权威标准里面是尽量减少中断的使用,怎么就被理解成不开中断?当然IEC61508是针对安全设备的,但是其一般的设备也可以借鉴其思想

使用特权

评论回复
10
h0610001210| | 2012-9-9 20:03 | 只看该作者
这个没什么好争论的,就看你用在什么样的场合。比如在LCD操作中,我们通常会插入几个等待的时钟周期。
用for(i=0;i<DelayCnt;++)这种延时,要特别注意,变量DelayCnt不要被编译器优化掉,还有在不同的平台下,延时周期不一定是DelayCnt个机器周期,不同的处理器的取指周期不一样,会造成延时周期不一定是DelayCnt个机器周期。

使用特权

评论回复
11
程序匠人| | 2012-9-9 22:52 | 只看该作者
特殊情况特殊处理

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
hp34401a + 1
12
kseeker| | 2012-9-10 08:37 | 只看该作者
这个方法随时可能被编译器优化掉,每次编译结果可能不同,延时效果随着中断的频率而不断发生变化。
可靠性和稳定性都比基于定时器的方法要差得多,甚至程序的清晰性也要差的多。
要知道,用定时器并不意味着要用中断!

使用特权

评论回复
13
zcw9911|  楼主 | 2012-9-10 09:14 | 只看该作者
精确定时当然要用定时器,我这个帖子还有一层意思,就是写程序不要过分追求技巧性的东西,从架构到语法,技巧性的东西可以学习但是不必要一定要应用,例如 misra-c中对C语言的指针运算做了很严格的限定,只能用于指向数组的指针,虽然限值了灵活性,但是大大提高了可靠性。

使用特权

评论回复
14
jlass| | 2012-9-10 09:16 | 只看该作者
顶楼主
我们做驱动的时候只用for循环做延迟

使用特权

评论回复
15
zcw9911|  楼主 | 2012-9-10 09:23 | 只看该作者
最近一年一直做产品的失效分析和安全级别分析的工作,打算写一些总结性的**,从产品的FMEA分析入手,如何计算产品的平均无故障时间,在结合IEC61508标准计算产品的要求时失效概率,到从硬件设计角度如何提高产品的安全级别

使用特权

评论回复
16
chenbb8| | 2012-9-10 09:24 | 只看该作者
哈哈,刚开始的时候理解错误LZ的意思了。以为LZ反对的是状态机,因为大家都推崇的是状态机,还在想状态机应该可以增强抗干扰的能力的,因为状态量如果给干扰掉了马上就能够发现,怎么成了安全性的负担呢。
回去用了下脑子才记起来当初调试状态机的时候用的还是软件延迟呢:loveliness:
另外操作系统的书中也提到了,抢占式的操作系统会带来任务执行时间的不确定性,这种抢占式的任务调度应该也是不符合LZ说的要求的~

使用特权

评论回复
17
coody| | 2012-9-10 09:36 | 只看该作者
“而这种循环方式的可靠性是高于采用中断方式的”,非常不认同。
LZ估计没做过比较复杂的工业控制系统,同时并发数十上百个控制单元,每个都是可以独立操作的,你用指令死循环延时试试。

很简单的一个例子:纯开关类控制,64点传感器输入,32点开关输出(电磁阀、继电器等等),这32个开关是每个独立操作,可以任意的延时触发、设置输出时间、输出完毕可以触发一些事件,时间为1ms~65535ms。
LZ用指令循环延时看看。

指令循环延时,我一般用在如下两点:
1、演示程序,只说明一种算法或逻辑。
2、非常简单的项目,比如红外遥控器。

使用特权

评论回复
18
litter001| | 2012-9-10 10:05 | 只看该作者
来看看呢,这个好像有帮助哦

使用特权

评论回复
19
zcw9911|  楼主 | 2012-9-10 10:33 | 只看该作者
“而这种循环方式的可靠性是高于采用中断方式的”,非常不认同。
LZ估计没做过比较复杂的工业控制系统,同时并发数十上百个控制单元,每个都是可以独立操作的,你用指令死循环延时试试。

很简单的一个例子:纯开关类控制,64点传感器输入,32点开关输出(电磁阀、继电器等等),这32个开关是每个独立操作,可以任意的延时触发、设置输出时间、输出完毕可以触发一些事件,时间为1ms~65535ms。
---------------------------------------
  像这种大量开关量的设备,也就是使用计数器计时的问题,我的意思是尽量减少中断的使用,如果一个功能能用简单的方法完成,就不用复杂的方法。

使用特权

评论回复
20
joyme| | 2012-9-10 10:52 | 只看该作者
没有绝对好的设计,只有合适的设计
大家说不建议用delay死等,只是一种规范,不是说完全不能用,而且一般是建议不要用长时间的死等延时如ms级别以上的等待
有些时候如果任务是独占的(连中断都要关掉),时序性很强的时候,用delay死等可以

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

147

主题

786

帖子

1

粉丝