Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Convertire da LSB a MSB ... pic HELP!!!

171 views
Skip to first unread message

Geppo

unread,
Mar 20, 2011, 6:52:26 AM3/20/11
to
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!

Piccio

unread,
Mar 20, 2011, 9:28:13 AM3/20/11
to
On 20 Mar, 11:52, "Geppo" <megadu...@tin.it> wrote:

...


> 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!

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.

dalmontealpiano

unread,
Mar 20, 2011, 11:43:02 AM3/20/11
to
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

bikerfab

unread,
Mar 20, 2011, 2:49:35 PM3/20/11
to
On 20/03/2011 11.52, Geppo wrote:

> 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 ?

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/

Geppo

unread,
Mar 22, 2011, 3:27:20 PM3/22/11
to
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!

bikerfab

unread,
Mar 22, 2011, 7:10:39 PM3/22/11
to
On 22/03/2011 20.27, Geppo wrote:

> La funzioncina in basic che ho fatto è questa pero ho funziona solo per
> 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.

CG Audio Laboratories

unread,
Mar 23, 2011, 6:17:39 AM3/23/11
to
> La funzioncina in basic che ho fatto è questa pero ho funziona solo per
> dati in formato LSB e funziona abbastanza bene "provata con simulatore" :

Bleah!!! Il basic non è adatto a programmare microcontrollori!
Il migliore è il C, ma se proprio non ci riesci usa ALMENO il Pascal!!!

> 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

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


bikerfab

unread,
Mar 23, 2011, 5:03:21 PM3/23/11
to
On 23/03/2011 0.10, bikerfab wrote:
> 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.

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.

AntonioBignami

unread,
Mar 23, 2011, 5:08:10 PM3/23/11
to
Il 22/03/2011 20:27, Geppo ha scritto:
> 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

Sono tanti anni che non uso il basic e non ricordo se siano disponibili
le istruzioni di shift a destra o a sinistra.
Sono disponibili?
Se si, alloora usa lo schift e la funzione nad (quella sono quasi
sicuro che sia disponibile).
ciao
Angelo


dalmontealpiano su un altro computer.

> Grazie ancora!

Geppo

unread,
Mar 24, 2011, 3:34:58 AM3/24/11
to
bikerfab ha scritto:

>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.

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!


Geppo

unread,
Mar 24, 2011, 3:42:46 AM3/24/11
to
"AntonioBignami" ha scritto nel messaggio
news:4d8a6139$0$38648$4faf...@reader1.news.tin.it...

>Sono tanti anni che non uso il basic e non ricordo se siano disponibili le
>istruzioni di shift a destra o a sinistra.
>Sono disponibili?
>Se si, alloora usa lo schift e la funzione nad (quella sono quasi sicuro
>che sia disponibile).
>ciao
>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!

dalmontealpiano

unread,
Mar 24, 2011, 5:31:24 AM3/24/11
to
Il 24/03/2011 8.42, Geppo ha scritto:
> 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!
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.

CG Audio Laboratories

unread,
Mar 25, 2011, 6:11:59 AM3/25/11
to
> 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!

Ti ho dato il codice corretto sia in basic sia in C. Forse non vedi il post?

Ciao
CG


STeve

unread,
Mar 25, 2011, 7:13:15 PM3/25/11
to
On Mar 23, 5:17 am, "CG Audio Laboratories"

<cgaudiolaborator...@interfree.it> wrote:
> Bleah!!! Il basic non è adatto a programmare microcontrollori!

Concordo, non tanto per la mancanza di costrutti decenti, ma per la
mentalita' che ti costringe ad usare.

> Il migliore è il C, ma se proprio non ci riesci usa ALMENO il Pascal!!!

Pascal ????

Anyway, non mi torna una cosa .. va beh,tante, ma questa pero' proprio
non la capisco :)
Uso il tuo esempio che e' piu' chiaro.

> 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);
>     }
> }

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

STeve

unread,
Mar 25, 2011, 7:35:11 PM3/25/11
to
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);

F. Bertolazzi

unread,
Mar 25, 2011, 11:24:45 PM3/25/11
to
STeve:

> Pascal ????

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

NNTP

unread,
Mar 26, 2011, 4:53:34 AM3/26/11
to
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

0 new messages