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!
...
> 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.
> 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/
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!
> 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.
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
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.
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!
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!
>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!
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.
Ti ho dato il codice corretto sia in basic sia in C. Forse non vedi il post?
Ciao
CG
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
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.
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