Fabio Gaeta Inserito: 24 agosto 2014 Segnala Share Inserito: 24 agosto 2014 Salve a tutto. Essendo un nuovo utente vi ringrazio per tutti gli aiuti che potete fornirmi. Ho la necessità in SCL, di cui non sono molto pratico, di eseguire la somma in byte di un'area di memoria di un DB. Mi serve per costruire un CRC di tipo somma. Ho quindi la necessità, sapendo la lunghezza dell'area nel db della parola da scrivere di eseguire la somma. Vorrei eseguire una funzione SCL parametrizzata con due valori in ingresso: un puntatore all'area di memoria da cui iniziare e numero (la grandezza dell'area di memoria). Quindi, a partire dall'area di memoria puntata eseguire la somma di N byte. Sembra banale fatta in C, oppure altri linguaggi che conosco. In SCL, di cui non sono molto pratico, mi viene un pò difficile. Vi ringrazio per l'aiuto function int sum (*pointer char data, int number) { int i; int sum; for (i=0, i<=number, i++) { sum=data+sum; } return sum; } Link al commento Condividi su altri siti More sharing options...
walterword Inserita: 24 agosto 2014 Segnala Share Inserita: 24 agosto 2014 in SCL non ti conviene lavorare con i puntatori .lo scopo per cui e' stato progettato e quello di rendere la vita meno dura al programmatore quando deve eseguire calcoli o lavorare con strutture dati abbastanza complesse Pur essendo un linguaggio struturato tendente al pascal , per come e' la sitnassi , o al C , non e' niente di tutot ciò. La libreria e le funzioni built_in sono abbastanza limitate per quanto si po ssa fare in ambito automazione di quel tipico ambiente di plc. Puoi lavorare con array piu o meno complessi composti da dati definiti , array di array di strutture e/o strutture di array di array di strutture di array , tramite indici che sono in qualche modo puntatori mascherati Non e' possibile usare le funzioni del C come malloc o creare locazioni di memoria dinamicamente Pero' ci sono istruzioni , in scl , che ti permettono di lavorare con i puntatori a tipi di dati tipo byte , ANY , pointer ect Per quanto riguarda la tua funzione che accetta come parametro in ingresso un puntatore a caratteri dovresti rivedere un po la sitnassi , ti consiglio di lavorare con varaibili globali definite si DB globali oppure locali .Nel secondo caso lo stack dei dati e' limitato e rischi che ti escan dei pasticci .Se vuoi lavorare con scl dichiari un db globale con array di caratteri o stringhe all'interno di esse .COn il tipo dati stringa stai attento perche il formato che usa siemens si mangia due byte alla fine di ogni stringa per cui creati una VAT , tabela delle variabili ed inizia a giocare con array di caratteri e stringhe e vedi cosa succede altrimenti rischi di perdere giornate inutilmente .....esperienza personale Per cui se usci scl , dimentica il C o altri linguaggi di programmazione e interpreta scl piu come un linguaggio di scripting per plc Link al commento Condividi su altri siti More sharing options...
Fabio Gaeta Inserita: 24 agosto 2014 Autore Segnala Share Inserita: 24 agosto 2014 ho eseguito il seguente programma scl e restituisce quello che volevo. In pratica ho costruito un CHECKSUM Vi fornisco il codice così ne possiamo discutere FUNCTION_BLOCK FB30 TITLE = 'CRCSUM' AUTHOR : 'GAETA' VAR_INPUT nData : ANY; iLenght : INT; END_VAR VAR_OUTPUT wCrcSum : WORD; END_VAR VAR_TEMP I : INT; // Contatore pDB : ANY; // Puntatore al blocco dati DBAny AT pDB : STRUCT // Definizione struttura per il tipo di dati ANY S7Code : BYTE; // Codice per S7 = 0x10 DataType : BYTE; // Codice per il tipo DB (0x02 = byte) Length : INT; // Fattore di ripetizione = Lunghezza send/receive DBNumber : INT; // Numero DB MemoryArea : BYTE; // Specifica l'area di memoria (0x84 = DB) ByteAddressMSB : BYTE; // Bits più significativo del byte ByteAddressLSB : WORD; // Bits meno significativo del byte END_STRUCT; uAddr : DWORD; // Unione del puntatore per calcolare l'offset dell'indirizzo del byte union AT uAddr : STRUCT // Equivale a fare una unione in C ByteAddrLSBPad : BYTE; // Non usato ByteAddrMSB : BYTE; // Bits più significativo del byte WordAddr : WORD; // Bits meno significativo del byte END_STRUCT; CRCData : BYTE; // Appoggio byte letto RetVal : INT; // Valore di ritorno della funzione BLKMOV END_VAR pDB := nData; DBAny.DataType := B#16#02; // Azzero le variabili union.ByteAddrLSBPad := 0; union.ByteAddrMSB := DBAny.ByteAddressMSB; union.WordAddr := DBAny.ByteAddressLSB; wCrcSum := 0; FOR I := 0 TO iLenght DO // Punto al bit più significatico DBAny.ByteAddressMSB := union.ByteAddrMSB; // Punto al bit meno significativo DBAny.ByteAddressLSB := union.WordAddr; // Trasferisco il byte puntato nel DB alla variabile di appoggio RetVal := BLKMOV(SRCBLK := pDB, DSTBLK := CRCData); // Somma parziale wCrcSum := INT_TO_WORD(BYTE_TO_INT(CRCData) + WORD_TO_INT(wCrcSum)); // Incremento di 8 bits per puntare al successivo byte uAddr := DINT_TO_DWORD(DWORD_TO_DINT(uAddr) + 8); END_FOR; END_FUNCTION_BLOCK Link al commento Condividi su altri siti More sharing options...
Fabio Gaeta Inserita: 24 agosto 2014 Autore Segnala Share Inserita: 24 agosto 2014 Mi chiedo: se la lunghezza supera un certo valore e il calcolo quindi richiede un tempo lungo, il PLC potrebbe andare in STOP? Link al commento Condividi su altri siti More sharing options...
walterword Inserita: 24 agosto 2014 Segnala Share Inserita: 24 agosto 2014 se il tempo di esecuzione del programma , in generale , supera il tempo di watchdog specificato in configurazione hw allora il plc va in stop .Il plc deve elaborare dati provenienti da processi e impianti e rispondere entro un certo tempo , comunque in OB1 c'e' un parametro che ti dice quanto tempo ha impeigato il programma ad essere eseguito e se vedi che e' troppo alto (ovviamente fai un test dove fai girare solo la tua funzione ) puoi implementare una macchina a stati ed elaborare i tuoi dati a passi , uno o pu passi per ogni ciclo di scansione e sincronizzare il tutto al termine . Bravo , finalmente qualcuno che lavora seriamente ed usa SCL comunque puoi sempre lavorare con un array di strutture dati , cioe tabelle . Se poi il tipo di dato byte in SCL ti crea problemi usi gli interi e via 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