发布于 2012-07-24 09:18:52
32楼
今天有点时间,我也写了一下。使用STL,注释比较方便,但程序能转成LAD。
ORGANIZATION_BLOCK 主程序:OB1
TITLE=注释:
// 1、输出点能在有限的资源内任意使用。
// 输出点M、V、Q区均可,从0.0开始编号,连续,编号为16位编码,共可表达65536个点;
// 2、顺序步数可以在有限的储存空间内任意设置。
// 这个就认为很有限,最大256个步数应该足够了,1个字节表达,从VB0开始连续存放,每个步数只出现1次,填0表示不动作。如果本步没有可输出的点,虽然不动作,但也占节拍。
//
BEGIN
Network 1 // 上电
// 1、上电,清掉相关的变量
// 2、没有清输出点。如果有必要,加入些部分程序。
LD SM0.1
R M0.0, 1
Network 2 // 启动
// 1、假定以I0.0的上升沿启动一个动作序列,中间没有停止/再启动逻辑,直到一个序列动作完成。
//
LD I0.0
S M0.0, 1 // =1表示序列进行中
S M0.1, 1 // =1表示此刻执行动作
MOVB 0, VB1000
MOVB 16#FE, VB1001 // 在此填第一个动作点在字节内的位置,比如FE表示0.0位
MOVD &QB0, VD1008 // 第一输出点所在的字节指针
Network 3 // 执行动作
// 1、M0.1=1表示要执行动作
// 2、For..Next循环在条件不成立时,会整个跳过,这在Automann的另一贴中研究过。
LD M0.0 // 整个动作序列的允许位
A M0.1
R M0.1, 1 // 下面的指令序列只执行1次
R T33, 1 // 间隔定时器复位
ANDB VB1001, *VD1008 // 前一节拍的动作点复位
LPS
AB> VB1001, 4 // 是否到终点,(步长数-1),2012。07。25修改
R M0.0, 1 // 到终点后,清掉序列允许位
LPP
A M0.0
INCB VB1000 // 本次要执行的节拍序号。先INCB,保证序号从非0开始。
MOVD &VB0, VD1004 // 初始化查找指针
FOR VW1002, 0, 4 // 表长在此设定,可以用变量。注意Index是从0开始,方便下面计算。表长也是事先-1
Network 4 // 查找
// 1、节拍序号被存放在VB0开始的连续单元中
LDB= VB1000, *VD1004 // 如果对应的节拍存在
JMP 10 // 跳出循环
NOT
INCW VW1006 // 指针移动一个位置。此处使用区内偏移增1方式。
Network 5 // 循环
NEXT
Network 6 // 没查到
// 1、如果是正常结束循环,表示当前节拍序号没有在表中查到,本节拍为空节拍。
LD SM0.0
JMP 20
Network 7 // 标号
LBL 10
Network 8 // 查到
// 1、如果程序进到此处,表示本节拍要执行的点在表中
// 2、存点的序号存在VW300开始的单元,连续存放
LD SM0.0
MOVD &VB300, AC1
+I VW1002, AC1 // VW300的表地址增量为2
+I VW1002, AC1 // 合成指针,找到那个输出点序号
MOVW *AC1, AC0
ANDB 16#07, AC0
DECO AC0, AC2 // 解码输出点在字节内偏移
MOVW *AC1, AC0
SRW AC0, 3 // 右移3位,相当于无符号数/8
MOVD &QB0, AC1 // 第一个第出点所在的字节指针
+I AC0, AC1 // 现在*VD1008指向本节拍所要动作的输出点所在字节
ORB AC2, *AC1 // 输出节点=1
INVB AC2
MOVD AC1, VD1008 // 保存此输出点的位置,下一个节拍开始时清掉输出
MOVB AC2, VB1001
Network 9 // 标号
LBL 20
Network 10 // 定时间隔
LD SM0.0
TON T33, 100 // 1秒钟
Network 11 // 定时到,处理下一个点
LD T33
A M0.0
S M0.1, 1
END_ORGANIZATION_BLOCK