Newsgroup: it.hobby.elettronica.digitale
Titolo: Convertire da LSB a MSB ... pic HELP!!!

Ciao,
ho i soliti 3 pin di invio dati.
1 Clock
2 Data
3 Le
La periferica che trasmette è un PIC 16F876 mentre il ricevente è un PLL
Il PLL in questione vuole i dati solo MSB----------LSB
Tramite un semplice ciclo sono riuscito a preparare i dati in modo 
LSB------MSB.
Esiste la possibilità di convertire la presentazione dei dati ?
Grazie mille! 

 Grazie mille!
Tramite l'istruzione "RLF" (Rotate Left f through Carry).
Sposta nel CY l'MSB, effettua il salto condizionato in base del CY per
8 cicli e il gioco è fatto.
Piccio.


Di solito in questi casi si compone un byte attraverso i bit che abbiamo 
man mano a disposizione.
Se e' cosi', basta invertire il ciclo di rotazione del byte ricostruito, 
facendo lo shift a sinistra anziche' a destra.
Unico avvertimento, dato che altrimenti si rischia di perdere uno o piu' 
bit, iniziare lo shift prima di aggiornare la coda del byte.
Se invece usi un modo diverso di ricostruire il byte, forse e' il caso 
che tu pubblichi la funzione che usi per vedere se qualcuno e' in grado 
di darti un aiuto.
ciao
Angelo

 Esiste la possibilità di convertire la presentazione dei dati ?
non fai prima a costruire il dato da inviare già nel formato che piace 
al ricevitore ? se è un numero è già di suo in questo formato (comunque 
è una questione di endian, il pic come memorizza i bit in un byte ?). In 
ogni caso, piuttosto che creare un byte al contrario e poi girarlo, 
tanto vale crearlo già giusto. Il tutto se ho capito la domanda :-)
Immagino che tu intenda Most/Least Significant Bit (non Byte).
-- 
bikerfab
Viaggi in bicicletta, report foto e informazioni
Travelling by bicycle, report, pics and information
http://bikerfab.altervista.org/

Vi ringrazio per le risposte...provo a spiegarmi un po meglio.
Il pll in questione è un LMX1501.
Devo riempire 2 registri:
1 a 19 bit e 1 a 14 bit
Faccio un esempio, prendo i 14 bit del secondo registro.
Gli devo "sparare" dentro il numero 800 in binario sarebbe 00000100110000 
questo sarebbe in formato LSB.
Ora pero dovrei mandarglielo in 00001100100000 ovvero in MSB
La funzioncina in basic che ho fatto è questa pero ho funziona solo per dati 
in formato LSB e funziona abbastanza bene "provata con simulatore" :
dim a,b as word
dim dato as bit
dim k as byte
a=800
a= a DIV 2 ( divisione in cui ottengo un intero)
b=a MOD 2 ( divisione in cui ottengo il resto )
for k=0 to 13
if b =0
    dato=0 else dato=1
end if ( se ho resto il bit è 1 se non ho resto ho 0 )
PORTC.1=dato    ( preparo il dato )
PORTC.0=0         (clock fronte basso)
delay_us(10)
PORTC.0=1         (clock fronte alto)
delay_us(10)
next k
Grazie ancora! 

 dati in formato LSB e funziona abbastanza bene "provata con simulatore" :
Per pietà, prova ad usare linguaggi meno osceni del basic per questi lavori.
Senza pretendere l'asm, in C prendi il numero, fai l'AND con una 
maschera che ha un 1 nella posizione del bit che ti serve (dato che il 
pll ha registri di lunghezza diversa, quindi l'msb sarebbe il 14°, ad 
esempio), se il risultato è zero spari uno zero, se è diverso da zero 
spari un 1 al pll. Poi fai shift a sinistra e buonanotte, il tutto per 
il numero di bit che ti servono.
Se proprio te l'ha ordinato il medico di usare il basic :-) prendi 
quella funzione e invece di sparare direttamente il bit, crea una var 
temporanea che inizializzi a zero e poi ad ogni giro del tuo loop gli 
sommi 2^k - 1  se dato è uguale a 1. Alla fine del loop hai il valore a 
con i bit girati.
Spero di essere stato chiaro e di non aver detto stupidaggini, 
considerando che è mezzanotte.


 next k
ma se fai il ciclo semplicemente scrivendo
for k=13 to 0
non lo fa nel senso opposto?
considera che in C puoi scrivere tranquillamente
for (k = 0; k < 13; k++) ;
oppure
for (k = 13; k > 0; k--)
E tutto il tuo programma diventa
void FUNZIONE (void) {
    unsigned int a, b;
    boolean dato;
    unsigned char k;
    a = 800;
    a /= 2;
    b = a % 2;
    for (k = 13; k > 0; k--) {
        if (!b) dato = 0; else dato = 1;
        PORTC.1 = dato;
        PORTC.0 = 0;
        delay_us(10);
        PORTC.0 = 1;
        delay_us(10);
    }
}
non mi torna cosa fai però ti ho fatto vedere come diventa in C. Se 
scrivessi un programma così per l'azienda dove lavoro sarei licenziato in 
tronco :)
Ciao
CG

 considerando che è mezzanotte.
appunto, era mezzanotte. Errata corrige, sommi 2^(N-k) dove N è il 
numero di bit del registro. Che poi per calcolare 2^qualcosa in basic ci 
metta mezza giornata mentre in C è uno shift, è un altro discorso. 
Traduzione, cambia linguaggio.


 Grazie ancora!

cambia linguaggio.
Ciao! per essere piu preciso uso Mikrobasic della Mikroe. Lo shift c'è come 
comando.
L'uso che ne faccio io è puramente hobbystico e fino ad oggi ho avuto le mie 
piccole soddisfazioni con tale programma "della MIKROE"
Faccio una prova con la formula da te consigliata e ti faccio sapere.
Grazie ancora!

Angelo
Ciao Angelo la versione che uso č Mikrobasic della MIKROE.
Capisco che non č il massimo come linguaggio, ma l'uso č puramente 
hobbystico.
I comandi di shift sono presenti. Penso di dover leggere bene da qualche 
parte l'utilizzo dei comandi di shift a dx o a sx perchč non mi sono ben 
chiari.
Se per caso mi potete dare 2 dritte sull'utilizzo del comando di shift mi 
fate un grande piacere.
Grazie a tutti! 

 Grazie a tutti!
per ricostruire il byte usando lo shift
byte = 0;
inizio ciclo di 8 iterazioni
byte = shift left/right 1 posizione
eseguo il primo shift sul byte vuoto
se eseguo shift right per 8 volte, costruisco il byte con il primo bit 
inserito che, al termine si trovera' nel bit 0 del byte.
con shift right
controllo se il bit da inserire == 1
se bit == 1
eseguo l'or
byte | 0x10000000
se non ho terminato le 8 iterazioni torno a inizio ciclo.
fine ricostruzione di 1 byte
se eseguo shift right per 8 volte, costruisco il byte con il primo bit 
inserito che, al termine si trovera' nel bit 0 del byte.
con shift left
controllo se il bit da inserire == 1
se bit == 1
eseguo l'or
byte | 0x00000001
se non ho terminato le 8 iterazioni torno a inizio ciclo.
fine ricostruzione di 1 byte
Spero di non aver scritto cose errate; comunque sia, il metodo funziona, 
al limite posso essermi incasinato nello scrivere qualche passo, ma 
dovresti essere in grado di capire il procedimento.
ciao
Angelo
N.B. Il primo shift deve essere eseguito sul byte vuoto per non perdere 
la ricostruzione dell'ultimo bit.

 Grazie a tutti!
Ti ho dato il codice corretto sia in basic sia in C. Forse non vedi il post?
Ciao
CG 

 }
b e' preparato fuori dal loop, il test di b e' dentro il loop.
b non cambia dentro il loop, quindi come fa il dato a cambiare ?
Poi il loop fa solo 13 bit e non 14, il test nel loop e' "se maggiore
di zero", non "se maggiore uguale a zero" (che comunque non
funzionerebbe, anziche' 13 basta partire da 14).
Qualcosa tipo :  for (k = 14; k > 0; k--)
Se dovessi spedire il dato 800 decimale (320 hex) dall'MSB userei una
maschera per selezionare il bit, come nikerfab aveva suggerito.  E' il
modo migliore.
Dato che si vuole caricare il registro con 14 bit, la maschera parte
dal 14esimo bit, ovvero 0x2000.
A scanso di confusione, il 14esimo bit e' il bit 13.
Poi assumiamo che l'intero sia di 16 bit, sarebbe piu' corretto usare
un unsigned short.
void FUNZIONE (void)
{
   unsigned short a, mask;
   boolean dato;
   unsigned char k;
   a = 0x320;            /* 800 decimale in hex */
   mask = 0x2000;   /* 0010 0000 0000 0000 */
   for(k = 0; k <= 13; k++)     /* k e' ininfluente che decresca o
cresca, basta il ciclo sia per 14 bit */
   {
      if(a & mask)
          dato = 1;
      else
           dato = 0;
       /*
        *  In C viene piu' elegante e veloce pero' usare una
condizionale :
        *  dato = (a & b) ? 1 : 0;
        */
       mask >>= 1;            /* Sposto la maschera sul bit successivo
da testare con lo shift a destra  */
       PORTC.1 = dato;
       PORTC.0 = 0;
       delay_us(10);
       PORTC.0 = 1;
       delay_us(10);
    }
}
E per finire, dando un'occhiata al datasheet del chip, mi sa che i
delay sul clock non sono necessari a meno che si usi un Cray per
pilotare l'I/O :-)
Il tempo minimo di transizione del clock e' di 50 ns.
Gia' con il basic ...
C'ya
  STeve

Una funzione generica per inviare i bit al chip (max 16 bit)  potrebbe
venire cosi' :-)
void invia_nbit_dato (unsigned char nbit, unsigned short dato)
{
   unsigned short mask = 1 << (nbit -1);
   for(; nbit > 0; nbit--)
   {
      PORTC.1 = (dato & mask) ? 1 : 0;
      mask >>= 1;
      PORTC.0 = 0;
      PORTC.0 = 1;
    }
 }
nbit deve contenere il numero reale di bit da spedire.
E la si userebbe cosi' :
invia_nbit_dato(14, 800);

 Pascal ????
Boh, evidentemente non sei informato sul fatto che esistano solo tre
linguaggi di programmazione, ovvero Fortran, Algol e Eiffel.
E piů benemeriti figli.

Il 20/03/2011 11.52, Geppo ha scritto:

In picbasic (che mi trovo benissimo) è semplicissimo:
x     var byte
dato  var word
for x=0 to 15
   portc.1=dato.15	'out dato
   portc.0=1:portc.0=0	'CK
   dato= dato << 1	' shift 1bit
next