ifachsoftware Inserito: 16 marzo 2017 Segnala Share Inserito: 16 marzo 2017 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 Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 16 marzo 2017 Segnala Share Inserita: 16 marzo 2017 Non ho provato ad utilizzarli , ho guardato il codice del primo, sei sicuro che funzioni? Link al commento Condividi su altri siti More sharing options...
ifachsoftware Inserita: 17 marzo 2017 Autore Segnala Share Inserita: 17 marzo 2017 Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 17 marzo 2017 Segnala Share Inserita: 17 marzo 2017 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. Link al commento Condividi su altri siti More sharing options...
ifachsoftware Inserita: 20 marzo 2017 Autore Segnala Share Inserita: 20 marzo 2017 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 Se qualcuno volesse realizzare moltiplicazione e divisione e condividerle , sarebbero bene accette , nel contempo ringrazio Steu Link al commento Condividi su altri siti More sharing options...
STEU Inserita: 20 marzo 2017 Segnala Share Inserita: 20 marzo 2017 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 Link al commento Condividi su altri siti More sharing options...
stilnovo Inserita: 26 marzo 2017 Segnala Share Inserita: 26 marzo 2017 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 ? Link al commento Condividi su altri siti More sharing options...
ifachsoftware Inserita: 5 aprile 2017 Autore Segnala Share Inserita: 5 aprile 2017 Le operazioni con DW in SCL non sono ammesse. Appena trovo un poco di tempo testo le tua funzione. Per ora grazie Link al commento Condividi su altri siti More sharing options...
stilnovo Inserita: 8 aprile 2017 Segnala Share Inserita: 8 aprile 2017 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 Link al commento Condividi su altri siti More sharing options...
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora