[pic] - msb --> lsb

ciao!

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-

Reply to
ice
Loading thread data ...

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-

Reply to
Marcello

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

-ice-

#inline void putc_reverse(int i) { #bit i0=i.0 #bit i1=i.1 #bit i2=i.2 #bit i3=i.3 #bit i4=i.4 #bit i5=i.5 #bit i6=i.6 #bit i7=i.7 int j; #bit j0=j.0 #bit j1=j.1 #bit j2=j.2 #bit j3=j.3 #bit j4=j.4 #bit j5=j.5 #bit j6=j.6 #bit j7=j.7 j0=i7; j1=i6; j2=i5; j3=i4; j4=i3; j5=i2; j6=i1; j7=i0; putc(j, DSP); } // putc_reverse()

Reply to
ice

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-

Reply to
Marcello

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

Reply to
lowcost

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)

grazie!

-ice-

int d0,d1; int l0,l1; #locate l0=l #locate l1=l+1 #asm RLCF l0,1 RRCF d0,1 RLCF l0,1 RRCF d0,1 RLCF l0,1 RRCF d0,1 RLCF l0,1 RRCF d0,1 RLCF l0,1 RRCF d0,1 RLCF l0,1 RRCF d0,1 RLCF l0,1 RRCF d0,1 RLCF l0,1 RRCF d0,1 RLCF l1,1 RRCF d1,1 RLCF l1,1 RRCF d1,1 RLCF l1,1 RRCF d1,1 RLCF l1,1 RRCF d1,1 RLCF l1,1 RRCF d1,1 RLCF l1,1 RRCF d1,1 RLCF l1,1 RRCF d1,1 RLCF l1,1 RRCF d1,1 #endasm putc(d0, _DSP); putc(d1, _DSP);

Reply to
ice

mi correggo subito :) ***la rotazione di 2 bytes con 32 istruzioni***

a cui sommarne altre 8(6) ecc...

-ice-

Reply to
ice

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-

Reply to
Marcello

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-

Reply to
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:

int l0,l1; #locate l0=l #locate l1=l+1 #asm RLCF l0,1 RRCF l1,1 RLCF l0,1 RRCF l1,1 RLCF l0,1 RRCF l1,1 RLCF l0,1 RRCF l1,1 RLCF l0,1 RRCF l1,1 RLCF l0,1 RRCF l1,1 RLCF l0,1 RRCF l1,1 RLCF l0,1 RRCF l1,1 RLCF l0,1 #endasm fputc(l1, _DSP); fputc(l0, _DSP);

Reply to
ice

ringrazia lowcost è una soluzione in effetti banale ma non necessariamente così intuitiva.

Ciao

Marcello

-Catania-

Reply to
Marcello

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.