博途(TIA Portal)中的SCL(Structured Control Language)是一种基于高级语言(类似Pascal)的文本化编程语言,它功能强大,尤其擅长处理复杂逻辑、数学运算和数据结构。**运算符是SCL构建逻辑和操作数据的核心工具**。下面详细讲解常见运算符及其在PLC编程中的实战案例。
一、SCL运算符分类详解
1. 赋值运算符
:=` (赋值)
功能:将右侧表达式的结果计算出来后,赋给左侧的变量。
示例:
a := 10; // 将整数10赋给变量a
b := a * 2; // 将a*2的结果(20)赋给变量b
motorRunning := TRUE; // 将布尔值TRUE赋给变量motorRunning
strText := 'Hello'; // 将字符串'Hello'赋给变量strText
注意:SCL中没有`=`运算符用于赋值,`=`仅用于比较。
2. 算术运算符
`+` (加)
功能:数值相加或字符串连接。
示例:
sum := value1 + value2; // 数值加法
totalLength := length1 + length2; // 数值加法
fullName := firstName + ' ' + lastName; // 字符串连接 (firstName和lastName需是String类型)
`-` (减)
功能: 数值相减或取负。
示例:
difference := pressureSetpoint - pressureActual; // 数值减法
negativeValue := -positiveValue; // 取负
`*` (乘)**
功能: 数值相乘。
示例:
area := width * height; // 计算面积
totalCost := unitPrice * quantity; // 计算总价
`/` (除)
功能:数值相除。结果类型取决于操作数。
示例 & 重要陷阱:
ratio := numerator / denominator; // 如果两者都是整数(INT, DINT),结果被截断为整数! (e.g., 7 / 2 = 3)
average := REAL(total) / REAL(count); // 要得到浮点数结果,至少一个操作数需转换为REAL/LREAL
实战注意: 整数除法会丢弃小数部分!这是常见错误来源。确保使用`REAL()`或`LREAL()`转换操作数之一或两者,或直接使用`REAL`/`LREAL`变量进行除法运算。
`MOD` (取模)
功能: 返回整数除法的余数。
示例:
remainder := dividend MOD divisor; // e.g., 10 MOD 3 = 1, 7 MOD 2 = 1
// 判断奇偶:
isEven := (number MOD 2) = 0; // 如果余数为0,number是偶数
// 循环计数 (0,1,2,0,1,2...):
cycleCount := (currentIndex MOD 3);
`**` (幂)
功能: 计算左操作数的右操作数次幂。
示例:
square := base ** 2; // 平方
cube := base ** 3; // 立方
result := 10 ** exponent; // 10的exponent次方
注意: 指数通常是整数。对于实数指数,确保操作数是`REAL`或`LREAL`。
3. 比较运算符 (关系运算符)
`=` (等于)
功能: 判断左右操作数是否相等。返回布尔值(`BOOL`)。
示例:
isEqual := value1 = value2;
isZero := currentValue = 0;
isActive := status = 16#01; // 比较状态字是否等于16进制01
`<>` (不等于)
功能:判断左右操作数是否不相等。**返回布尔值(`BOOL`)**。
示例:
isNotEqual := value1 <> value2;
isNotFull := tankLevel <> maxLevel;
`>` (大于), `>=` (大于等于), `<` (小于), `<=` (小于等于)
功能: 比较两个操作数的大小关系。返回布尔值(`BOOL`)。
示例:
isOverTemp := temperature > maxAllowedTemp;
isLowPressure := pressure < minOperatingPressure;
isWarningLevel := level >= warningThreshold;
canStart := readySignal = TRUE AND temperature <= safeStartTemp;
4. 逻辑运算符 (布尔运算符)
`AND` (逻辑与)
功能: 当且仅当所有**操作数为`TRUE`时,结果为`TRUE`。短路求值:如果第一个操作数为`FALSE`,不再计算第二个。
示例:
startPermitted := safetyGateClosed AND emergencyStopReleased AND motorNotRunning;
`&` (按位与 / 逻辑与)
功能:
当操作数是`BOOL`时,等同于`AND` (不短路)。
当操作数是整数类型(`BYTE`, `WORD`, `DWORD`, `LWORD`, `INT`, `DINT`, `USINT`等)时,进行按位与操作。
示例:
// 逻辑与 (BOOL)
resultBool := input1 & input2; // 等同于 input1 AND input2 (但不短路)
// 按位与 (WORD)
filteredStatus := statusWord AND maskWord; // 使用掩码提取statusWord的特定位
specificBit := statusWord AND 16#0008; // 提取第3位 (从0开始计数,16#0008 = 2#0000_0000_0000_1000)
`OR` (逻辑或)
功能: 当至少一个操作数为`TRUE`时,结果为`TRUE`。短路求值:如果第一个操作数为`TRUE`,不再计算第二个。
示例:
alarmActive := overTempAlarm OR lowPressureAlarm OR highVibrationAlarm;
`OR` (按位或)
功能:
当操作数是`BOOL`时,等同于`OR` (不短路)。
当操作数是整数类型时,进行**按位或**操作。
示例:
// 逻辑或 (BOOL)
resultBool := input1 OR input2; // 等同于 input1 OR input2 (但不短路)
// 按位或 (BYTE)
combinedFlags := flagByte1 OR flagByte2; // 合并两个字节的标志位
setBit5 := originalByte OR 16#20; // 将第5位设置为1 (16#20 = 2#0010_0000)
`XOR` (逻辑异或)
功能: 当有且仅有一个操作数为`TRUE`时,结果为`TRUE`。两个都是`TRUE`或都是`FALSE`结果为`FALSE`。无短路。
示例:
isDifferent := (stateA XOR stateB); // 当stateA和stateB不同时为TRUE
toggle := oldState XOR TRUE; // 切换布尔状态 (TRUE变FALSE, FALSE变TRUE)
`XOR` (按位异或)
功能: 当操作数是整数类型时,进行按位异或操作。
示例:
// 按位异或 (DWORD)
flippedBits := dataDWord XOR invertMaskDWord; // 对dataDWord中由invertMaskDWord指定为1的位进行翻转
`NOT` (逻辑非 / 按位取反)
功能:
当操作数是`BOOL`时,进行逻辑非操作。`TRUE`变`FALSE`,`FALSE`变`TRUE`。
当操作数是整数类型时,进行**按位取反**操作(所有位翻转)。
示例:
// 逻辑非 (BOOL)
isNotReady := NOT readySignal;
// 按位取反 (WORD)
invertedWord := NOT originalWord; // 所有0变1,1变0
5. 位运算符 (专门用于整数的位操作)
`AND`, `OR`, `XOR`, `NOT`
如上所述,当操作数是整数类型时,执行按位操作。
`SHR` (逻辑右移)
功能:将整数的二进制位序列**向右**移动指定的位数。左侧空出的位用**0**填充。相当于无符号整数除以2的n次方。
示例:
shiftedRight := inputWord SHR 3; // 将inputWord右移3位
// 提取高字节 (假设inputWord是WORD = 2字节):
highByte := BYTE_TO_WORD(WORD_TO_BYTE(inputWord SHR 8)); // 更常用WORD_TO_BYTE(inputWord SHR 8) 直接得到BYTE
`SHL` (逻辑左移)
功能: 将整数的二进制位序列**向左**移动指定的位数。右侧空出的位用**0**填充。相当于无符号整数乘以2的n次方。
示例:
shiftedLeft := inputByte SHL 2; // 将inputByte左移2位
// 构造一个只有第n位为1的标志:
bitMask := 1 SHL n; // n=0是第0位,n=1是第1位,以此类推
6. 其他运算符
`()` (括号)
功能: 改变运算的优先级,强制先计算括号内的表达式。
示例:
result := (a + b) * c; // 先计算a+b, 再乘以c
valid := (x > min) AND (x < max); // 清晰界定比较范围
`..` (范围)
功能: 用于定义数组索引范围或`CASE`语句中的值范围。
示例:
VAR
arr : ARRAY[1..10] OF INT; // 定义数组索引范围1到10
END_VAR
CASE state OF
0..5: // 当state在0到5之间(包含0和5)
// do something
10, 15, 20: // 当state等于10, 15或20
// do something else
END_CASE;
`:` (类型声明)
功能:用于变量、常量、输入/输出参数等的类型声明。
示例:
VAR
counter : INT; // 声明一个INT类型的变量counter
speed : REAL := 0.0; // 声明并初始化一个REAL变量speed
END_VAR
FUNCTION_BLOCK MyFB
VAR_INPUT
start : BOOL; // 输入参数start类型为BOOL
END_VAR
706

被折叠的 条评论
为什么被折叠?



