ifachsoftware

DWORD

7 messaggi in questa discussione

Buongiorno a tutti , ho notato che i plc Siemens supportano le DWORD solo come DINT per tutte le operazioni matematiche e di comparazione. 

La differenza tra i due tipi di dati è la gestione del segno.

Le DWORD essendo unsigned dovrebbero lavorare tra 0 e 4294967295 , mentre i DINT lavorano tra -2147483648 e 2147483647.

Nel mio caso volevo realizzare un contatore e con i comandi standard sono stato costretto a limitare la gestione al range della parte positiva dei DINT.

Per superare questo clamoroso limite ho scritto delle funzioni in AWL che allego , invitandomi a dare suggerimenti e a completarle.

 

MINORE

 

FUNCTION "DW_A<B" : Bool
TITLE = DWORD A < DWORD B
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : CR
VERSION : 0.1
   VAR_INPUT 
      A : DWord;
      B : DWord;
   END_VAR

   VAR_TEMP 
      TmpA : DInt;
      TmpB : DInt;
   END_VAR


BEGIN
NETWORK
TITLE = 
      L #A;
      AD DW#16#0FFF_FFFF;
      T #TmpA;

      L #B;
      AD DW#16#0FFF_FFFF;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      <D;
      JC AAA;

// CHECK LAST BYTE

      L #A;
      AD DW#16#F000_0000;
      SLD 28;
      T #TmpA;


      L #B;
      AD DW#16#F000_0000;
      SLD 28;
      T #TmpB;


      L #TmpA;
      L #TmpB;
      <D;
      JC AAA;

      SET;
      R #"DW_A<B";
      BE;

AAA:      SET;
      S #"DW_A<B";

      BE;
END_FUNCTION

 

MAGGIORE

 

FUNCTION "DW_A>B" : Bool
TITLE = DWORD A > DWORD B
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : CR
VERSION : 0.1
   VAR_INPUT 
      A : DWord;
      B : DWord;
   END_VAR

   VAR_TEMP 
      TmpA : DInt;
      TmpB : DInt;
   END_VAR


BEGIN
NETWORK
TITLE = 
      L #A;
      AD DW#16#0FFF_FFFF;
      T #TmpA;

      L #B;
      AD DW#16#0FFF_FFFF;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      >D;
      JC AAA;

// CHECK LAST BYTE

      L #A;
      AD DW#16#F000_0000;
      SLD 28;
      T #TmpA;


      L #B;
      AD DW#16#F000_0000;
      SLD 28;
      T #TmpB;


      L #TmpA;
      L #TmpB;
      >D;
      JC AAA;

      SET;
      R #"DW_A>B";
      BE;

AAA:      SET;
      S #"DW_A>B";

      BE;
END_FUNCTION

 

SOMMA

 

FUNCTION "DW_SUM" : DWord
TITLE = DWORD A < DWORD B
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : CR
VERSION : 0.1
   VAR_INPUT 
      A : DWord;
      B : DWord;
   END_VAR

   VAR_TEMP 
      TmpA : DInt;
      TmpB : DInt;
      SumR : DInt;
      SumL : DInt;
   END_VAR


BEGIN
NETWORK
TITLE = 
// SUM LOW PART

      L #A;
      AD DW#16#0000_FFFF;
      T #TmpA;

      L #B;
      AD DW#16#0000_FFFF;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      +D;
      T #SumR;

// Sum High Part

      L #A;
      AD DW#16#FFFF_0000;
      SRD 16;
      T #TmpA;

      L #B;
      AD DW#16#FFFF_0000;
      SRD 16;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      +D;
      T #SumL;

// GET REMINDER

      L #SumR;
      AD DW#16#FFFF_0000;
      SRD 16;
      T #TmpA;

      L #TmpA;
      L 0;
      >D;
      JC REM;

      JU aa;

REM:      L #TmpA;
      L #SumL;
      +D;
      T #SumL;

aa:      L #SumL;
      SLD 16;
      T #SumL;

      L #SumR;
      AD DW#16#0000_FFFF;
      T #SumR;

      L #SumR;
      L #SumL;
      OD;
      T #DW_SUM;

      BE;
END_FUNCTION

 

Cattura.PNG

Condividi questa discussione


Link discussione
Condividi su altri siti

Non ho provato ad utilizzarli ,

ho guardato il codice del primo, sei sicuro che funzioni?

 

 

Condividi questa discussione


Link discussione
Condividi su altri siti

Cattura.PNG

Condividi questa discussione


Link discussione
Condividi su altri siti

Vedo dagli screenshoot che funziona. Tieni presente che non ho mai aperto TIA PORTAL , ti faccio una domanda :

hai provao con A= EFFFFFFF   B= FFFFFFFF

 

Io ho provato con step 7 e con i valori sopra indicati non funziona , ripeto non conosco assolutamente TIA Portal e ho visto la riga del tuo sorgente

{ S7_Optimized_Access := 'FALSE' }

che probabilmente è la spiegazione del non corretto funzionamento sul mio PC.

 

 

Condividi questa discussione


Link discussione
Condividi su altri siti

Ciao , hai ragione , ho caricato la versione precedente e chiedo venia.

Carico ora le versioni corrette con relativi esempi :

 

<

FUNCTION "DW<" : Bool
TITLE = DWORD A < B
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : CR
VERSION : 0.1
   VAR_INPUT 
      A : DWord;
      B : DWord;
   END_VAR

   VAR_TEMP 
      TmpA : DInt;
      TmpB : DInt;
   END_VAR


BEGIN
NETWORK
TITLE = 
      L #A;
      AD DW#16#0FFF_FFFF;
      T #TmpA;

      L #B;
      AD DW#16#0FFF_FFFF;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      <D;
      JC AAA;

// CHECK LAST BYTE

      L #A;
      AD DW#16#F000_0000;
      SRD 28;
      T #TmpA;


      L #B;
      AD DW#16#F000_0000;
      SRD 28;
      T #TmpB;


      L #TmpA;
      L #TmpB;
      <D;
      JC AAA;

      SET;
      R #"DW<";
      BE;

AAA:      SET;
      S #"DW<";
      BE;
END_FUNCTION

>

FUNCTION "DW>" : Bool
TITLE = DWORD A > B
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : CR
VERSION : 0.1
   VAR_INPUT 
      A : DWord;
      B : DWord;
   END_VAR

   VAR_TEMP 
      TmpA : DInt;
      TmpB : DInt;
   END_VAR


BEGIN
NETWORK
TITLE = 
      L #A;
      AD DW#16#0FFF_FFFF;
      T #TmpA;

      L #B;
      AD DW#16#0FFF_FFFF;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      >D;
      JC AAA;

// CHECK LAST BYTE

      L #A;
      AD DW#16#F000_0000;
      SRD 28;
      T #TmpA;


      L #B;
      AD DW#16#F000_0000;
      SRD 28;
      T #TmpB;


      L #TmpA;
      L #TmpB;
      >D;
      JC AAA;

      SET;
      R #"DW>";
      BE;

AAA:      SET;
      S #"DW>";

      BE;
END_FUNCTION

>=

FUNCTION "DW>=" : Bool
TITLE = DWORD A >= B
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : CR
VERSION : 0.1
   VAR_INPUT 
      A : DWord;
      B : DWord;
   END_VAR

   VAR_TEMP 
      TmpA : DInt;
      TmpB : DInt;
   END_VAR


BEGIN
NETWORK
TITLE = 
      L #A;
      AD DW#16#0FFF_FFFF;
      T #TmpA;

      L #B;
      AD DW#16#0FFF_FFFF;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      <D;
      JC AAA;

// CHECK LAST BYTE

      L #A;
      AD DW#16#F000_0000;
      SRD 28;
      T #TmpA;


      L #B;
      AD DW#16#F000_0000;
      SRD 28;
      T #TmpB;


      L #TmpA;
      L #TmpB;
      <D;
      JC AAA;

      SET;
      S #"DW>=";
      BE;

AAA:      SET;
      R #"DW>=";

      BE;
END_FUNCTION

<=

FUNCTION "DW<=" : Bool
TITLE = DWORD A <= B
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : CR
VERSION : 0.1
   VAR_INPUT 
      A : DWord;
      B : DWord;
   END_VAR

   VAR_TEMP 
      TmpA : DInt;
      TmpB : DInt;
   END_VAR


BEGIN
NETWORK
TITLE = 
      L #A;
      AD DW#16#0FFF_FFFF;
      T #TmpA;

      L #B;
      AD DW#16#0FFF_FFFF;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      >D;
      JC AAA;

// CHECK LAST BYTE

      L #A;
      AD DW#16#F000_0000;
      SRD 28;
      T #TmpA;


      L #B;
      AD DW#16#F000_0000;
      SRD 28;
      T #TmpB;


      L #TmpA;
      L #TmpB;
      >D;
      JC AAA;

      SET;
      S #"DW<=";
      BE;

AAA:      SET;
      R #"DW<=";

      BE;
END_FUNCTION

Somma

FUNCTION "DW+" : DWord
TITLE = DWORD C = A + B
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : CR
VERSION : 0.1
   VAR_INPUT 
      A : DWord;
      B : DWord;
   END_VAR

   VAR_TEMP 
      TmpA : DInt;
      TmpB : DInt;
      SumR : DInt;
      SumL : DInt;
   END_VAR


BEGIN
NETWORK
TITLE = 
// SUM LOW PART

      L #A;
      AD DW#16#0000_FFFF;
      T #TmpA;

      L #B;
      AD DW#16#0000_FFFF;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      +D;
      T #SumR;

// Sum High Part

      L #A;
      AD DW#16#FFFF_0000;
      SRD 16;
      T #TmpA;

      L #B;
      AD DW#16#FFFF_0000;
      SRD 16;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      +D;
      T #SumL;

// GET REMINDER

      L #SumR;
      AD DW#16#FFFF_0000;
      SRD 16;
      T #TmpA;

      L #TmpA;
      L 0;
      >D;
      JC REM;

      JU aa;

REM:      L #TmpA;
      L #SumL;
      +D;
      T #SumL;

aa:      L #SumL;
      SLD 16;
      T #SumL;

      L #SumR;
      AD DW#16#0000_FFFF;
      T #SumR;

      L #SumR;
      L #SumL;
      OD;
      T #"DW+";

      BE;
END_FUNCTION

Sottrazione

FUNCTION "DW-" : DWord
TITLE = DWORD C = A - B
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : CR
VERSION : 0.1
   VAR_INPUT 
      A : DWord;
      B : DWord;
   END_VAR

   VAR_TEMP 
      TmpA : DInt;
      TmpB : DInt;
      SubR : DInt;
      SubL : DInt;
   END_VAR


BEGIN
NETWORK
TITLE = 
// SUBTRACT LOW PART

      L #A;
      AD DW#16#0000_FFFF;
      T #TmpA;

      L #B;
      AD DW#16#0000_FFFF;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      -D;
      T #SubR;

// SUBTRACT HIGH PART

      L #A;
      AD DW#16#FFFF_0000;
      SRD 16;
      T #TmpA;

      L #B;
      AD DW#16#FFFF_0000;
      SRD 16;
      T #TmpB;

      L #TmpA;
      L #TmpB;
      -D;
      T #SubL;

// GET REMINDER

      L #SubR;
      AD DW#16#FFFF_0000;
      SRD 16;
      T #TmpA;

      L #TmpA;
      L 0;
      >D;
      JC REM;

      JU aa;

REM:      L #TmpA;
      L #SubL;
      +D;
      T #SubL;

aa:      L #SubL;
      SLD 16;
      T #SubL;

      L #SubR;
      AD DW#16#0000_FFFF;
      T #SubR;

      L #SubR;
      L #SubL;
      OD;
      T #"DW-";

      BE;
END_FUNCTION

 

Esempio1.PNG

Esempio2.PNG

Esempio3.PNG

Esempio4.PNG

Se qualcuno volesse realizzare moltiplicazione e divisione e condividerle , sarebbero bene accette , nel contempo ringrazio Steu

Condividi questa discussione


Link discussione
Condividi su altri siti

Ciao premetto che ancora non ho testato il programma, e ho guardato solamente il primo e forse non è la versione che gira nei screen shoot seguenti.

Credo che sia giusto testare prima i bit più significativi e poi gli altri

scusa la scocciatura

 

Condividi questa discussione


Link discussione
Condividi su altri siti

Hai scritto una tonnellata di SW per risolvere un problema che forse nemmeno c'è.

Infatti nulla vieta di utilizzare le operazioni di aritmetiche con le DWORD, e il risultato fa esattamente quello che chiedi, ovvero

DW#80000000

+

DW#10000000

=

DW#90000000

 

Per i confronti invece è sufficiente utlizzare gli operatori disponibili per gli i DINT, con l'accortezza di invertire il risultato quando necessario.

Vedi codice seguente:

FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  Value1 : DWORD ;	
  Value2 : DWORD ;	
END_VAR
VAR_OUTPUT
  Minore : BOOL ;	
  Uguale : BOOL ;	
  Maggiore : BOOL ;	
END_VAR
VAR_TEMP
  Value1Negativo : BOOL ;	
  Value2Negativo : BOOL ;	
  CfrIntermedio : BOOL ;	
END_VAR
BEGIN
NETWORK
TITLE =#Value1Negativo

      L     #Value1; 
      L     0; 
      <D    ; 
      =     #Value1Negativo; 
NETWORK
TITLE =#Value2Negativo

      L     #Value2; 
      L     0; 
      <D    ; 
      =     #Value2Negativo; 
NETWORK
TITLE =#CfrIntermedio

      L     #Value1; 
      L     #Value2; 
      <D    ; 
      =     #CfrIntermedio; 
NETWORK
TITLE =Res #Uguale

      L     #Value1; 
      L     #Value2; 
      ==D   ; 
      =     #Uguale; 
NETWORK
TITLE =Res #Minore

      U(    ; 
      U(    ; 
      UN    #Value1Negativo; 
      UN    #Value2Negativo; 
      O     ; 
      U     #Value1Negativo; 
      U     #Value2Negativo; 
      )     ; 
      U     #CfrIntermedio; 
      O     ; 
      U(    ; 
      UN    #Value1Negativo; 
      U     #Value2Negativo; 
      O     ; 
      U     #Value1Negativo; 
      UN    #Value2Negativo; 
      )     ; 
      UN    #CfrIntermedio; 
      )     ; 
      UN    #Uguale; 
      =     #Minore; 
NETWORK
TITLE =Res #Maggiore

      UN    #Uguale; 
      UN    #Minore; 
      =     #Maggiore; 
END_FUNCTION

Ti ho convinto ? ;)

Condividi questa discussione


Link discussione
Condividi su altri siti

Registrati o accedi per inserire messaggi

Devi essere un utente registrato per lasciare un messaggio. La registrazione è GRATUITA.

Crea un account

Iscriviti alla nostra comunità. È facile!


Registra un nuovo account

Connettiti

Hai già un account? Connettiti qui


Connettiti adesso