2017-09-22 12 views
0

は、i軸についての情報で満たされている、以下の構造を有していると言う:反復処理(構造化テキスト)

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軸を持っている)を実行します。これは、すべての構造と組み合わせた656バイトになります。

さて、私はバッファという変数があります。

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バイトを上書きするのを避けるために、バッファを最初の軸で塗りつぶした後。の構造体のメンバを変更する場合には、何らかの方法でを自動的に作成する必要があります。

+1

ヒント:ポインタ、サイズ&Memcpy –

答えて

-1

コンパイラがハードウェアターゲットに基づいて領域を最適化するため、バイト位置と要素の位置を保証することはできません。あなたはこの戦いに勝つことはできません - あなたは構造がすべてであるものに対して飛行します。

1)。あなたは手動で構造体を使用する代わりに位置を保証するために自分のバイト配列をパックすることができます(しかし、あなたは高いレベルのプログラミングを打ち負かすため、機械語でプログラムすることもできます...

バッファ:= ARRAY [0..7 ] AxisInfo OF;

BUFFER [0]軸であろう、 緩衝液[1]、 のETC

2軸であろう)。バッファを構造体の配列として定義し、特定のメモリ位置へのアクセスを停止することができます(ハードウェア/プラットフォームに依存します)。

3)。構造体を認識しないがバイトのみのHMIまたはデバイスにデータを送信する場合は、構造体の要素をバイト配列の場所に手動でマッピングする必要があります。これは、ModbusTCPのようなフィールドバス通信の通常のソリューションです。

+0

構造内のバイト位置を保証することができます。コンパイラによるハードウェアへの最適化はありません。属性「パックモード」だけがあります。ルールセットのように、構造内の変数がどのように配置されるかを見ることができます –

+0

MotorolaからIntelプラットフォームに切り替えると、バイトスワップが発生する可能性があります。また、コンパイラはバイトを整列させ、構造の定義に応じてデッドバイトを導入することがあります(DWORDは4で割り切れるメモリ位置に合わせる必要があります)。 – Scott

+0

はい、これはTwinCatのパックモードです。 –

0

MEMCPY関数を使用しようとしましたか?それははるかに少ない労力を必要とするでしょう... ストラクチャとバイト配列を両方の方法でコピーできます。いくつかのインデックスとオフセットポインタ。

+0

"将来構造体のメンバを変更する場合に自動的に行う方法がいくつかありますか?" または明示的なメモリ機能を使用して、ARRAY OF BYTEのような同じメモリにARRAY OF STRUCTを配置することもできます。 (%MB0、%MB *、...)(https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/18014398645980299.html&id=) – Tost

0

構造体宣言で{attribute 'pack_mode' := '1'}を使用し、MEMCPYでデータを簡単にコピーすることをお勧めします。

構造体宣言:

{attribute 'pack_mode' := '1'} 
TYPE AxisInfo : 
STRUCT 

は今、あなたは、例えばバイト、または単にいくつかの変数の配列に全体の構造体をコピーすることができます。たとえば、バイト配列にあなたの構造体からInputsをコピーするには、バッファ[2へ

MEMCPY(ADR(Buffer[2]), ADR(AxisStatus) + 12, 1)

コピー(Inputsに等しいAxisStatus + 12バイトのアドレス)からの1バイトのようなものを使用することができます]。複数のバイトをコピーすると、バッファ[2]、バッファ[3]、バッファ[4]などにコピーされます。

memcpyはこのような状況で非常に便利です。バッファの初めに全体の構造体をコピーするには

、あなたはそれが MEMCPY(ADR(Buffer) + SIZEOF(AxisStatus), ADR(AxisStatus), SIZEOF(AxisStatus))

0

正直なところ、私はちょうど取得するために、構造をループ避けるだろう後だけ MEMCPY(ADR(Buffer), ADR(AxisStatus), SIZEOF(AxisStatus))

は、次の構造体をコピーすることができます必要なステータス情報もしあなたが100軸を持っていたら?

スケールがうまくいかない。

代わりにプログラムのデザインを変更するとどうなりますか?

たとえば、軸をモデル化する関数ブロック(AxisDeviceと呼ぶ)を設計できます。

AxisDeviceは、内部でaxisを操作するために必要なすべての機能ブロックを持ちます。 AXIS_REFAxisDeviceに渡し、プロパティ(例:getStatus:= AxisStatusStruct)のおかげでaxisのステータス情報を取得できます。

これを行うことで、軸に関する情報が「public」になったら決定し実装するだけで済みます。

すべて8 axisは、タイプAxisDeviceであり、必要なときに実行時に情報を提供できます。

+0

ひまわりを整形していただきありがとうございます;) –