假设我有以下结构,其中包含有关Axis的信息:
TYPE AxisInfo :
STRUCT
AxisStatus : ARRAY [0..3] OF BYTE;
DriveStatis : ARRAY [0..3] OF BYTE;
FeedRate : ARRAY [0..3] OF BYTE;
Inputs : BYTE;
Outputs : BYTE;
Extra : BYTE;
CurPosW: UDINT;
CurPosX: UDINT;
CurPosY: UDINT;
CurPosZ: UDINT;
CurVelX: UDINT;
CurVelY: UDINT;
CurVelZ: UDINT;
ComPos : UDINT;
SetVel : UDINT;
DacVel : UDINT;
WinchErrPos : UDINT;
XYZErrPos : UDINT;
EnFaults : UDINT;
ActFaults : UDINT;
BpFaults : UDINT;
BpTimeLeft : UDINT;
此结构总共包含 82个字节。我将一直运行 8 这些结构(因为我有8轴)。这相当于 656字节与所有结构相结合。
现在,我有一个名为Buffer的变量:
Buffer: ARRAY [0..1023] OF BYTE;
我希望能够按顺序用8个结构中的每一个填充此缓冲区。例如:
Buffer[0] := AxisStatus[0]; //this is for the 1st axis
Buffer[1] := AxisStatus[1]; //this is for the 1st axis
….
Buffer[78] := BpTimeLeft; //this is for the 1st axis
…
Buffer[648] := BpFaults;
Buffer[652] := BpTimeLeft; //this is for the 8th axis
PLC上的ST中是否有一种方法可以迭代结构的成员,然后将这些成员放入缓冲区并确保它们位于适当的位置?你知道有什么技巧吗?
我问这个是因为我可以用以下方法来做,
For axisIndex:=1 to 8 DO
Buffer[0] := AxisStatus[0];
Buffer[1] := AxisStatus[1];
…
Buffer[78] := BpTimeLeft; this is for the 1st axis
END_FOR
但是我必须输出缓冲区需要分配给的每一行,然后在用第一个轴填充缓冲区之后必须做一些技巧,以避免它覆盖前82个字节。如果我将来更改结构的成员,必须有一些方法自动执行。
答案 0 :(得分:0)
您是否尝试使用MEMCPY功能?这应该是更少的努力...... 您可以通过两种方式复制Struct和字节数组。使用一些索引和偏移指针。
答案 1 :(得分:0)
我建议在结构声明中使用{attribute 'pack_mode' := '1'}
,然后您可以使用MEMCPY轻松复制数据。
结构声明:
{attribute 'pack_mode' := '1'}
TYPE AxisInfo :
STRUCT
现在您可以将整个结构复制到字节数组,例如,或者只是一些变量。例如,要将Inputs
从结构复制到字节数组,可以使用类似
MEMCPY(ADR(Buffer[2]), ADR(AxisStatus) + 12, 1)
将一个字节(AxisStatus的地址+ 12个字节,等于Inputs
)复制到缓冲区[2]。如果复制多个字节,它会将它们复制到缓冲区[2],缓冲区[3],缓冲区[4]等等。
memcpy在这种情况下非常有用。
要将整个结构复制到缓冲区的开头,您可以
MEMCPY(ADR(Buffer), ADR(AxisStatus), SIZEOF(AxisStatus))
复制后面的下一个结构
MEMCPY(ADR(Buffer) + SIZEOF(AxisStatus), ADR(AxisStatus), SIZEOF(AxisStatus))
答案 2 :(得分:0)
老实说,我会避免遍历结构只是为了检索你需要的状态信息。如果你有100轴怎么办?
它不能很好地扩展。
如果改变程序的设计会怎样?
您可以设计一个功能块(让我们称之为AxisDevice),例如为轴建模。
AxisDevice
将拥有在其中运行axis
所需的所有功能块。然后,您会将AXIS_REF
传递给AxisDevice
,并且可以通过属性检索axis
的状态信息(例如:getStatus:= AxisStatusStruct)。
通过这样做,您只需要决定并实施一次关于轴的信息" public"。
您的所有8 axis
都可以是AxisDevice
类型,并在需要时在运行时提供信息。
答案 3 :(得分:-1)
您无法保证字节位置和元素位置,因为编译器将根据硬件目标优化空间。你无法赢得这场战斗 - 你会反对结构的全部内容。
1)。您可以手动打包自己的字节数组以保证位置而不是使用结构(但是您可能也可以用机器语言编程,因为您正在击败高级编程...
BUFFER:= AxisInfo的ARRAY [0..7];
BUFFER [0]将是0轴, BUFFER [1]将是轴1, 等
2)。您可以将缓冲区定义为结构数组,并停止访问特定的内存位置(这取决于硬件/平台!)
3)。如果要将数据发送到HMI或某些不知道结构但只知道字节的设备,则会手动将结构元素映射到字节数组中的位置。这是现场总线通信的常规解决方案,如ModbusTCP。