per via di uno sfortunato abbinamento mi trovo con un dsp (slave) che può ricevere dati in modo seriale sincrono, msb first
il pic (master) usa la sua uart integrata per comunicare con il dsp... purtroppo la uart configuarata come master-sincrono può trasmettere solo lsb first
c'è un sistema veloce per ribaltare un byte in modo che il suo msb diventi il suo lsb?
grazie!
-ice-
Didn't find your answer? Ask the community — no account required.
M
Marcello
la prima cosa che mi viene in mente è quella di fare una doppia operazione di shift supponiamo che hai il byte da ribaltare che chiami byte e quello invertito che chiami "nuovo".
Fai uno shift verso sinistra di byte. In questo modo msb finisce in C di status. Fai uno shift verso destra di "nuovo". Così facendo msb entra da destra in "nuovo" e si sposterà sempre di più verso destra se cicli questa operazione fino a diventare lsb nel momento in cui hai ripetuto l'operazione per l'ultimo byte. Spero di essermi spiegato. Sinceramente non penso ci siano operazioni più veloci (ma potrei anche sbagliarmi)
Ciao
Marcello
-Catania-
I
ice
ti ringrazio per la risposta
si, ho capito che intendi
al momento ho appena risolto come segue, cmq ora implemento la tua idea e poi conto le istruzioni generate per vedere quale è più efficiente
considera poi che l'efficienza si può considerare in dipendenza del numero di linee di codice oppure nella velocità di esecuzione. Dipende dalle tue esigenze.
Ciao
Marcello
-Catania-
L
lowcost
Marcello ha scritto:
esatto; e se alla fine aggiungi 1 ultimo shift a sx di "byte" hai=20 ribaltato 2 byte, raddoppiando l' efficienza. saluti
I
ice
si certo, ho omesso di specificarlo in effetti! in questa situazione volevo ottimizzare la velocità di esecuzione
RISULTATI: con il metodo che ho postato in pratica la rotazione di un byte mi viene gratis perchè è semplicemente dovuta ad una mappatura forzata delle variabili in memoria (il C della CCS supporta questo anche per le variabili booleane) poi, di contro, dovevo rinunciare alla seriale sincrona hardware e mandare fuori i bit con una routine software. questo mi costava 80 istruzioni per buttare fuori 16 bit (2 bytes) nel caso migliore e 96 istruzioni nel worst-case (sempre per 16 bit ovviamente)
con il metodo da voi suggerito faccio la rotazione di 2 bytes con 40 istruzioni a cui vanno sommate 8 (worst-case, 6 nel best-case) istruzioni per spostare il 2 bytes (prima uno e poi l'altro) nel buffer di trasmissione (poi l'hardware si occupa di serializzarlo e mandarlo al dsp)
quindi, in ogni caso, il metodo delle rotazioni a desta e sinistra è più efficiente! forse marcello suggeriva un ulteriore passaggio visto i bytes da gestire sono proprio 2
è così che intendevi?
- alla funzione viene passato un intero a 16-bit chiamato "l" (elle minuscolo insomma)
- le 2 #locate servono per spezzare "gratis" "l" in due int8 (purtroppo la seriale sincrona del pic non può gestire 16 bit in un colpo solo)
mi correggo subito :) ***la rotazione di 2 bytes con 32 istruzioni***
a cui sommarne altre 8(6) ecc...
-ice-
M
Marcello
Si, solo che, essendo abituato a lavorare più in termini di righe di codice e non di velocità (la gran parte delle volte la velocità non è importante nelle mie applicazioni), io avevo pensato ad un ciclo più che a delle singole istruzioni. Molto probabilmente (dal momento che un'operazione di salto l'equivalente di due istruzioni) con il ciclo il tempo di esecuzione sarebbe maggiore. In ogni caso ottimo mi è sembrato il suggerimento di lowcost che mi sembra tu non abbia considerato (e al momento in effetti a me non era neanche passato per la mente). Tu stai utilizzando una variabile di appoggio in cui ti trovi il risultato. Se al posto di utilizzare una qualsiasi variabile, hai già a disposizione il byte successivo che devi inviare, puoi utilizzare questo. Su questa variabile di appoggio stai infatti effettuando la stessa operazione di inversione tramite shift che stai facendo sulla prima variabile (anche se in maniera inversa). Aggiungendo una operazione di shift in più, così facendo, avrai ribaltato due byte e non uno solo, raddoppiando l'efficenza rispetto all'algoritmo così come lo avevo suggerito io in partenza.
Ciao
Marcello
-Catania-
I
ice
anche perchè, oltre al salto, devi incrementare la variabile di controllo
si
si, la funzione accetta un intero a 16-bit che poi spezzo in 2 int8 perchè il pic che uso è ad 8-bit (RLCF e RRCF accettano un int8)
come inversa? faccio la stessa operazione sia ad "l0" (risultato in "d0") che ad "l1" (risultato in "d1")
in pratica il bit che esce da l0 va a finire nel carry-flag e da qui lo faccio entrare in d0 (idem per la coppia l1/d1)
si, forse ho capito! adesso ci provo :)
grazie! poi faccio sapere
-ice-
I
ice
l'ho implementato! è geniale, vi ringrazio molto! siamo ulteriormente scesi da 38 istruzioni (best-case) a 25 istruzioni (worst-case)
lo riporto nel caso in futuro ad altri possa tornare comodo: