最近因为用到300PLC与变频器通讯的问题,一般都是使用官网的视频教程中方法来实现。后来,在PCS7项目中,用到了FB_Drive块。因为没有源程序,所以套用FB_Drive的部分输入、输出接口,经过两天的摸索,终于搞出来了。实际使用中,直接调用该块,连接实际通道,设置基准电流量程和基准转矩量程即可。根据FB_Drive块的思路,目前只支持标准报文1和20.后续如果有时间,再研究其它报文的格式。如果有什么不对指出,欢迎各位专家批评指正。
FUNCTION_BLOCK FB2100 //FBDrive
TITLE = 'FBDrive'
//
// Block Comment...
//
VERSION: '1.0'
AUTHOR: Author
NAME: HSC
FAMILY: Drive
VAR_INPUT
PZDIn1 : WORD :=W#16#00;
PZDIn2 : WORD :=W#16#00;
PZDIn3 : WORD :=W#16#00;
PZDIn4 : WORD :=W#16#00;
PZDIn5 : WORD :=W#16#00;
PZDIn6 : WORD :=W#16#00;
Telegram : INT := 20;
PZDIn2Scale : STRUCT
HIGH : REAL := 50.0;
LOW : REAL := 0.0;
END_STRUCT;
SP_Li : REAL := 0.0 ;
SP_LiScale : STRUCT
HIGH : REAL := 50.0;
LOW : REAL := 0.0;
END_STRUCT;
PZDIn3Scale : STRUCT
HIGH : REAL := 100.0;
LOW : REAL := 0.0;
END_STRUCT;
PZDIn4Scale : STRUCT
HIGH : REAL := 100.0;
LOW : REAL := 0.0;
END_STRUCT;
PZDIn5Scale : STRUCT
HIGH : REAL := 100.0;
LOW : REAL := 0.0;
END_STRUCT;
PZDIn6Scale : STRUCT
HIGH : REAL := 100.0;
LOW : REAL := 0.0;
END_STRUCT;
On : BOOL := False;
InvSp : BOOL := False;
END_VAR
VAR_IN_OUT
// I/O Parameters
END_VAR
VAR_OUTPUT
PZDOut1 : WORD := W#16#00;
PZDOut2 : WORD := W#16#00;
SpeedLi : REAL := 0.0;
SpeedScale : STRUCT
HIGH : REAL := 50.0;
LOW : REAL := 0.0;
END_STRUCT;
Current_Value : REAL :=0.0; //PZD3的值
CurrentScale : STRUCT
HIGH : REAL := 100.0;
LOW : REAL := 0.0;
END_STRUCT;
Mist_Glatt : REAL := 0.0 ; //当前转矩值
Warn_Code : INT := 0 ; // 报警代码
Fault_Code : INT := 0 ; // 故障代码
Rdy_On : BOOL := False ; // 准备打开
RdyOp : BOOL := False ; // 准备运行
Warnning : BOOL := False ; // 报警
Fault : BOOL := False ; // 故障
Running : BOOL := False ; // 运行
Inv_Running : BOOL := False ; // 反向运行
END_VAR
VAR
FbDriveState : WORD;
FbDriveIn AT FbDriveState : ARRAY[0..15] OF BOOL;
END_VAR
BEGIN
IF On THEN
PZDOut1 := W#16#047F;
IF InvSp THEN
PZDOut1 := W#16#0C7F;
END_IF;
ELSE PZDOut1 := W#16#047E;
END_IF;
IF SP_Li >0.0 THEN
PZDOut2 := INT_TO_WORD(REAL_TO_INT(SP_Li*16384.0/(SP_LiScale.HIGH-SP_LiScale.LOW)));
ELSE PZDOut2 := W#16#00;
END_IF;
FbDriveState := PZDIn1 ;
Rdy_On := FbDriveIn[8];
RdyOp := FbDriveIn[9];
Running := FbDriveIn[10];
Fault := FbDriveIn[11];
Warnning := FbDriveIn[15];
Inv_Running := NOT FbDriveIn[6];
CASE Telegram OF
1:
IF SP_Li >0.0 THEN
SpeedLi := (INT_TO_REAL(WORD_TO_INT(PZDIn2))*((SP_LiScale.HIGH-SP_LiScale.LOW)/16384.0))+SP_LiScale.LOW;
SpeedScale.HIGH := SP_LiScale.HIGH;
SpeedScale.LOW := SP_LiScale.LOW;
ELSE SpeedLi := 0.0;
END_IF;
20:
IF SP_Li >0.0 THEN
SpeedLi := (INT_TO_REAL(WORD_TO_INT(PZDIn2))*((SP_LiScale.HIGH-SP_LiScale.LOW)/16384.0))+SP_LiScale.LOW;
SpeedScale.HIGH := SP_LiScale.HIGH;
SpeedScale.LOW := SP_LiScale.LOW;
ELSE SpeedLi := 0.0;
END_IF;
IF (INT_TO_REAL(WORD_TO_INT(PZDIn3)))> 0 THEN
Current_Value := (INT_TO_REAL(WORD_TO_INT(PZDIn3))*((CurrentScale.HIGH-CurrentScale.LOW)/16384.0))+CurrentScale.LOW;
CurrentScale.HIGH := PZDIn3Scale.HIGH;
CurrentScale.LOW := PZDIn3Scale.LOW;
ELSE Current_Value := 0.0;
END_IF;
IF (INT_TO_REAL(WORD_TO_INT(PZDIn4)))> 0 THEN
Mist_Glatt := (INT_TO_REAL(WORD_TO_INT(PZDIn4))*((PZDIn4Scale.HIGH-PZDIn4Scale.LOW)/16384.0))+PZDIn4Scale.LOW;
ELSE Mist_Glatt := 0.0;
END_IF;
IF WORD_TO_INT(PZDIn5)>0 THEN
Warn_Code := WORD_TO_INT(PZDIn5);
ELSE Warn_Code := 0;
END_IF;
IF WORD_TO_INT(PZDIn6)>0 THEN
Fault_Code := WORD_TO_INT(PZDIn6);
ELSE Fault_Code := 0 ;
END_IF;
END_CASE;
END_FUNCTION_BLOCK