Problema di casting TO_UINT su array di byte
Home › Forum › Programmazione IEC 61131 (LogicLab) › Problema di casting TO_UINT su array di byte
- Questo topic ha 3 risposte, 2 partecipanti ed è stato aggiornato l'ultima volta 10 anni, 2 mesi fa da
Sergio Bertana.
-
AutorePost
-
Dicembre 17, 2013 alle 2:15 pm #35467
Anonimo
OspiteHo la necessità di convertire il contenuto di un array di numeri USINT in numeri a 16 bit UINT. Per comodità ho usato la macro TO_UINT applicandola sul vettore stesso.
ptrWrd := ADR( buf[13] );
wrd := TO_UINT( @ptrWrd );Ho scoperto che per indici pari (o divisibili per 2) la macro funziona correttamente, ma per indici dispari sbaglia clamorosamente il cast della variabile. Credevo che funzionasse per qualsi varabile in entrata (come menzionato nel manuale) e che quindi si gestisse da sola lo spiazzamento in memoria della variabile d’entrata. E’ un bug ? Oppure l’array di byte non essendo un numero da luogo a spiazzamenti imprevisti ? Ho risolto in questo modo:
wrd := TO_UINT(buf[14]); (* MSB *)
wrd := SHL(wrd, 8);
wrd := wrd OR TO_UINT(buf[13]); (* LSB *)Dicembre 18, 2013 alle 3:38 pm #37930Sergio Bertana
Amministratore del forumI nostri sistemi SlimLine sono basati su architettura ARM, questo tipo di architettura vuole che le variabili a due bytes siano allocate ad indirizzi divisibili per 2 e le variabili a 4 bytes siano allocate ad indirizzi divisibili per 4. L’allocazione delle variabili ad indirizzi che non rispondono a queste regole ne rende impossibile l’accesso.
LogicLab provvede automaticamente ad allocare le variabili seguendo le direttive imposte dalla architettura ARM, ma utilizzando un puntatore su di un array di bytes ecco che sarà il tuo programma a gestire l’indirizzamento e quindi quando ti trovi a puntare indirizzi pari verrà letta corettamente la variabile UINT (Come sequenza di due bytes) mentre se l’indirizzo è dispari la variabile non viene letta correttamente.
Ma devi anche prestare attenzione all’endiannes dei dati, l’architettura ARM è di tipo Little-Endian, quindi il byte meno significativo si trova ad indirizzo più basso rispetto al byte più significativo. Come vedi dallo screenshot del programma ByteToWord, ho allocato un array di bytes a MX100.0 (In questo modo sono sicuro che sono allocati ad indirizzo pari divisibile per 4).
Quando il puntatore a WORD punta l’indice 2 dell’array il risultato Result[0] è corretto (Il valore di LSB è l’indirizzo puntato mentre l’MSB è indirizzo+1, Little-Endian). Quando il puntatore a WORD punta l’indice 3 dell’array il risultato Result[1] è errato.
Gennaio 30, 2015 alle 12:22 pm #38702Anonimo
InattivoHo il seguente problema. Dopo avere acquisito un valore di tensione attaverso un modulo analogico, mi trovo con la necessità di trasferire questo valore in una word al fine di consentire al PC collegato in Modbus TCP di tenere aggiornata la visualizzazione di questa variabile ed altre varie condizioni
Mi rendo ovviamente conto che perdo precisione ma in realtà io acquisico un valore in V dal modulo analogico, ad esempio 8,8888888 V. Lo moltiplico in seguito x il mio fattore di conversione pari a 16 ed ottengo 142,222208. se adesso moltiplico questo valore per 100, ottenendo 14222,2208 i primi 5 caratteri 14222 contengono più di quello che mi serve, ma se utilizzo ad esempio la TO_UINT il compilatore mi alza un warning e la word non viene aggiornata. Come posso risolvere il problema ?
Gennaio 30, 2015 alle 2:26 pm #38703Sergio Bertana
Amministratore del forumQuello che fai è corretto, è un normale cast di una variabile, unica accortezza è controllare che il valore massimo che assume la variabile REAL dopo i calcoli non superi il valore che può essere espresso in una variabile UINT (65535).
Nel tuo caso il massimo può essere 10.0*16.0*100.0=16000.
Ma se fai tutte le operazioni così come mi scrivi il compilatore non deve dare nessuna warning e la conversione deve funzionare come vedi dal mio screenshot. Non è che la variabile WORD è allocata in memoria ad un indirizzo che non è divisibile per 2.
-
AutorePost
- Devi essere connesso per rispondere a questo topic.