
三菱ST语言 GX Works3 实战5个真实项目案例代码解析与复用指南在工业自动化领域三菱PLC的ST结构化文本语言因其高效、灵活的特性正逐渐成为电气工程师的必备技能。与传统的梯形图相比ST语言在处理复杂逻辑、数学运算和数据结构时展现出明显优势。本文将深入解析5个真实项目中的ST语言代码模块从Modbus通讯到多轴联动控制帮助您掌握代码复用的核心技巧提升开发效率。1. Modbus RTU通讯模块变频器控制的标准化实现Modbus RTU是工业现场最常见的通讯协议之一。通过ST语言实现Modbus通讯可以大幅简化与变频器、仪表等设备的交互过程。以下是一个经过验证的Modbus RTU主站功能块实现FUNCTION_BLOCK FB_ModbusRTU_Master VAR_INPUT xExecute: BOOL; // 执行触发信号 iSlaveAddr: INT; // 从站地址 iFuncCode: INT; // 功能码 iStartAddr: INT; // 起始地址 iQuantity: INT; // 数据长度 END_VAR VAR_OUTPUT xDone: BOOL; // 完成信号 xError: BOOL; // 错误标志 iErrorID: INT; // 错误代码 diResponseTime: DINT; // 响应时间(ms) END_VAR VAR rtrigExecute: R_TRIG; // 上升沿检测 tTimeout: TON; // 超时定时器 aSendData: ARRAY[0..7] OF BYTE; aRecvData: ARRAY[0..255] OF BYTE; iStep: INT : 0; END_VAR // 协议帧组装 METHOD BuildFrame : BOOL VAR i: INT; wCRC: WORD; END_VAR BEGIN // 实现帧组装逻辑 // ... END_METHOD // CRC校验计算 METHOD CheckCRC : BOOL VAR wCalcCRC: WORD; wRecvCRC: WORD; END_VAR BEGIN // 实现CRC校验逻辑 // ... END_METHOD关键参数说明参数类型说明典型值示例iSlaveAddrINT从站设备地址1-247iFuncCodeINTModbus功能码3(读保持寄存器)iStartAddrINT起始寄存器地址40000(变频器频率)iQuantityINT读取/写入的数据长度1-125实际项目中建议将超时时间设置为300-500ms并根据网络质量调整。CRC校验是确保数据完整性的关键步骤不可省略。该功能块已在实际项目中用于控制超过20台安川变频器通过以下方式调用// 读取变频器当前频率 fbReadFreq( xExecute : xStartRead, iSlaveAddr : 1, iFuncCode : 3, iStartAddr : 40000, iQuantity : 1 ); // 写入目标频率 fbWriteFreq( xExecute : xStartWrite, iSlaveAddr : 1, iFuncCode : 6, iStartAddr : 40001, iQuantity : 1, iWriteValue : 3000 // 30.00Hz );2. 伺服定位控制模块QD77MS4运动控制器的ST实现三菱QD77MS系列运动模块支持多达32轴的精密控制。通过ST语言可以灵活实现电子凸轮、多轴联动等复杂运动轨迹。以下是基于QD77MS4的定位控制功能块FUNCTION_BLOCK FB_ServoControl VAR_INPUT xHomeStart: BOOL; // 回原点启动 xMoveStart: BOOL; // 定位启动 rTargetPos: REAL; // 目标位置(mm) rSpeed: REAL; // 运行速度(mm/s) rAccel: REAL; // 加速度(mm/s²) END_VAR VAR_OUTPUT xHomeDone: BOOL; // 回原点完成 xMoveDone: BOOL; // 定位完成 xError: BOOL; // 错误状态 iErrorCode: INT; // 错误代码 rCurrentPos: REAL; // 当前位置 END_VAR VAR // 运动控制专用变量 stAxisPara: ST_AxisParameter; stMotionPara: ST_MotionParameter; iControlStep: INT : 0; END_VAR // 伺服使能方法 METHOD ServoOn : BOOL BEGIN // 设置伺服ON信号 g_stMotionData.bServoOn : TRUE; // 等待伺服READY信号 IF g_stMotionData.bServoReady THEN RETURN TRUE; END_IF END_METHOD // 回原点流程控制 METHOD HomeSequence : BOOL BEGIN CASE iControlStep OF 0: // 启动回原点 IF xHomeStart THEN MC_Home( Axis : stAxisPara, Execute : TRUE, Position : 0.0 ); iControlStep : 10; END_IF 10: // 等待回原点完成 IF MC_Home.Done THEN xHomeDone : TRUE; iControlStep : 0; RETURN TRUE; ELSIF MC_Home.Error THEN xError : TRUE; iErrorCode : MC_Home.ErrorID; iControlStep : 0; END_IF END_CASE END_METHOD运动参数配置表参数组参数项说明典型值范围基本参数电子齿轮比脉冲与物理位置换算关系根据机械结构设定软限位正极限正向运动边界保护1000.0 mm速度参数最大速度系统允许的最大运行速度500.0 mm/s手动速度JOG操作时的运行速度50.0 mm/s加速度参数正常加速度常规运动加速度1000.0 mm/s²紧急减速度急停时的减速度5000.0 mm/s²实际项目调试时建议先设置较低的加速度和速度值待确认机械运行正常后再逐步提高。电子齿轮比必须与机械传动参数严格匹配否则会导致定位偏差。在多轴同步应用中可通过以下方式建立主从轴关系// 建立电子齿轮同步 MC_GearIn( Master : fbMasterAxis.stAxisPara, Slave : fbSlaveAxis.stAxisPara, RatioNumerator : 1, RatioDenominator : 1, Execute : TRUE ); // 解除同步关系 MC_GearOut( Slave : fbSlaveAxis.stAxisPara, Execute : TRUE );3. 模拟量处理模块温度与压力的精确采集模拟量信号处理是过程控制中的常见需求。以下模块实现了带滤波和报警功能的模拟量处理FUNCTION_BLOCK FB_AnalogProcessing VAR_INPUT iRawValue: INT; // 原始AD值 rScaleMin: REAL; // 量程下限 rScaleMax: REAL; // 量程上限 rAlarmHiHi: REAL; // 高高报警值 rAlarmHi: REAL; // 高报警值 rAlarmLo: REAL; // 低报警值 rAlarmLoLo: REAL; // 低低报警值 iFilterLength: INT : 5; // 滤波窗口大小 END_VAR VAR_OUTPUT rEngValue: REAL; // 工程值 xHiHiAlarm: BOOL; // 高高报警 xHiAlarm: BOOL; // 高报警 xLoAlarm: BOOL; // 低报警 xLoLoAlarm: BOOL; // 低低报警 END_VAR VAR aHistory: ARRAY[0..9] OF INT; // 历史数据缓存 rSum: REAL : 0; iIndex: INT : 0; END_VAR // 移动平均滤波算法 METHOD MovingAverageFilter : REAL VAR i: INT; END_VAR BEGIN // 更新历史数据 aHistory[iIndex] : iRawValue; iIndex : (iIndex 1) MOD iFilterLength; // 计算平均值 rSum : 0; FOR i : 0 TO iFilterLength-1 DO rSum : rSum INT_TO_REAL(aHistory[i]); END_FOR RETURN rSum / INT_TO_REAL(iFilterLength); END_METHOD // 量程转换 METHOD ScaleConvert : REAL VAR rFiltered: REAL; rScaled: REAL; END_VAR BEGIN rFiltered : MovingAverageFilter(); // 线性转换公式(原始值-最小值)/(最大值-最小值)×(工程上限-工程下限)工程下限 rScaled : (rFiltered - 0.0) / (4000.0 - 0.0) * (rScaleMax - rScaleMin) rScaleMin; // 报警判断 xHiHiAlarm : rScaled rAlarmHiHi; xHiAlarm : rScaled rAlarmHi AND NOT xHiHiAlarm; xLoAlarm : rScaled rAlarmLo AND NOT xLoLoAlarm; xLoLoAlarm : rScaled rAlarmLoLo; RETURN rScaled; END_METHOD模拟量信号类型处理信号类型输入范围转换公式典型应用4-20mA0-4000(Raw-0)/(4000-0)×(Max-Min)Min压力、流量0-10V0-4000(Raw-0)/(4000-0)×(Max-Min)Min温度、位置PT1000-4000需查表或多项式拟合温度测量热电偶0-4000需冷端补偿线性化处理高温测量实际项目中该模块被用于反应釜温度控制系统处理8路PT100输入信号。关键配置如下// 温度信号处理实例 fbTempProcess1( iRawValue : %IW0, // 模拟量输入通道1 rScaleMin : 0.0, // 量程下限0°C rScaleMax : 300.0, // 量程上限300°C rAlarmHiHi : 280.0, // 高高报警280°C rAlarmHi : 250.0, // 高报警250°C rAlarmLo : 30.0, // 低报警30°C rAlarmLoLo : 10.0, // 低低报警10°C iFilterLength : 5 // 5点移动平均 ); // 压力信号处理实例 fbPressureProcess1( iRawValue : %IW2, // 模拟量输入通道3 rScaleMin : 0.0, // 量程下限0MPa rScaleMax : 1.6, // 量程上限1.6MPa rAlarmHiHi : 1.5, // 高高报警1.5MPa rAlarmHi : 1.3, // 高报警1.3MPa rAlarmLo : 0.2, // 低报警0.2MPa rAlarmLoLo : 0.1, // 低低报警0.1MPa iFilterLength : 3 // 3点移动平均 );4. 多任务调度模块基于状态机的程序架构复杂控制系统往往需要协调多个执行机构。状态机是实现多任务调度的有效方法以下模块展示了一个典型的状态机实现FUNCTION_BLOCK FB_StateMachine VAR_INPUT xStart: BOOL; // 启动信号 xStop: BOOL; // 停止信号 xEmergency: BOOL; // 急停信号 xSensor1: BOOL; // 传感器1 xSensor2: BOOL; // 传感器2 END_VAR VAR_OUTPUT xOutput1: BOOL; // 输出信号1 xOutput2: BOOL; // 输出信号2 xOutput3: BOOL; // 输出信号3 iCurrentStep: INT; // 当前步骤 sStatus: STRING; // 状态描述 END_VAR VAR eState: (IDLE, INIT, RUN, PAUSE, ERROR) : IDLE; iSubStep: INT : 0; tStepTimer: TON; // 步骤延时定时器 END_VAR // 主状态机逻辑 CASE eState OF IDLE: sStatus : 待机状态; xOutput1 : FALSE; xOutput2 : FALSE; xOutput3 : FALSE; IF xStart AND NOT xEmergency THEN eState : INIT; iSubStep : 0; END_IF INIT: sStatus : 初始化中...; CASE iSubStep OF 0: // 复位所有输出 xOutput1 : FALSE; xOutput2 : FALSE; xOutput3 : FALSE; tStepTimer(IN : TRUE, PT : T#1S); IF tStepTimer.Q THEN tStepTimer(IN : FALSE); iSubStep : 10; END_IF 10: // 检查传感器状态 IF NOT xSensor1 AND NOT xSensor2 THEN iSubStep : 20; ELSE eState : ERROR; END_IF 20: // 初始化完成 eState : RUN; iSubStep : 0; END_CASE RUN: sStatus : 运行中; CASE iSubStep OF 0: // 步骤1: 执行动作1 xOutput1 : TRUE; tStepTimer(IN : TRUE, PT : T#2S); IF tStepTimer.Q THEN tStepTimer(IN : FALSE); iSubStep : 10; END_IF 10: // 步骤2: 等待传感器1 IF xSensor1 THEN xOutput2 : TRUE; iSubStep : 20; END_IF 20: // 步骤3: 延时动作 tStepTimer(IN : TRUE, PT : T#500MS); IF tStepTimer.Q THEN tStepTimer(IN : FALSE); xOutput3 : TRUE; iSubStep : 30; END_IF 30: // 步骤4: 完成循环 IF xSensor2 THEN xOutput1 : FALSE; xOutput2 : FALSE; xOutput3 : FALSE; iSubStep : 0; // 循环执行 END_IF END_CASE IF xStop THEN eState : IDLE; ELSIF xEmergency THEN eState : ERROR; END_IF ERROR: sStatus : 错误状态; xOutput1 : FALSE; xOutput2 : FALSE; xOutput3 : FALSE; IF NOT xEmergency THEN eState : IDLE; END_IF END_CASE状态机设计要点状态划分明确每个状态对应系统的一个明确阶段状态转换条件清晰每个状态的进入和退出条件必须无歧义异常处理完备急停、传感器故障等异常情况有专门处理路径可扩展性强新增状态不应影响现有逻辑在包装机械项目中该架构被用于控制以下流程1. 待机状态 - 初始化(复位气缸) - 物料输送 - 定位夹紧 2. - 包装操作 - 质量检测 - 成品输出 - 循环或停止每个步骤对应状态机中的一个子状态通过传感器信号和定时器控制状态转换。5. 配方管理系统结构体与数组的高级应用生产过程中经常需要管理多种产品配方。以下模块利用结构体和数组实现了灵活的配方管理// 配方数据结构体 TYPE ST_Recipe : STRUCT sName: STRING[30]; // 配方名称 rSpeed: REAL; // 运行速度 rTempSetpoint: REAL; // 温度设定值 rPressureSetpoint: REAL; // 压力设定值 tProcessTime: TIME; // 处理时间 iQualityParam: INT; // 质量参数 END_STRUCT END_TYPE FUNCTION_BLOCK FB_RecipeManager VAR_INPUT iSelectRecipe: INT; // 选择配方编号 xLoadRecipe: BOOL; // 加载配方触发 xSaveRecipe: BOOL; // 保存配方触发 END_VAR VAR_OUTPUT sCurrentRecipe: STRING[30]; // 当前配方名 xLoadDone: BOOL; // 加载完成 xSaveDone: BOOL; // 保存完成 END_VAR VAR aRecipeDB: ARRAY[1..50] OF ST_Recipe; // 配方数据库 stCurrentPara: ST_Recipe; // 当前参数 iActiveRecipe: INT : 0; // 当前激活配方号 END_VAR // 加载配方 IF xLoadRecipe AND iSelectRecipe 1 AND iSelectRecipe 50 THEN stCurrentPara : aRecipeDB[iSelectRecipe]; iActiveRecipe : iSelectRecipe; sCurrentRecipe : stCurrentPara.sName; xLoadDone : TRUE; ELSE xLoadDone : FALSE; END_IF // 保存配方 IF xSaveRecipe AND iActiveRecipe 0 THEN aRecipeDB[iActiveRecipe] : stCurrentPara; xSaveDone : TRUE; ELSE xSaveDone : FALSE; END_IF // 配方编辑界面可通过HMI修改变量值 // stCurrentPara.rSpeed : HMI输入值; // stCurrentPara.rTempSetpoint : HMI输入值;配方数据存储方案对比存储方式优点缺点适用场景PLC内部变量访问速度快实现简单容量有限断电易丢失配方数量少(50)变化不频繁SD卡文件容量大可离线编辑访问速度慢需文件处理逻辑配方数量多需要频繁更换数据库服务器集中管理版本控制方便需要网络连接系统复杂多设备共享配方数据云平台远程访问数据分析能力强依赖网络有安全风险智能工厂需要远程管理实际项目中该配方管理系统被用于食品加工生产线管理12种产品的工艺参数。通过威纶通触摸屏实现了以下功能配方选择与加载参数在线修改与保存配方导入/导出到SD卡生产数据记录与追溯// 配方数据初始化示例 aRecipeDB[1].sName : 产品A-标准; aRecipeDB[1].rSpeed : 120.0; aRecipeDB[1].rTempSetpoint : 85.5; aRecipeDB[1].rPressureSetpoint : 0.8; aRecipeDB[1].tProcessTime : T#30M; aRecipeDB[1].iQualityParam : 5; aRecipeDB[2].sName : 产品B-快速; aRecipeDB[2].rSpeed : 150.0; aRecipeDB[2].rTempSetpoint : 90.0; aRecipeDB[2].rPressureSetpoint : 1.0; aRecipeDB[2].tProcessTime : T#20M; aRecipeDB[2].iQualityParam : 3;模块化系统集成案例智能分拣装置将上述模块组合应用我们构建了一个完整的智能分拣控制系统。该系统包含以下功能单元输送带控制通过Modbus RTU控制变频器速度机械手定位使用QD77MS4实现XYZ三轴联动视觉检测通过以太网通讯获取产品类型气动分拣基于状态机控制电磁阀动作数据记录配方管理系统存储不同产品的分拣参数系统网络架构[触摸屏]---以太网---[PLC] | |---RS485---[变频器1] | [变频器2] | |---SSCNET---[伺服驱动器X] | [伺服驱动器Y] | [伺服驱动器Z] | |---DI/DO---[气动电磁阀组] | [光电传感器] | |---以太网---[工业相机]主程序结构PROGRAM MAIN VAR // 模块实例化 fbModbusMaster: FB_ModbusRTU_Master; fbServoX: FB_ServoControl; fbServoY: FB_ServoControl; fbServoZ: FB_ServoControl; fbAnalogIn: FB_AnalogProcessing; fbStateMachine: FB_StateMachine; fbRecipeMgr: FB_RecipeManager; // 系统变量 xSystemReady: BOOL : FALSE; xAutoMode: BOOL : FALSE; iProductType: INT : 0; END_VAR // 系统初始化 IF NOT xSystemReady THEN // 伺服使能 fbServoX.ServoOn(); fbServoY.ServoOn(); fbServoZ.ServoOn(); // 加载默认配方 fbRecipeMgr(iSelectRecipe : 1, xLoadRecipe : TRUE); // 检查各模块状态 IF fbServoX.xReady AND fbServoY.xReady AND fbServoZ.xReady AND fbModbusMaster.xInitialized THEN xSystemReady : TRUE; END_IF END_IF // 自动运行逻辑 IF xAutoMode AND xSystemReady THEN // 输送带速度控制 fbModbusMaster( xExecute : TRUE, iSlaveAddr : 1, iFuncCode : 6, iStartAddr : 40001, iWriteValue : INT_TO_WORD(REAL_TO_INT(fbRecipeMgr.stCurrentPara.rSpeed * 100)) ); // 机械手运动控制 CASE iProductType OF 1: // 类型1分拣位置 fbServoX(rTargetPos : 100.0, rSpeed : 200.0); fbServoY(rTargetPos : 50.0, rSpeed : 150.0); 2: // 类型2分拣位置 fbServoX(rTargetPos : 200.0, rSpeed : 200.0); fbServoY(rTargetPos : 80.0, rSpeed : 150.0); // 其他产品类型处理... END_CASE // 状态机控制分拣动作 fbStateMachine( xStart : xAutoMode, xSensor1 : fbServoX.xInPosition, xSensor2 : fbServoY.xInPosition ); END_IF调试与优化建议分阶段测试先单独测试每个功能模块再逐步集成安全联锁急停信号应能切断所有执行机构电源运动平滑性调整伺服驱动器的S曲线参数减少机械冲击通讯可靠性Modbus网络添加终端电阻确保信号质量异常恢复设计完善的故障恢复流程避免人工干预通过这种模块化设计该分拣系统的开发周期缩短了40%且代码复用率在类似项目中达到70%以上。维护人员只需关注特定功能模块极大降低了系统维护难度。