beckHoff_FB --> GET SNC 功能块
一、功能块实例化
二、功能块变量声明
VAR_INPUTptIN_STATION_ITAC :POINTER TO ST_ITAC_V2_0; (* Data for communication *)sIN_SerialNumber :STRING[cSerialNumberLen];uiSerialNrMode :UINT;iMaxLoopCounter :INT :=-1;uiCheckMode :UINT;uiLayer :UINT :=2;bIN_SendCMD :BOOL; (* Start send command. Wait for response *)
END_VAR(*---------------------------------------------*)
(*OUT variables*)
(*---------------------------------------------*)
VAR_OUTPUTbOUT_ACK :BOOL;bOUT_NAK :BOOL;starParameterValuesRecv :ARRAY[1..siMAX_PARAM_LINES] OF ST_GET_SNC_Param;
END_VAR(*---------------------------------------------*)
(*Local variables*)
(*---------------------------------------------*)
VARiStep,iStepOld :INT;fbiTonTimeinStep : TON;tTimeinStep : TIME;itest: INT;
END_VAR(*---------------------------------------------*)
(*IN/OUT variables*)
(*---------------------------------------------*)
VAR_IN_OUT
END_VARVAR CONSTANTtTimeout :TIME:=T#30S ; (* bmtrue Timeout wieder auf 30 s*)
END_VAR
三、GET SNC 代码
(* Timer *)
IF iStep <> iStepOld THENiStepold := istep;fbiTonTimeinStep(IN:= FALSE, PT:= t#1h, Q=> , ET=> tTimeinStep);
ELSEfbiTonTimeinStep(IN:= TRUE, PT:= t#1h, Q=> , ET=> tTimeinStep);
END_IFCASE iStep OF0:(*clear function's return value*)bOUT_ACK := FALSE;bOUT_NAK := FALSE;iStep := 1;1:(* wait for command *)IF bIN_SendCMD THENptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bError := FALSE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bRecACK := FALSE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bRecNAK := FALSE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sErrText := '';ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sMaterialNrRecv := '';ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sOrderNrRecv := '';IF sIN_SerialNumber <>'' THENptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sSerialNr := sIN_SerialNumber;ELSEptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sSerialNr := '9999999999999999';END_IFptIN_STATION_ITAC^.MMC_Comm.GET_SNC.iMaxLoopCounter := iMaxLoopCounter;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.uiCheckMode := uiCheckMode;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.uiLayer := uiLayer;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bSendRequest := TRUE;iStep := iStep +1;END_IF2:(* wait for answer *)IF ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bRecACK THENstarParameterValuesRecv := ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.starParameterValuesRecv;bOUT_ACK := TRUE;iStep:= iStep +1;END_IFIF ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bRecNAK THENbOUT_NAK := TRUE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bError := TRUE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sErrText := '02| FB_SEQ_iTAC_GET_SNC -> NAK received ';iStep:= iStep +1;END_IFIF tTimeinStep>tTimeout THENbOUT_NAK := TRUE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bRecACK := FALSE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bRecNAK := TRUE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bError := TRUE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sErrText := '02| FB_SEQ_iTAC_GET_SNC -> timout ';iStep:=iStep +1;END_IF3: (*END*)IF NOT bIN_SendCMD THENiStep:= 0;END_IFELSEiStep := 0;END_CASE;
四、代码说明
这段代码是工业自动化控制系统中基于状态机(State Machine)实现的序列号查询(GET_SNC)功能模块,主要用于与制造执行系统(MMC)交互获取生产参数。以下是按功能模块的详细解析:
1、状态机计时器管理
IF iStep <> iStepOld THENiStepold := iStep;fbiTonTimeinStep(IN:= FALSE, PT:= t#1h, Q=> , ET=> tTimeinStep); // 重置计时器
ELSEfbiTonTimeinStep(IN:= TRUE, PT:= t#1h, Q=> , ET=> tTimeinStep); // 启动计时器
END_IF;
- 功能:
- 检测状态机状态 (
iStep
) 是否变化,变化时重置计时器,否则持续计时。 tTimeinStep
记录当前状态的持续时间,用于后续超时判断。
- 检测状态机状态 (
2、状态机核心逻辑(CASE 结构)
1. 状态 0:初始化(iStep=0)
0:(*clear function's return value*)bOUT_ACK := FALSE; // 清除确认响应bOUT_NAK := FALSE; // 清除否定响应iStep := 1; // 切换到等待命令状态
- 功能:重置输出信号,为新的通信请求做准备。
2. 状态 1:等待命令(iStep=1)
1:(* wait for command *)IF bIN_SendCMD THEN // 检测到发送命令请求// 重置通信错误标志和接收数据ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bError := FALSE;// ... 清除其他接收标志和文本// 设置序列号(SN)IF sIN_SerialNumber <> '' THENptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sSerialNr := sIN_SerialNumber;ELSEptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sSerialNr := '9999999999999999'; // 默认序列号END_IF;// 配置通信参数(循环计数器、检查模式、层级)ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.iMaxLoopCounter := iMaxLoopCounter;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.uiCheckMode := uiCheckMode;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.uiLayer := uiLayer;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bSendRequest := TRUE; // 触发发送请求iStep := iStep + 1; // 切换到等待响应状态END_IF;
- 功能:
- 收到发送命令后,重置通信模块状态,避免历史错误影响当前请求。
- 设置序列号(若未提供则使用默认值)和通信参数,向 MMC 系统发送序列号查询请求。
3. 状态 2:等待响应(iStep=2)
2:(* wait for answer *)IF ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bRecACK THEN // 收到确认响应starParameterValuesRecv := ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.starParameterValuesRecv; // 保存接收的参数bOUT_ACK := TRUE; // 输出确认信号iStep := iStep + 1; // 切换到结束状态END_IF;IF ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bRecNAK THEN // 收到否定响应bOUT_NAK := TRUE; // 输出否定信号ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bError := TRUE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sErrText := '02| FB_SEQ_iTAC_GET_SNC -> NAK received ';iStep := iStep + 1;END_IF;IF tTimeinStep > tTimeout THEN // 超时处理bOUT_NAK := TRUE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bRecNAK := TRUE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.bError := TRUE;ptIN_STATION_ITAC^.MMC_Comm.GET_SNC.sErrText := '02| FB_SEQ_iTAC_GET_SNC -> timout ';iStep := iStep + 1;END_IF;
- 功能:
- 根据 MMC 系统的响应类型(ACK/NAK)或超时,设置对应的输出信号,并记录错误信息。
- 成功接收数据后,将参数保存到
starParameterValuesRecv
数组。
4. 状态 3:结束(iStep=3)
3: (*END*)IF NOT bIN_SendCMD THEN // 若不再有发送命令iStep := 0; // 回到初始化状态END_IF;
- 功能:当发送命令请求取消时,重置状态机,准备处理下一次请求。
5. 默认状态处理
iecst
ELSEiStep := 0; // 未知状态时回到初始化
END_CASE;
- 功能:确保状态机在遇到异常状态时自动重置,提高系统鲁棒性。
3、核心交互流程总结
-
请求发送:
接收到发送命令后,配置序列号和通信参数,向 MMC 系统发送查询请求。 -
响应处理:
- ACK 响应:成功接收参数,输出确认信号。
- NAK 响应:请求被拒绝,记录错误。
- 超时:通信无响应时触发错误,防止系统阻塞。
-
状态循环:
每次通信完成后,根据是否有新命令决定回到初始化状态或继续等待。
4、工业应用场景
这段代码通常用于生产追溯系统中:
- 序列号查询:通过序列号获取物料信息、生产工艺参数等。
- 质量控制:MMC 返回的参数可用于验证产品是否符合工艺要求。
- 自动化流程:与生产线其他模块(如供料器、扫描器)联动,实现无人化生产。