Vai al contenuto
PLC Forum


DWORD


Messaggi consigliati

ifachsoftware
Inserito:

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


Inserita:

Non ho provato ad utilizzarli ,

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

 

 

Inserita:

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.

 

 

ifachsoftware
Inserita:

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

Inserita:

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

 

Inserita:

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 ? ;)

  • 2 weeks later...
ifachsoftware
Inserita:

Le operazioni con DW in SCL non sono ammesse.

Appena trovo un poco di tempo testo le tua funzione.

Per ora grazie

Inserita:

Con Simatic "Classic" lo sono, con TIA Portal non ho provato.

Le seguenti variabili Pippox sono tutte DWORD. Basta solo dichiarare esplicitamente la conversione a DINT.

Il risultato dell'operazione è sempre un numero da 0 a 2^32-1. Per le operazioni di confronto, ovviamente non puoi affidarti direttamente a quelle di sistema, ma attuare uno stratagemma tipo quello che ti ho suggerito sopra.

Pippo3 := DINT_TO_DWORD(DWORD_TO_DINT(Pippo1) + DWORD_TO_DINT(Pippo2));

 

Ciao

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...