西门子S7-1500学习总结
- 1. 设备组态
- 2. PLC变量定义
- 3 PLC程序块--基本操作指令
- 3.1 逻辑运算
- 3.2 计数器
- 3.3 定时器
- 3.4 移动操作
- 3.4.1 移动值(Move)
- 3.4.2 移动块(Move_BLK)
- 3.4.3 存储区移动(Move_BLK_VARIANT)
- 3.4.4 不可中断存储区移动(UMove_BLK)
- 3.4.5 填充块(FILL_BLK)
- 3.4.6 交换(SWAP)
- 3.4.7 序列化与反序列化
- 3.4.8 数组DB--从ARRAY数据块中读取(ReadFromArrayDB)
- 3.4.9 数组DB--写入ARRAY数据块中(WriteToArrayDB)
- 3.4.10 数组DB--从装载存储器的ArrayDB中读取(ReadFromArrayDBL)
- 3.4.11 数组DB--写入装载存储器的ArrayDB中(WriteToArrayDBL)
- 3.4.12 变量--读出/写入VARIANT变量值(VariantGet/PUT)
- 3.4.12 变量--获取ARRAY元素数量(CountOfElement)
- 3.5 比较操作
- 3.6 数学函数
- 3.7 转换操作
- 3.8 字逻辑运算
- 3.9 移位与循环
- 3.10 程序控制指令
- 4. PLC程序块--扩展操作指令
- 4.1 时间与日期
- 4.2 字符串与字符
- 4.2.1 移动字符串S_MOVE/比较字符串S_COMP/转换字符串S_CONV
- 4.2.2 将字符串转换成数字值STRG_VAL/ 将数字转换成字符串VAL_STRG/ 将字符串转换成数组STRG_TO_CHARS/ 将数组转换成字符串CHARS_TO_STRG
- 4.2.3 确定字符串长度MAX_LEN
- 4.2.4 连接多个字符串JOIN/ 分解成多个字符串:SPLIT
- 4.2.5 ASCII字符串转换十六进制ATH/ 十六进制数转换成ASCII字符串HTA
- 4.2.6 确定字符串长度LEN / MAX_LAN
- 4.2.7 合并字符串CONCAT
- 4.2.7 读取字符串左边的字符LEFT/ 读取字符串右边的字符RIGHT/ 读取字符串中间的字符MID/
- 4.2.8 删除字符串中间的字符DELETE/ 在字符串中插入字符INSERT/ 替换字符串中的字符REPLACE/ 在字符串中查找字符FIND
- 4.3 过程映像
- 4.4 分布式I/O(交换机)
- 4.5 模块参数化分配
- 4.6 中断
- 4.6.1 OB的中断
- 4.6.2 程序中断--将OB附加到中断事件ATTACH/将OB与中断事件脱离DETACH
- 4.6.3 循环中断--设置循环中断参数SET_CINT/查询循环中断参数QRY_CINT
- 4.6.4 时间中断--设置时间中断SET_TINT/取消时间中断CAN_TINT/ 启用时间中断ACT_YINT/ 查询时间中断状态QRY_TINT
- 4.6.6 延时中断--启动延时中断SRT_DINT/取消时间中断CAN_TINT/ 查询延时中断状态QRY_DINT
- 4.6.7 同步错误事件--屏蔽同步错误事件MSK_FLT/不屏蔽同步错误事件DMSK_FLT/ 读出时间状态寄存器RED_ERR
- 4.6.8 异步错误事件--禁用事件DIS_IRT/启用中断事件EN_IRT/ 延时高优先级DIS_AIRT/启用高优先级EN_AIRT
- 4.7 报警
- 4.8 诊断
- 4.9 配方和数据日志
- 4.10 数据块控制
- 5. 寻址(主要用SCL中)
- 6 案例:
1. 设备组态
引言: 对PLC模块进行配置:电源、cpu、开关量输入输出、模拟量输入输出、HMI、通讯等。
1.1 CPU
用来给输入输出分配物理地址
1.2 通讯
PLC的地址应当与主机的地址保持一致(具体操作方法:网络共享中心设置,按照PLC的地址设置好主机的地址,然后WIN+R→cmd→Ping_地址,二者地址统一之后可以下载到PLC中,否则无法下载)
2. PLC变量定义
引言: 定义变量需要注意类型、地址、名称、注释、保持性。
2.1 类型
Name | Type | Longth | Example |
---|---|---|---|
位 | bool | 1 | 0/1 |
字节 | byte | 8 | 1,2,3 等 |
字符 | char | 8 | A,a 等 |
字 | word | 16 | – |
双字 | Dword | 32 | – |
整数 | int | 16 | -1,2,-4 等 |
双整数 | DInt | 32 | – |
浮点数 | real | 32 | 1.1、5.4 等 |
字符串 | string | – | [a,b] 等 |
数组 | array | – | [1,2,3] 等 |
结构 | struct | – | 可嵌套任意类型 |
UDT | – | – | – |
2.2 地址
符号 | 名称 | 方式 |
---|---|---|
I | 输入寄存器 | I0.0-I0.7\IB0\IW0\ID0-I32760.0 |
Q | 输出寄存器 | Q0.0-Q0.7\QB0\IW0\ID0 |
M | 中间寄存器(全局) | M0.0-M0.7\MB0\MW0\MD0 |
L | 临时变量寄存器 | L0.0-L0,7\LB0\LW0\LD0 |
DB | 数据寄存器 | DB1.DBX0.0\DB1.DBB0\DB1.DBW0\SB1.DBD0 |
注:I、Q、M因为都是全局变量所以可以直接在PLC的默认变量表中添加,L是局部的,所以只能在对应程序的OB块(main)中添加,DB只能在DB块中添加。
2.3 名称、注释、保持性
名称:定义变量的名字,关系到程序的运行。
注释:给变量加的注释方便理解,随便写。
保持性:可保持断电重启后数据会保持,不可保持则相反。
3 PLC程序块–基本操作指令
引言:
组织块OB:是主程序,函数FC是子程序,FC单独是无法运行的,必须在OB中调用FC才可以运行,因此FC并没有实际的数值存储。
函数块FB:是可以单独运行的也有自己的数据存储区(背景数据块)。
数据块DB:与变量表几乎一致,但是只有DB块的变量才允许保持。
编程语言:分为FBD、LAD和SCL三种,FBD与LAD是分开的,但是SCL可以使用在任何程序中。SCL适合批量处理数据用。
3.1 逻辑运算
3.1.1 触点与线圈
(1) LAD
(2) FBD
(3) SCL
3.1.2 电机正反转
(1) LAD
(2) FBD
(3) SCL
3.1.3 置位与复位
复位输出R : 信号无论是0还是1都复位为0;(并保持)
置位输出S:信号无论是0还是1都置位为1;(并保持)
复位位域SET:从当前输出的地址开始往后的一直到设置长度全部复位;(并保持)
置位位域RESET:从当前输出的地址开始往后的一直到设置长度全部置位;(并保持)
置位/复位触发器SR:S位置为1,触发器触发,Q启动;R1位复为0,触发器停止,Q停止;同时按下,复位优先则停止。(并保持)
复位/置位触发器RS:R位复为0,触发器停止,Q停止;S1位置为1,触发器触发,Q启动;同时按下置位优先则启动。(并保持)
(1)LAD
(2)FBD
(3)SCL
图为复位/置位触发器RS,复位/置位触发器RS则是将两个if语句换一下顺序。
3.1.4 上升沿与下降沿
上升沿P:数字从0变为1的瞬间(不保持);
下降沿N:数字从1变为0的瞬间(不保持);
上升沿置位:碰到上升沿信号置位为1;
下降沿置位:碰到下降沿信号置位为1;
扫描RLO信号上升沿:
扫描RLO信号下升沿:
检测信号上升沿
检测信号下降沿
上升沿与下降沿的功能几乎一致
3.2 计数器
引言:计数器在FB块和FC块的使用方法是不同的。
3.2.1 FB块–加计数 CTU/减计数 CTD/加减计数 CTUD
- 加计数 CTU
输入:CU-触发加计数、R-复位、PV-赋值(加计数器的累加次数CV≥PV值才可以输出Q)
输出:Q线圈、CV累加次数
- 减计数 CTD
输入:CD-触发减计数器 、LD-false、 PV-赋值(减法计数的初被减始值)
输出:Q-输出(仅在计数≤0时启动)、CV-累计减法计数
- 加减计数 CTUD
输入:CU-加触发 CD-减触发、R-计数器复位成0、LD-把PV值赋值到计数器中 PV-赋值
输出:QU-仅当计数≥PV值时启动、 QD-仅当计数≤0时启动、 CV-计数值
注:SCL和FBD的使用方法与此相同,并且都有集成好模块可以直接调用
3.2.2 FC块–加计数 CTU/减计数 CTD/加减计数 CTUD
- 加计数 CTU
- 减计数 CTD
- 加减计数 CTUD
基本原理,输入输出是一致的,但是FC块的需要建立一个DB数据块保存变量,因为FC块属于临时块,并没有全局的变量,同时也要注意数据类型。
3.3 定时器
引言:
3.3.1 生成脉冲TP
输入:IN-触发条件,PT-定时时间
输出:Q-线圈,ET-时间值
作用:触发条件为1,则触发器启动,启动保持时长为PT,PT保持时长结束后,触发器关闭。但如果触发条件一直为1的话那触发器也只会因为PT时长结束而停止。
3.3.2 接通延时TON
输入:IN-触发条件,PT-定时时间
输出:Q-线圈,ET-时间值
作用:触发条件为1,只有触发条件1一直保持到PT时长,触发器才会启动,并且当触发条件消失之后,触发器就会停止。
3.3.3 关断延时TOF
输入:IN-触发条件,PT-定时时间
输出:Q-线圈,ET-时间值
作用:触发条件为1,只要检测到上升沿,那触发器就会启动,启动PT时长之后关停。如果触发条件1一直保持,那触发器就不会关停,只有检测到下降沿之后,触发器才会停留PT时长然后关停。
3.3.3 时间累加器TONF
输入:IN-触发条件,PT-定时时间,R-复位
输出:Q-线圈,ET-时间值
作用:触发条件为1,检测为1的时长,会累加,比如第一次按3秒,第二次按6秒,最后按1秒,时长达到了设定值PT的10秒触发器就会启动并且一直保持。
3.3.4 启动脉冲定时器
与TP相似
3.3.4 启动接通延时定时器
与TON相似
3.3.5 启动关断延时定时器
与TOF相似
3.3.5 启动时间累加器
其与时间累加器的区别是没有复位,需要添加一个复位定时器。
3.4 移动操作
3.4.1 移动值(Move)
输入:EN-使能输入, IN-输入数值A。
输出:ENO-使能输出 , OUT-输出数值B=A。
3.4.2 移动块(Move_BLK)
输入:EN-使能输入, IN-输入数组A[ ],COUNT-要移动的数组里内容的长度。
输出:ENO-使能输出 , OUT-输出数组B[ ]=A[ ]。
注:批量操作的话使用FC块在DB块中建立一个struct结构体更方便。移动块相当于批量操作移动值。
3.4.3 存储区移动(Move_BLK_VARIANT)
输入:EN-使能输入,SRC-源,COUNT-要移动的数组里内容的长度, SRC_INDEX-源开始的数据首位, DEST_INDEX-目标开始的数据首位B[6]。
输出:ENO-使能输出 , Ret_Val-错误信息提示, DEST-目标,
注:SRC=A[1]-A[10],COUNT=2,SRC_INDEX=5, DEST_INDEX=6, 那么DEST就是B[6]B[7]=A[5]A[6].
3.4.4 不可中断存储区移动(UMove_BLK)
UMove_BLKD的原理与移动块相似,但是其不会被操作系统的其它任务打断,而移动块move_BLK会。
3.4.5 填充块(FILL_BLK)
输入:EN-使能输入, IN-输入变量A,COUNT-要移动的数组里内容的长度4。
输出:ENO-使能输出 位 , OUT-输出数组B[ ]=[ A,A,A,A,]。
3.4.6 交换(SWAP)
输入:EN-使能输入, IN-输入变量A。
输出:ENO-使能输出 , OUT-输出变量B。
注:将A=12先转换成二进制1100的数然后高位与低位交换得到0011,最后B=0011=3。
3.4.7 序列化与反序列化
序列化:将对象转成字节序列。
反序列化:将字节恢复成对象。
注:主要和数据库配合使用。
3.4.8 数组DB–从ARRAY数据块中读取(ReadFromArrayDB)
输入:EN-使能输入, db-要读取的数据块,index-数组DB中被读取的元素的位置
输出:ENO-使能输出 , Ret_Val-错误信息提示, value-一个数组或者一个变量
注释:数组DB和建立变量的DB不同,在建立新的DB块时要选择数组数据DB,不可以选择全局DB。
数组DB(A)=数据块A[0],数据块A[1]–数据块A[10], index=2,那么结果就是A[2]传送给value,value可以是全局DB数据块。但是需要注意数据类型相同。
3.4.9 数组DB–写入ARRAY数据块中(WriteToArrayDB)
输入:EN-使能输入, db-要写入的数据块,index-数组DB中被写入的位置, value-被写入的数据
输出:ENO-使能输出 , Ret_Val-错误信息提示。
3.4.10 数组DB–从装载存储器的ArrayDB中读取(ReadFromArrayDBL)
ReadFromArrayDBL与WriteToArrayDBL一般是同时使用的,应用场景主要是从不常用的大型数据库中调用数据,因此该DBL是不占用控制器主内存的任何空间。装载数据块是对数组DB建立完毕后选择“属性”,里面有选项,选中“仅存储在装载内存中”。
3.4.11 数组DB–写入装载存储器的ArrayDB中(WriteToArrayDBL)
输入:EN-使能输入,req-写入?(上升沿触发),db-要写入的装载数据块,index-装载DB中被写入的位置, value-被写入的数据
输出:ENO-使能输出 , busy-数据还未写入, done-数据已经写入, error-错误信息提示。
3.4.12 变量–读出/写入VARIANT变量值(VariantGet/PUT)
输入:EN-使能输入
输出:ENO-使能输出
读出:从SRC读出放到DST
写入:从DST取出写入SRC
3.4.12 变量–获取ARRAY元素数量(CountOfElement)
输入:EN-使能输入,IN-要查寻的ARRAY
输出:ENO-使能输出 ,RET_VAL-ARRAY的元素数量,如果ARRAY是多维的则输出维度。
3.5 比较操作
3.5.1 等于/不等于/大于等于/小于等于/大于/小于
input可以是个数也可以是一个变量。
- CMP==: 上-input1 and 下-input2 ,选择input的数据类型,然后判断input1=input2则触发;
- CMP<>: 上-input1 and 下-input2 ,选择input的数据类型,然后判断input1≠input2则触发;
- CMP>=: 上-input1 and 下-input2 ,选择input的数据类型,然后判断input1≥input2则触发;
- CMP<=: 上-input1 and 下-input2 ,选择input的数据类型,然后判断input1≤input2则触发;
- CMP> : 上-input1 and 下-input2 ,选择input的数据类型,然后判断input1>input2则触发;
- CMP< : 上-input1 and 下-input2 ,选择input的数据类型,然后判断input1<input2则触发;
3.5.2 值在范围内/值超出范围
输入:MIN-范围下限, VAL-比较值,MAX-范围上限,
输出:IN_Range值在范围内(闭区间比较)则触发,out_Range值在范围外(开区间比较)则触发。
3.5.3 检查有效性/检查无效性
检查浮点数(int)是否有效,input可以是各种变量,但是该块只能识别浮点数,OK检查有效性则触发,NO_OK无效则触发。
有效和无效的判断标准?比如变量是16进制的数,那浮点数则会判断为无效。
3.5.4 检查数据类型/检查数组数据类型/检查NULL/检查ARRAY
- EQ_Type:比较数据类型与变量数据是否相同:上-input1 and 下-input2,如果input1与input2数据类型相同则触发。
- NE_Type:比较数据类型与变量数据是否相同:上-input1 and 下-input2,如果input1与input2数据类型不同则触发。
- EQ_ElemType:比较array中元素数据类型与变量数据是否相同:上-input1 and 下-input2,如果input1中元素数据类型与input2数据类型相同则触发。
- NE_ElemType:比较array中元素数据类型与变量数据是否相同:上-input1 and 下-input2,如果input1中元素数据类型与input2数据类型不同则触发。
- IS_NULL:检查EQUALS NULL指针,检查是否是空值,是空值则触发;
- NOT_NULL:检查UNEQUALS NULL指针,检查是否是空值,不是空值则触发;
- IS_ARRAY:检查是否是数组,是则触发;
3.6 数学函数
3.6.1 加减乘除
- ADD: IN1+IN2+…=OUT
- SUB: IN1-IN2=OUT
- MUL: IN1IN2…=OUT
- DIV: IN1÷IN2=OUT
注:有溢出要如何处理?限制输入输出的最大值或者修改输出的数据类型。
3.6.2 取余/取反/递增/递减/取小数/取幂
- 取余MOD:IN1÷IN2=OUT(OUT是余数)
- 取反NEG: IN=OUT(OUT是-IN的值)
- 递增INC:IN/OUT(执行+1)
- 递减DEC:IN/OUT(执行-1)
- 取小数FRAC:输入in,则OUT获取IN的小数,其余位置不要
- 取幂:输入:IN1,IN2, OUT=IN1为底IN2为指数的数值
3.6.3 绝对值/平方/平方根/对数/指数/sin/cos/tan/arcsin/arccos/arctan
- 绝对值ABS: IN取绝对值=OUT;
- 平方SQR:IN的平方=OUT;
- 平方根SQRT:IN的平方根=OUT;
- 对数LN:e为底的
- 指数EXP:10为指数
- 。。。
3.6.4 获取最小/最大值
- 获取最小值MIN: 输入:IN1,IN2,IN3…=OUT,OUT是最小值;
- 获取最大值Max: 输入:IN1,IN2,IN3…=OUT,OUT是最大值;
3.6.5 设置限值LIMIT
输入:min-下限值,in-输入值,max-上限值
输出:out:如果in大于max则输出max,如果IN小于min则输出min
3.6.6 计算 CALCULATE
自定义运算方式:上面全部的指令都可以使用,交换也可以。
3.7 转换操作
3.7.1 转换值CONV
输入in读取数据类型并根据指令框的数据类型选择进行转换,转换值由OUT输出。比如实现一个a(int类型)转换成b(REAL类型)
3.7.2 取整
- 整数取整ROUND: 四舍五入原则;
- 小数向上取整CEIL:小数位大于0则进向上取,-0.5则为0,0.5为1;
- 小数向下取整FLOOR:小数位大于0则像下取,-0.5则为-1,0.7为1;
- 截尾取整TRUNC:删掉小数后位;
3.7.3 缩放与标准化
- SCALE_X:
输入:IN-输入的变量(4-20mA), HI_LIM-缩放上限(1.7) LO_LIM-缩放下限(0), BOROLAR-如果输入的变量中有负数则输入1,没有复数输入0。
将4-20ma的电流模拟量2.4ma转换成0-1.7的量程内。
输出:ENO-使能, RET_VAL-错误提示, OUT-变量缩放后的值
- NORM_X
就是将量程变成百分比
3.8 字逻辑运算
3.8.1 与/或/异或
- AND: 输入IN1,IN2,out: 有0则0,全1则1;
- OR: 输入IN1,IN2,out: 有1则1,全0则0;
- XOR: 输入IN1,IN2,out: 相同为0,不同为1;
3.8.2 求反码INV/解码ENCO/编码DECO
- 反码INV: 输入:IN=23(十进制)转换成2进制就是00010111,取反码,11101000输出给OUT=232(十进制)
- 解码DECO :IN-必须是无符号int数据类型,out-是二进制数
- 编码ENCO:
3.8.3 选择SEL/多路复用MUX/多路分用DEMUX
- 选择SEL: 两个输入IN0,IN1, 根据开关G选择要输出的信号,G=0,OUT=IN0或G=1,OUT=IN1.
- 多路复用MUX: 多个输入IN0,IN1, … 根据开关K选择要输出的信号,K=0,OUT=IN0或K=1,OUT=IN1,…(最多可以选择32个,就是高级版的选择),ELSE就是当选择的K大于要选择的数的数量,那就把ELSE赋值给OUT
- 多路分用DEMUX:就是多路复用的反过来用.唯一不同的地方就是,输出之后并不会自动复位,比如当前选择K是4,但是之前K选过0所以在OUT0处的数值并不会自动复位。
3.9 移位与循环
3.9.1 左移SHL/右移SHR
将IN的内容按位向左移或者向右移动,N表示要移动的位数。OUT是移动之后的结果。如果N的值大于IN的全部位数则IN值将向左或向右移动,比如IN是8位,N是10,那么则先移动8位,再移动2位。最后的一位数会跳转到最前面。
3.9.1 循环左移ROL/循环右移ROR
将IN的内容按位向左移或者向右移动,N表示要移动的位数,按照N的长度一直移动,但是OUT输出连接的必须是IN这个变量。相当于是自己移动自己。
3.10 程序控制指令
3.10.1 跳转JMP/JMPN
JMP是等于1跳转,JMPN是等于0跳转,其会从当前程序段跳转到指定标签LABEL的位置。
注:跳转指令的名称与标签的名称必须一致并且不可以重复。
3.10.2 定义跳转列表JMP_LIST
输入K=0的时候跳转到DEST0, 输入K=1的时候跳转到DEST1,K=2的时候跳转到DEST2,…是一种多跳转指令
3.10.3 跳转分支SWITCH
比较K与下面输入的数,可以是大于,也可以是等于,等等,满足条件才可以跳转到后面的标签LABLE中。
3.10.4 返回RET
为0时返回或者为1时返回都可以,返回到程序开始的地方,后面的程序不执行
3.10.5 ENDIS_PW/ RE_TRIGR/ STP/ GET_ERROR/ GET_ERR_ID/ INIT_RD/ WAIT/ RUNTIME
- ENDIS_PW: 限制和启用密码合法性:控制读写的访问权和HMI访问权
输入:REQ=1,允许下面的输入进入到块中;REQ=0则不允许;F_PWD表示读写访问权(安全故障),FULL_PWD表示读写访问权,R_PWD表示读访问权,HMI_PWD表示HMI的访问权。输出就是与上面一一对应的关系,哪位值为1,哪个输出,并会给相应权限。 - RE_TRIGR:重置周期监测时间:定期检查CPU工作状态,如果不工作则重启CPU工作。
- 退出程序:STP:直接停止CPU工作
- 获取本地错误:GET_ERROR: 主要告诉客户故障信息。
- 获取本地错误ID:GET_ERR_ID: 主要告诉客户故障信息。
- 初始化保留所有数据:INIT_RD: 初始化程序,但保留程序之前的数据,只能再OB中执行。
- 组态延时时间:WAIT:就是再程序运行的过程中暂停一段时间,时间结束后继续运行,设置的暂停时间时长WT的单位时微秒。
- 测量程序运行时间:RUNTIME。
4. PLC程序块–扩展操作指令
4.1 时间与日期
4.1.1 比较时间变量T_COMP
比较时间大小,IN1-时间1, IN2-时间2,经过块中的比较指令判断OUT。(记得选数据类型)
4.1.2 转换时间并提取T_CONV
将输入的时间类型根据框中的类型定义转换,然后通过OUT输出。
4.1.3 时间相加T_ADD/时间相减T_SUB
只能是毫秒相加减
4.1.4 时差T_DIFF/组合时间T_COMBINE
- 时差T_DIFF:计算日期的相减
- 组合时间T_COMBINE:计算日期相加
4.1.5 时钟–设置时间WR_SYS_T/读取时间RD_SYS_T
- 设置时间WR_SYS_T: 往CPU里写入时间;
- 读取时间RD_SYS_T:读取CPU时间;、
4.1.6 时钟–写入本地时间WR_LOC_T/读取本地时间RD_LOC_T
4.1.7 时钟–设置时区SET_TIMEZONE
4.1.7 时钟–读取系统时间TIME_TCK/ 运行时间定时器RTM
- TIME_TCK: 读取CPU上电之后运行的时间。
- RTM:
4.2 字符串与字符
4.2.1 移动字符串S_MOVE/比较字符串S_COMP/转换字符串S_CONV
移动字符串S_MOVE:IN:“abcd”;OUT:“abcd”;
比较字符串S_COMP:IN1:“abcd”,IN2:“abcdef”; 判断:==? (自行选择比较指令); OUT:比较结果(false);
转换字符串S_CONV:IN:“1234”(字符串);OUT:1234(数值);IN:“abcd”(字符串);OUT:false(不识别);
4.2.2 将字符串转换成数字值STRG_VAL/ 将数字转换成字符串VAL_STRG/ 将字符串转换成数组STRG_TO_CHARS/ 将数组转换成字符串CHARS_TO_STRG
- STRG_VAL: IN:“123”, FORMAT:(选择要转换的类型。0表示整数,1表示小数,2表示指数) P: 从第几位开始转换,超出字符串长度则输出0; OUT:输出数值
- VAL_STRG:IN:“1234”,SIZE:2 限制字符串的位数, PREC :小数位数 FORMAT:(选择要转换的类型。0表示整数,1表示小数,2表示指数) P: 从第几位开始转换,超出字符串长度则输出0; OUT:输出数值.
- STRG_TO_CHARS: Strg:“12345” , pChars: 到第几位停止,比如输入3,那么CHARS[1,2,3,1,2,3,4,5,…],图片中是输入0,Chars:拆分后的字符写入CHARS; Cnt:Chars的最后一位数值
- CHARS_TO_STRG:与上类似
4.2.3 确定字符串长度MAX_LEN
一个字符2个位,IN:“1234”,OUT:8.
4.2.4 连接多个字符串JOIN/ 分解成多个字符串:SPLIT
- JOIN: MODE- 合并字符串的方式,RECSEP-源字符串分隔符, ENDSWP- 转换末尾字符串分隔符,SrcS-指向源字符串的指针 COUNT-要连接字符串的数量, DST- 转换之后写入的区域,POS-字符串的位置索引;RET_Val-报错状态。
- SPLIT:与上面类似就是将数组字符串拆解成单个字符串
4.2.5 ASCII字符串转换十六进制ATH/ 十六进制数转换成ASCII字符串HTA
ATH: IN-字符串 N-修改字节的位数; RET_VAL-错误提示 OUT-输出16进制
2. HTA: 使用方法一致。
4.2.6 确定字符串长度LEN / MAX_LAN
包括两个长度,最大长度MAX_LAN和当前长度LEN
4.2.7 合并字符串CONCAT
4.2.7 读取字符串左边的字符LEFT/ 读取字符串右边的字符RIGHT/ 读取字符串中间的字符MID/
4.2.8 删除字符串中间的字符DELETE/ 在字符串中插入字符INSERT/ 替换字符串中的字符REPLACE/ 在字符串中查找字符FIND
4.3 过程映像
4.3.1 更新过程映像输入UPDATE_PI/ 更新过程映像输出UPDATE_PO
- UPDATE_PI: PART- 待更新的输出过程映像分区的数量(需要在组态画面–输出–属性–输出0-31–IO地址–过程映像–pipx); RET_VAL- 错误提示,FLADDR-
这样设置之后,外部数据改变,cpu的数据不会更新,只有在UPDATE_PI触发的条件下,外部数据改变CPU内部数据才会更新。 - UPDATE_PO:与UPDATE_PI相似,设置之后数据不会立即输出,需要模块触发才能输出。
4.4 分布式I/O(交换机)
引言:分布式I/O又是一种设备,适合远距离通讯,在PLC和I/O中间加入一个分布式I/O模块就可以使用网线直接将I/O的数据传送到CPU上。
4.4.1 分布式I/O组态
step1: 首先需要有GSD文,官网下载,不同的分布式I/O有不同的GSD文件,必须要和软件相匹配。下载之后解压,不要改名字。
step2: 导入GSD文件。主界面-选项–管理通用站描述文件–找到解压后的文件–安装
step3:打开组态画面–硬件目录–分布式I/O(如果不是西门子的分布式I/O那就去其它现场设备–PROFINET IO-- I/O 中找)–拖到组态画面中–组态连接。
step4:修改分布式I/O的IP地址,与CPU保持一个网段。然后再属性中给分布式I/O分配地址。
step5:在分布式I/O硬件上找到其MAC地址,然后回到组态画面–右键分布式I/O–为设备分配名称–更新列表–选择与mac地址相同那个–分配名称。
step6: 在线与诊断–分配IP地址,无需更改。
4.4.2 分布式I/O指令–读取数据记录RDREC/ 写数据记录WRREC
- 读取数据记录RDREC:输入: REQ-=1传输数据、=0不传输, ID-去组态画面-分布式I/O–属性–硬件标识符–274, INDEX-16#AFF0, MLEN- ,RECORD-需要单独建立一个结构体里面的信息看帮助; 输出:VALID- BUSY- ERROR- STATUS- LEN-
- 写数据记录WRREC:与读取相似。
4.4.2 分布式I/O指令–读取过程映像GETIO/ 传送过程映像SETIO
4.4.3 分布式I/O指令–启用/禁用DP从站D_ACT_DP
输入:REQ- =1启用,MODE-=0请求寻址、=1启用、=2禁用, LADDR- 去组态画面-分布式I/O–属性–硬件标识符–274,输出:BUSY-目前状态表示。
4.5 模块参数化分配
4.5.1 读取模块数据记录RD_DPAR
REQ-触发, LADDR-硬件标识符,INDEX- RECORD-去帮助里面看结构体如何定义。
输出:VALID- BUSY- ERROR- STATUS- LEN-
4.6 中断
引言:中断时独立于主程序OB的,是单独运行的程序,只要事件使能,中断便会执行,但是一般由主程序进行使能,主要用于故障。中断的优先级别大于OB1(优先级是可以设置的,数值越大,优先级越高)
4.6.1 OB的中断
直接创建一个OB块就好了无需编辑程序,系统会自动运行。
4.6.2 程序中断–将OB附加到中断事件ATTACH/将OB与中断事件脱离DETACH
- EN: 程序使能,OB_NR:OB中断的类型,EVENT:OB中断触发条件(需要去组态画面-常规-输入-通道里面选择),ADD:中断是否执行.
当上升沿时,将OB40这个中断附加给主程序 - DETACH:OB_NR:OB中断的类型,EVENT:OB中断触发条件(需要去组态画面-常规-输入-通道里面选择)
当下降沿时,将OB40中断从主程序中退出
4.6.3 循环中断–设置循环中断参数SET_CINT/查询循环中断参数QRY_CINT
- SET_CINTOB_NR:输入:OB中断类型(OB30), CYCLE:时间间隔(毫秒)–去OB30中查找设置,PHASE:相位偏移量–去OB30中查找设置。
作用是在CYCLE归定的时间内,一直循环扫描,出现问题就执行中断,继续扫描,出现问题继续中断。 - QRY_CINT
作用就是查询循环中断的参数,没用。
4.6.4 时间中断–设置时间中断SET_TINT/取消时间中断CAN_TINT/ 启用时间中断ACT_YINT/ 查询时间中断状态QRY_TINT
- SET_TINT:输入:OB_NR:OB中断类型(OB11); SDT:开始的时间与日期; PERIOD:见帮助,不同的序号对应不同的功能,比如W#16#0000=执行一次,0201=一分钟一次,0401=一小时一次等等。
- 启用时间中断ACT_YINT:输入就是OB_NR,在启用状态下SET_TINT可以用。
- 设置时间中断2_SET_TINTL:其比SET_TINT输入多了LOCAL(=1使用本地时间,=0使用系统时间)和ACTIVATE(=1自动激活时间中断,=0只有在调用的时候激活)。
- 取消时间中断ACT_YINT:输入就是OB_NR,在取消状态下SET_TINT不可用。
- 查询时间中断状态QRY_TINT:输入就是OB_NR; 输出:STATUS不同数字代表不同状态,详细见帮助。
4.6.6 延时中断–启动延时中断SRT_DINT/取消时间中断CAN_TINT/ 查询延时中断状态QRY_DINT
- SRT_DINT: OB_NR:中断类型; DITIME:在时间超过DITIME时执行延时中断OB; SIGN调用OB启动时的标识符,启动了是1,未启动是2。
- 取消时间中断CAN_TINT:与取消时间中断类似。
- 查询延时中断状态QRY_DINT:与查询时间中断状态类似。
4.6.7 同步错误事件–屏蔽同步错误事件MSK_FLT/不屏蔽同步错误事件DMSK_FLT/ 读出时间状态寄存器RED_ERR
- MSK_FLT:输入:PRGFLT: 要屏蔽编程错误; ACCFLT:要屏蔽访问错误。输出:PRGFLT: 已屏蔽编程错误; ACCFLT:已屏蔽访问错误.
- DMSK_FLT: 与MSK_FLT刚好相反。
- RED_ERR: 与MSK_FLT功能类似,只不过输出是显示不是屏蔽。PRGFLT: 显示已发生编程错误; ACCFLT:显示已发生的访问错误.
4.6.8 异步错误事件–禁用事件DIS_IRT/启用中断事件EN_IRT/ 延时高优先级DIS_AIRT/启用高优先级EN_AIRT
- DIS_IRT:不会调用中断和异步错误,输入:MODE表示要禁用的中断和异步错误的类型、。
- EN_IRT:与DIS_IRT相反。
- DIS_AIRT和EN_AIRT无用
4.7 报警
可以用于Web端查看报警状态。(组态画面CPU–属性–Web服务器–启用模块上的Web服务器–用户管理–新建一个用户–然后里面的选项全部启用–设置密码。然后打开浏览器–输入IP地址就可以进入西门子的一个界面–点击左上角下载证书–安装证书–然后点击进入–登录(之前设置的就是用户名和密码)–最后就会显示如下页面,就可以查看报警信息。)
4.7.1 生成具有相关值的程序报警Program_Alarm
Program_Alarm只能在FB程序块中添加。
输入:SIG:启用Program_Alarm, TIMESTAMP: 时间日期。SD_1输出:ERROR:有无错误 STATUS:显示错误信息。
4.7.2 输出报警状态Get_AlarmAtate
Get_AlarmAtate:与Program_Alarm联用,显示Program_Alarm的报警信息状态
4.7.2 生成用户诊断报警Gen_UsrMsg
Gen_UsrMsg:输入:Mode:=1到达的报警=0离去的报警; TextID:报警文本 TextListID :报警文本。AssocValues:直接创建一个这样的数据类型又来存放报警信息(TextLISTIO+ TextID组合的显示)。
Gen_UsrMsg也要与Program_Alarm联用。
4.8 诊断
4.8.1 读取当前OB启动信息RD_SINFO/读取运行系统统计RD_INFO
- RD_SINFO:主要是读取OB的信息,比如OB的编号等等
输出:TOP_SI: 当前启动OB的信息,STATR_UP_SI:上一时刻启动OB的信息。
- RD_INFO: 读取的是OB的运行状态信息,是动态的,比如运行的时长等等。
输入:MODE:是希望读取的信息,OB:读取的OB块,INFO:输出OB的运行状态信息。
4.8.2 读取LED状态LED/读取标识及维护数据GET_IM_Data/读取IO设备或DP从站名称GET_NAME/读取IO设备的信息GetStationInfo/读取SIMATIC存储卡信息GETSMCinfo
- LED: 输入:LADDR:固定的,是CPU的硬件标识符(组态–cpu–属性–系统常数)。LED:读取LED状态。
- GET_IM_Data:LADDR:固定的。IM_TYPE:固定的,详见帮助,DATA:读取出来的标识及维护数据(详见帮助)。输出:DONE BASY ERROR STATUS
- GET_NAME: LADDR:固定的(IO设备或DP从站的标识符)。STATION_NR:固定的(IO设备或DP从站的编号)。DATA:读取出来的名称(详见帮助).输出:DONE BASY ERROR STATUS。
- GetStationInfo: REQ:使能,LADDR:固定的IO设备的标识符。MODE:=1,IP地址,=2MAC地址。输出:DONE BASY ERROR STATUS。
- GETSMCinfo:REQ:使能。MODE:固定的,见帮助。输出:DONE BASY ERROR STATUS。
4.8.3 读取IO系统模块信息DeviceStates/读取模块状态信息ModuleStates
- DeviceStates:输入:LADDR:PROFINET IO或DP主站系统的硬件标识符。 MODE: 选择要读取的状态信息,参考说明书。 STATE: IO或DP从站状态缓冲区,参考说明书。DeviceStates:可以实时读取站点的状态信息,STATE
- ModuleStates:使用方法与DeviceStates类似。
4.9 配方和数据日志
4.9.1 导出配方RecipeExport/导入配方
- 导出配方RecipeExport:输出:REQ:上升沿使能,RECIPE_DB:配方的内容。输出:DONE BASY ERROR STATUS。
首先要先建立一个PLC数据类型命名为配方,
然后再该列表下定义变量,只可以用英文。
然后建立一个数据块DB(命名为RECIPE_DB)存放这个数据,最好用数组(长度选择1-5)。
然后把建立好的数据块DB与RECIPE_DB连接.
使用wed浏览器中的–文件浏览器就可以查询到导出配方的CSV文件。
- 导入配方RecipeIMport:使用方法就是将上述过程反转。先将csv文件的内容修改(复制导出的内容在下载,因为其内容是有格式的,自己直接编辑内容会报错),然后再wed上上传文件。RecipeIMport的使用方法与RecipeExport一致。
4.9.2 创建数据日志DataLogCreate/ 打开数据日志DataLogOpen/ 写入数据记录DataLogWrite/ 清空数据记录DataLogClear/ 关闭数据日志DataLogClear/ 删除数据日志DataLogDelete/ 新文件中的数据记录DataLogNewFile
- DataLogCreate:输入:RECORDS:数据记录的最大数量。 RORMAT:数据格式=1为CSV文件=0为内部格式。TIMESTAMP:=0无时间戳,=1有时间戳。NAME:数据名称。ID:数据记录。HEADER:标题。DATA:数据写入的指针。输出:输出:DONE BASY ERROR STATUS。然后可以去WEB端下载生成的日志
- DataLogOpen:必须先用DataLogCreate生成日志,才能打开。
- DataLogWrite:必须先用DataLogOpen打开日志,才能往里写入数据记录。
- DataLogClear:必须先用DataLogOpen打开日志,才能清除数据记录。
- DataLogClear:关闭数据日志。
- DataLogNewFile:就是创建一个与现有的数据日志相同的数据日志,可以保留原日志的内容。
4.10 数据块控制
4.10.1 DB数据块操作
- 创建数据块CREATE_DB
然后根据帮助设置改块的输入输出。运行之后可以发现在CPU中创建了新的数据块。
此时的数据块已经变成了装载数据块DBL,接下来对DBL进行读取等操作。
4.10.2 DBL装载存储器操作
- 读取DBL装载存储器READ_DBL
从创建好的DBL中读取:
- 写入到DBL装载存储器WRITE_DBL
在WRITE中手动写入数据
然后再执行一次读取的操作就可可以写入DBL中。
4.10.2 读取DB数据块属性ATTR_DB与删除数据块DELETE_DB
- 读取DB数据块属性ATTR_DB:没什么用,看说明书即可。
- SHANCHU DB数据块
5. 寻址(主要用SCL中)
5.1 直接寻址
A[1]-B[1],A[2]-B[2],…一对一的关系,A[1]改变B[1]改变
5.2 间接寻址
A[i]–B[1],A[i]–B[2]。当索引值i=1时,只有A[i]–B[1],索引值i=2时只有A[i]–B[2].
6 案例:
6.1 计数器亮灯
要求:1、只使用1个按钮,每按下按钮1依次让指示灯1→指示灯2→…→指示灯10亮灯。2、使用另一个按钮,每按下按钮2依次让指示灯10→指示灯9→…→指示灯1亮灭。3、按下复位按钮程序复位,恢复到初始状态。
因为SDL与FBD都有集成的计数器模块,因此可以直接使用。
6.2 电机顺序启停(LAD与SCL)
要求:1、按下启动按钮,电机A启动; 延时5s后电机B启动; 延时4s后电机C启动,指示灯频率闪烁。2、按下停止按钮后电机C停止,指示灯停止闪烁延时3s后电机B停止; 延时3s后电机A停止。3、按下复位按钮恢复到初始状态
SCL方法
//电机A启动
IF "启动" = TRUE THEN
"电机A" := 1;
END_IF;
//电机B启动
IF "电机A"=TRUE THEN
"数据块_1".电机B.TON(IN := 1,
PT := T#5S,
Q => "电机B");
END_IF;
//电机C启动
IF "电机B"=TRUE THEN
"数据块_1".电机C.TON(IN := 1,
PT := T#4S,
Q => "电机C");
END_IF;
IF "电机C" = 1 AND "Clock_1Hz" = TRUE THEN
"指示灯" := 1;
END_IF;
//电机C停止,电机B停止,电机A停止
IF "停止"=TRUE THEN
"电机C" := 0;
"数据块_1".电机B停.TON(IN := "停止",
PT := T#3S,
Q => "电机B");
"数据块_1".电机A停.TON(IN := "停止",
PT := T#6S,
Q => "电机A");
END_IF;
//复位
IF "复位" = TRUE THEN
"电机A" := 0;
"电机B" := 0;
"电机C" := 0;
END_IF;