| 作者 | 主题 |
|---|---|
|
yanxiao 版主
经验值:28601 发帖数:12143 精华帖:46 |
楼主
主题:一本正经“消灭”双线圈问题
我目前还经常用单片机(MCU)设计一些简单的控制装置,程序是不带操作系统的,直接用C或汇编,对于IO节点,一般是直接操作,没有刻意设计缓存机制,因此,每一个对输出点(Q点)的操作均直接反应在外面。这种简单的输出结构,有双线圈问题吗?我的答案是没有。理由是,持双线圈观点的人认为,双线圈之所以成为问题,是因为“某些Q点操作”无法反应到外面,那么,象这种“直肠子”式的输出结构,不存在这个问题。 我不知道现在还有没“直肠子”输出结构的PLC,如果没有例外,假定PLC的输出Q点都是经过缓存,在某一个时间点才COPY到外界输出。 另外,双线圈问题仅限于输出Q点。虽然Q点和内部的M点等内存位变量没有本质区别,但把双线圈问题扩展到内存M类位变量,其“荒谬性”显而易见。 我使用的程序例子以Smart200的STL语言写成,尽量保持与LAD格式互相转换的结构,不习惯STL语言的,可以COP程序到STEP 7-MicroWIN SMART编程软件,STL显示模式入贴入,再转成LAD显示即可。 双线圈问题,我也不知道从何处入手“破解”。 先从例子入手吧。 假如要实现如下的逻辑式: Q0.0=(I0.0 and I0.1) or I0.2 1、一步到位的写法: 网络1 LD I0.0 // 读取I0.0 A I0.1 // 完成 I0.0 and I0.1 O I0.2 // 上面的结果再 or I0.2 = Q0.0 // 输出 2、分两步,使用中间变量的写法 网络1 LD I0.0 // 读取I0.0 A I0.1 // 完成 I0.0 and I0.1 = M0.0 // 中间变量临时存贮 网络2 LD M0.0 // 读取 I0.0 and I0.1 的结果 O I0.2 // 再 or I0.2 = Q0.0 // 输出 3、分两步,“双线圈”写法 网络1 LD I0.0 // 读取I0.0 A I0.1 // 完成 I0.0 and I0.1 = Q0.0 // 中间变量临时存贮 网络2 LD Q0.0 // 读取 I0.0 and I0.1 的结果 O I0.2 // 再 or I0.2 = Q0.0 // 输出 这三种写法“几乎”等价,“完全”等价是有条件的。 最可能有人提出不等价的情况,是与中断程序的互动,比如中断程序需要读取Q0.0的状态,可能会读取到Q0.0的中间临时值,这个怎么解释呢? 我认为,中断程序与主程序的时序上的关系是不可预测的,如果中断程序和主程序共享变量值,始终有一个数据完整性的问题。如果没有考虑数据完整性,写的程序迟早会埋下定时炸弹。 插入中间变量M0.0,貌似绕开了“双线圈”问题。 我在开始就已经假定了,PLC的Q点是缓冲型的,只在特定的时间点把Q点值COPY到外界输出(有意使用立即输出指令的除外),在用户程序执行阶段,Q点并不与外界相连,此时的Q点是“自由”的。 强调程序“封装”的人,我想他会尽量减少程序对“环境”的影响。 使用Q0.0自身作中间临时变量,相比启用一个额外的M0.0,对环境影响更小,应该是更可取的使用方式。 暂时说这些。各位可以举各种例子来说明问题。 切记:举例子程序时,先说明程序要实现的功能。 无程序功能说明,讨论程序如何如何,无任何意义。 |
|
yanxiao 版主 经验值:28601 发帖数:12143 精华帖:46 |
42楼
主题:回复:一本正经“消灭”双线圈问题我举一个例子,大家看看什么情况下会变得不可靠? 经典的两按钮、一输出的启、保、停。 初始化部分略去。 I0.0:启动按钮,1=按下 I0.1:停止按钮,1=按下 Q0.0:输出,1=启动运行 1、通常的写法 LD I0.0 // 启动 EU // 脉冲型 O Q0.0 // 自保 AN I0.1 // 停止,状态型,停优先 = Q0.0 // 输出 2、R/S写法 网络1 LD I0.0 // 启动 EU // 脉冲型 S Q0.0, 1 // 启动电机 网络2: LDN I0.0 // 停止 R Q0.0, 1 // 停电机 3、“双线圈”写法 网络1 LD I0.0 // 启动 EU // 脉冲型 O Q0.0 // 自保 = Q0.0 // 输出(实际是临时存贮) 网络2 LDN I0.0 // 停止 A Q0.0 // 清自保 = Q0.0 // 输出(最终值) 4、R/S+非全扫描写法 网络1 LD I0.0 // 启动 EU // 脉冲型 NOT // 未发生 JMP 1 // 跳转 网络2 LD Always_On S Q0.0, 1 // 只有在启动按钮按下时,被扫一次 网络3 LBL 1 // 第1个跳转点 网络4 LDN I0.1 // 停止没有按下 JMP 2 // 跳转 网络5 LD Always_On R Q0.0, 1 // 只有停止按钮按下时,才扫描 网络6 LBL 2 // 第二个跳转点 5、“双线圈”+非全扫描写法 网络1 LD I0.0 // 启动 EU // 脉冲型 NOT // 未发生 JMP 1 // 跳转 网络2 LD Always_On = Q0.0 // 置1 网络3 LBL 1 // 第1个跳转点 网络4 LDN I0.1 // 停止没有按下 JMP 2 // 跳转 网络5 LDN Always_On = Q0.0 // 清0 网络6 LBL 2 // 第二个跳转点 请评论可靠性问题。 编码和执行效率,不是本例子的目的。 |