3. PLC变量与数据类型

在Sysmac Studio中,变量是程序与硬件之间交换数据的唯一通道。与许多传统PLC用“地址”编程不同,Sysmac NJ/NX系列采用变量化编程:I/O、程序内部运算、HMI交互都通过具名变量完成,物理地址只在变量属性中映射。理解变量的作用域与数据类型,是后续编写可维护程序、实现PLC与HMI集成的第一步。

一、全局变量与局部变量:作用域决定可见性

Sysmac Studio把变量按作用域分为两类。全局变量定义在“全局变量表”中,整个工程的所有程序(POU)、功能块、HMI都能访问;局部变量定义在某个程序或功能块内部,只在该POU内可见。工程上的一条基本原则是:能用局部变量就不要用全局变量。局部变量随POU封装,修改时影响面小;全局变量一旦被多处引用,改名或改类型会牵动整个工程。

全局变量又细分为“变量”和“网络变量”两类。普通全局变量用于程序内部共享;网络变量(Network Variable)用于EtherNet/IP或EtherCAT网络上不同控制器之间的数据交换,需要指定发布/订阅关系。对于单机项目,通常只需普通全局变量。

局部变量在POU的变量声明区定义,分为内部变量(VAR)、输入变量(VAR_INPUT)、输出变量(VAR_OUTPUT)、输入输出变量(VAR_IN_OUT)和保持变量(VAR_RETAIN)。其中VAR_INPUT/VAR_OUTPUT/VAR_IN_OUT用于功能块与调用者之间的接口,是结构化编程的关键。

二、基本数据类型:选对类型才能省内存、防溢出

Sysmac Studio支持IEC 61131-3标准数据类型,常用的基本类型如下表。选择类型时既要考虑数值范围,也要考虑HMI和通信的兼容性。

类型位宽范围/说明典型用途
BOOL1位TRUE/FALSE按钮、限位、线圈
BYTE/WORD/DWORD8/16/32位无符号位串状态字、掩码
SINT/INT/DINT8/16/32位有符号整数计数、位置、温度×10
USINT/UINT/UDINT8/16/32位无符号整数索引、长度
REAL/LREAL32/64位浮点数模拟量、PID运算
TIME64位时间间隔定时器设定值
STRING可变字符串配方名、报警文本

工程上常见的错误是用INT存放模拟量。例如一个12位模拟量模块,原始值0~4095对应0~10V,若直接用INT存放原始值没问题;但若要做工程量转换,结果应使用REAL,否则小数部分会被截断。另一个常见问题是INT溢出:一个INT最大32767,若用INT做累计计数,超过就会翻转,应改用DINT或UDINT。

三、结构体、数组与枚举:组织复杂数据

结构体(STRUCT)把多个相关变量打包成一个数据类型。例如定义一个电机数据结构体:

TYPE ST_Motor :
STRUCT
    bRun      : BOOL;      // 运行命令
    bFault    : BOOL;      // 故障反馈
    nSpeed    : INT;       // 转速设定
    rCurrent  : REAL;      // 电流反馈
    nStatus   : WORD;      // 状态字
END_STRUCT
END_TYPE

定义后即可声明stMotor1 : ST_Motor;,通过stMotor1.bRun访问成员。结构体让程序接口清晰,也便于HMI按结构批量绑定。

数组(ARRAY)用于存放同类型的多个元素,声明格式为aData : ARRAY[0..9] OF INT;。数组下标默认从0开始,也可指定为1..10。数组常用于配方、历史数据、多工位状态。注意数组越界在Sysmac中会触发异常,访问前应做下标范围判断。

枚举(ENUM)用有意义的名称代替数字,提高可读性。例如:

TYPE E_State :
(
    eIdle    := 0,
    eRunning := 1,
    ePause   := 2,
    eFault   := 3
);
END_TYPE

声明eState : E_State;后,程序中可写eState := eRunning;,比写eState := 1;清晰得多。枚举在HMI中还能自动显示为文本列表。

Sysmac Studio 变量作用域与数据类型关系 全局变量表(Global) • 所有POU、HMI均可访问 • 可映射物理I/O地址 • 可设为网络变量(EtherNet/IP) • 可设为保持变量(RETAIN) 示例:g_bStart, g_nMode, g_stAlarm 命名前缀 g_ 标识全局 局部变量(Local / POU内) • 仅当前程序或功能块可见 • VAR / VAR_INPUT / VAR_OUTPUT • VAR_IN_OUT 传引用 • VAR_RETAIN 掉电保持 示例:i_nIndex, o_bDone, io_stMotor 命名前缀 i_/o_/io_ 标识方向 数据类型体系 基本数据类型 BOOL / BYTE / WORD INT / DINT / UINT REAL / LREAL TIME / STRING 派生数据类型 STRUCT 结构体 ARRAY 数组 ENUM 枚举 UNION 联合体 工程化命名规范 前缀:g_ / i_ / o_ / io_ 类型:b/n/r/st/a/e 驼峰式:bMotorRun 避免拼音与缩写混用

四、工程化命名规范:让变量自己说话

变量名是程序可读性的第一道防线。Sysmac Studio允许中文变量名,但工程上建议使用英文或拼音首字母,避免编码问题。推荐一套可落地的命名规则:

  • 作用域前缀:全局变量用g_,局部输入用i_,局部输出用o_,输入输出用io_,保持变量用r_。
  • 类型前缀:布尔b,整数n,实数r,字符串s,结构体st,数组a,枚举e。
  • 主体名:用驼峰式,如bMotorRun、nSpeedSet、rTempValue。
  • 单位后缀:带物理量时加单位,如rTemp_C、nTime_ms,避免单位混淆。

例如一个全局的电机运行命令,命名为g_bMotor1Run;一个局部功能块的输出完成标志,命名为o_bDone。这样即使不看注释,也能大致判断变量的作用域、类型和用途。

在Sysmac Studio中,变量名区分大小写,但建议统一使用驼峰式,避免同一变量在不同位置大小写不一致导致编译错误。变量注释应写清“是什么、单位、有效范围”,而不是重复变量名。

五、实操示例:定义一个电机控制功能块的变量

假设要编写一个电机控制功能块FB_Motor,输入启动命令、速度设定,输出运行状态、故障。变量声明如下:

FUNCTION_BLOCK FB_Motor
VAR_INPUT
    i_bStart   : BOOL;      // 启动命令
    i_bStop    : BOOL;      // 停止命令
    i_nSpeed   : INT;       // 速度设定,单位rpm,范围0~3000
END_VAR
VAR_OUTPUT
    o_bRunning : BOOL;      // 运行状态
    o_bFault   : BOOL;      // 故障标志
    o_nActual  : INT;       // 实际转速反馈
END_VAR
VAR
    nState     : E_State;   // 内部状态枚举
    tonStart   : TON;       // 启动延时定时器
END_VAR
VAR_RETAIN
    nRunCount  : DINT;      // 累计运行次数,掉电保持
END_VAR
END_FUNCTION_BLOCK

调用时,在程序中声明一个实例fbMotor1 : FB_Motor;,然后写fbMotor1(i_bStart := g_bStart, i_nSpeed := 1500);。这样,功能块内部状态与外部隔离,只有输入输出接口暴露,符合高内聚低耦合的工程原则。

结构体、数组、枚举必须先定义类型,再声明变量。类型定义放在“数据类型”工作区,不要与变量表混在一起。修改已使用的结构体成员时,Sysmac Studio会提示重新编译所有引用该类型的POU,务必确认影响范围后再操作。

掌握变量作用域与数据类型后,下一步是把这些变量映射到实际I/O和HMI标签。在Sysmac Studio中,全局变量可以直接在“I/O映射”中绑定到EtherCAT从站或内置I/O,HMI则通过变量名直接引用,无需再关心物理地址。这正是变量化编程带来的集成便利。