📊 一、ST语言数据类型概览
1. 基本数据类型
| 类型 | 大小 | 范围 | 说明 |
|---|---|---|---|
| BOOL | 1位 | TRUE/FALSE | 布尔值 |
| BYTE | 8位 | 0..255 | 无符号字节 |
| WORD | 16位 | 0..65535 | 无符号字 |
| DWORD | 32位 | 0..4.29e9 | 无符号双字 |
| LWORD | 64位 | 0..1.84e19 | 无符号四字 |
| SINT | 8位 | -128..127 | 有符号短整型 |
| USINT | 8位 | 0..255 | 无符号短整型 |
| INT | 16位 | -32768..32767 | 有符号整型 |
| UINT | 16位 | 0..65535 | 无符号整型 |
| DINT | 32位 | -2.14e9..2.14e9 | 有符号双整型 |
| UDINT | 32位 | 0..4.29e9 | 无符号双整型 |
| LINT | 64位 | -9.22e18..9.22e18 | 有符号长整型 |
| ULINT | 64位 | 0..1.84e19 | 无符号长整型 |
| REAL | 32位 | ±3.4e±38 | 单精度浮点数 |
| LREAL | 64位 | ±1.7e±308 | 双精度浮点数 |
| TIME | - | - | 时间间隔(如 T#5s) |
| DATE | - | - | 日期(如 D#2024-01-01) |
| TIME_OF_DAY | - | - | 时间点(如 TOD#10:30:00) |
| STRING | 可变 | 0..255字符 | 字符串 |
| WSTRING | 可变 | 0..16383字符 | 宽字符串(Unicode) |
2. 复合数据类型
st
// 数组
VAR
arr1: ARRAY[1..10] OF INT; // 一维数组
arr2: ARRAY[1..5, 1..3] OF REAL; // 二维数组
END_VAR
// 结构体
TYPE MyStruct:
STRUCT
x: INT;
y: REAL;
flag: BOOL;
END_STRUCT
END_TYPE
// 枚举
TYPE Colors:
(
Red := 0,
Green := 1,
Blue := 2
);
END_TYPE
💻 二、C#语言数据类型概览
1. 基本值类型
| 类型 | 大小 | 范围 | 对应 .NET 类型 |
|---|---|---|---|
| bool | 1字节 | true/false | System.Boolean |
| byte | 1字节 | 0..255 | System.Byte |
| sbyte | 1字节 | -128..127 | System.SByte |
| short | 2字节 | -32768..32767 | System.Int16 |
| ushort | 2字节 | 0..65535 | System.UInt16 |
| int | 4字节 | -2.14e9..2.14e9 | System.Int32 |
| uint | 4字节 | 0..4.29e9 | System.UInt32 |
| long | 8字节 | -9.22e18..9.22e18 | System.Int64 |
| ulong | 8字节 | 0..1.84e19 | System.UInt64 |
| float | 4字节 | ±3.4e±38 | System.Single |
| double | 8字节 | ±1.7e±308 | System.Double |
| decimal | 16字节 | ±7.9e28 | System.Decimal |
| char | 2字节 | U+0000..U+FFFF | System.Char |
2. 引用类型
csharp
string str = "Hello"; // 字符串
object obj = new object(); // 对象
dynamic dyn; // 动态类型
🔄 三、核心区别对比
1. 设计哲学差异
| 方面 | ST语言 (PLC) | C# (.NET) |
|---|---|---|
| 设计目标 | 实时控制,确定性 | 通用应用开发 |
| 运行环境 | PLC硬件,资源受限 | CLR/.NET,资源丰富 |
| 执行模型 | 扫描周期,硬实时 | 事件驱动,软实时 |
| 内存管理 | 静态分配为主 | 垃圾回收,动态管理 |
| 安全要求 | 功能安全 (IEC 61508) | 类型安全,内存安全 |
2. 数据类型具体对比
a) 布尔类型
st
// ST: 1位,严格TRUE/FALSE
VAR
b1: BOOL := TRUE;
END_VAR
csharp
// C#: 1字节,true/false小写
bool b1 = true;
b) 整型类型**
st
// ST: 明确位宽,多种选择
VAR
a: SINT := 127; // 8位有符号
b: INT := 32000; // 16位有符号
c: DINT := 1000000; // 32位有符号
END_VAR
csharp
// C#: 使用short/int/long等
sbyte a = 127; // 8位有符号
short b = 32000; // 16位有符号
int c = 1000000; // 32位有符号
long d = 1000000000; // 64位有符号
c) 浮点类型**
st
// ST: REAL (单精度) 和 LREAL (双精度)
VAR
f1: REAL := 3.14;
f2: LREAL := 3.14159265359;
END_VAR
csharp
// C#: float (单精度) 和 double (双精度)
float f1 = 3.14f; // 需要f后缀
double f2 = 3.14159265359;
decimal f3 = 123.456m; // 高精度十进制,ST无对应类型
d) 时间类型**
st
// ST: 专门的时间数据类型
VAR
t1: TIME := T#5s; // 5秒时间间隔
d1: DATE := D#2024-01-01; // 日期
tod1: TIME_OF_DAY := TOD#10:30:00; // 时间点
END_VAR
csharp
// C#: 使用DateTime和TimeSpan
TimeSpan t1 = TimeSpan.FromSeconds(5);
DateTime d1 = new DateTime(2024, 1, 1);
TimeSpan tod1 = new TimeSpan(10, 30, 0);
e) 字符串类型
st
// ST: 定长或可变长,通常有长度限制
VAR
s1: STRING(20) := 'Hello'; // 最大20字符
s2: WSTRING(50) := "世界"; // Unicode字符串
END_VAR
csharp
// C#: 动态长度,内存中管理
string s1 = "Hello";
string s2 = "世界";
// C#字符串长度几乎无限制
f) 数组类型**
st
// ST: 索引范围可自定义,多维
VAR
arr1: ARRAY[1..10] OF INT; // 索引1-10
arr2: ARRAY[0..4, 0..2] OF REAL; // 二维数组
END_VAR
csharp
// C#: 索引从0开始
int[] arr1 = new int[10]; // 索引0-9
int[,] arr2 = new int[5, 3]; // 二维数组
int[][] jagged = new int[5][]; // 交错数组(ST无)
g) 结构体**
st
// ST: STRUCT(类似C语言)
TYPE Point:
STRUCT
x: INT;
y: INT;
END_STRUCT
END_TYPE
csharp
// C#: struct(值类型)或class(引用类型)
// 值类型结构体
public struct Point
{
public int X;
public int Y;
}
// 引用类型类
public class PointClass
{
public int X { get; set; }
public int Y { get; set; }
}
3. 类型转换对比**
ST:显式转换函数
st
VAR
i: INT := 100;
r: REAL;
END_VAR
r := INT_TO_REAL(i); // 必须使用转换函数
C#:隐式和显式转换
csharp
int i = 100;
float f1 = i; // 隐式转换
float f2 = (float)i; // 显式转换
float f3 = Convert.ToSingle(i); // 使用Convert类
4. 特殊类型对比
| 类型 | ST语言 | C#语言 | 说明 |
|---|---|---|---|
| 枚举 | 基于整数,类型安全 | 基于整数,类型安全 | 两者相似 |
| 指针 | 支持,但少用 | unsafe支持指针 | ST用于硬件访问 |
| 函数块 | 特殊数据类型 | 无直接对应 | PLC特有 |
| 任务 | 特殊数据类型 | Thread/Task类 | PLC任务 vs .NET任务 |
| 引用 | REFERENCE类型 | ref/out参数 | 概念相似 |
⚠️ 四、关键注意事项
1. 数值范围陷阱
st
// ST: 溢出可能不会被检测
VAR
a: INT := 32767;
b: INT;
END_VAR
b := a + 1; // 可能变为-32768(无异常)
csharp
// C#: 默认不检查,但可配置
int a = int.MaxValue;
int b = a + 1; // 溢出,结果为负数
int c = checked(a + 1); // 抛出OverflowException
2. 字符串处理
st
// ST: 字符串操作函数有限
s1 := CONCAT('Hello', 'World');
len := LEN(s1);
csharp
// C#: 丰富的字符串API
string s1 = "Hello" + "World";
int len = s1.Length;
string sub = s1.Substring(0, 5);
3. 时间处理
st
// ST: 时间直接参与运算
t1 := T#5s + T#10s; // 结果为T#15s
csharp
// C#: 使用TimeSpan方法
TimeSpan t1 = TimeSpan.FromSeconds(5) + TimeSpan.FromSeconds(10);
4. 空值概念
st
// ST: 没有null概念(除字符串)
VAR
b: BOOL; // 默认FALSE
i: INT; // 默认0
END_VAR
csharp
// C#: 可空类型
bool? b = null; // 可空布尔
int? i = null; // 可空整数
🔧 五、跨平台数据交互
数据映射表(PLC ↔ C#)
| PLC (ST) | C# (.NET) | OPC UA 类型 | 备注 |
|---|---|---|---|
| BOOL | bool | Boolean | |
| SINT | sbyte | SByte | |
| INT | short | Int16 | |
| DINT | int | Int32 | |
| LINT | long | Int64 | |
| REAL | float | Float | |
| LREAL | double | Double | |
| STRING | string | String | 注意编码 |
| TIME | TimeSpan | Duration | |
| DATE | DateTime | DateTime | |
| ARRAY | Array | Array |
通信示例
csharp
// C#读取PLC数据(通过OPC UA或ADS)
// PLC端:定义变量
VAR_GLOBAL
gTemperature: REAL := 25.5;
gRunning: BOOL := TRUE;
END_VAR
// C#端:读取数据
float temperature = opcClient.ReadValue<float>("gTemperature");
bool isRunning = opcClient.ReadValue<bool>("gRunning");
📚 六、学习建议
-
从ST到C#:注意类型范围和转换问题
-
从C#到ST:简化思维,PLC更接近硬件
-
交互设计:定义清晰的数据接口规范
-
测试验证:边界值测试非常重要
💡 总结
| 特性 | ST语言 (PLC) | C#语言 (.NET) |
|---|---|---|
| 目标 | 实时控制 | 通用编程 |
| 类型系统 | 简单,确定 | 丰富,灵活 |
| 内存 | 静态分配 | 动态管理 |
| 实时性 | 硬实时 | 软实时 |
| 安全性 | 功能安全 | 类型安全 |
| 扩展性 | 有限 | 无限 |
核心区别 :ST是领域特定语言 ,为工业控制优化;C#是通用语言,为应用开发设计。理解这些区别有助于在自动化项目中正确选择和使用数据类型。