Vai al contenuto
PLC Forum


Spunto per calcolo matematico in PIC


Eramita Analogico

Messaggi consigliati

Eramita Analogico

Salve, avrei bisogno di uno spunto da seguire per implementare una routine di calcolo con un PIC

I PIC li ho usati in varie applicazioni cavandomela più o meno bene con la programmazione (PicBasic) anche se non sono propriamente un programmatore.

Ora dovrei fare una cosa un po' più complessa e mi servirebbe una mano o se non altro qualche direzione da seguire per cercare di risolvere da solo.

 

In sostanza devo usare un PIC16F877A per controllare il circuito PLL di un ricetrasmettitore radioamatoriale, quindi da una frequenza impostata e visualizzata sul display dovrei calcolare i valori dei divisori da scrivere nel PLL (un M54959 <http://datasheet.elcodis.com/pdf2/73/0/730068/m54959p.pdf>)

La parte di comunicazione penso di saperla gestire, ma per strutturare la routine di calcolo ho qualche difficoltà.

 

Le formule in gioco sono queste.

Per calcolare la frequenza sintonizzata avendo già noti i valori dei divisori:

 

F = (A+128*N)*ref (dove ref = 6,28 oppure 5)

 

Mentre a me serve questo passaggio, per calcolare i divisori dopo aver impostato la frequenza desiderata:

m = intero che arrotonda F/ref
A = m / 128 (scartando i decimali dopo la virgola)
N = m mod 128 (cioe' m-128*A)

 

Ora, quante e quanto lunghe sono le variabili che mi servono?

Che passaggi devo fare per ottenere una routine efficiente? Non necessariamente in Basic, ma anche in altri linguaggi tipo C, poi magari mi arrangio io a tradurre una volta chiaro il concetto.

 

Le mie incognite sono sul fatto che per i calcoli di cui sopra probabilmente è conveniente avere il valore di frequenza in un'unica variabile a 32 bit (per gestire sia 144000000 Hz che 430000000 Hz, mentre per gestire il display forse è più comodo avere le singole cifre della frequenza in altrettante variabili ad 8 bit (eventualmente come ottenerle?), ma come detto non sono esperto in programmazione quindi se potessi avere qualche indicazione migliore vi ringrazierei molto.

 

Link al commento
Condividi su altri siti


877 è veramente anziano, avrebbe diritto alla pensione anche con legge Fornero.😃

 

Amenità a parte io ti consiglierei di usa il "C" cone linguaggio, usando le variabili in real.

Poi quando devi passare il fattore di divisione intero fai un semplice casting da real a intero.

 

Per il display, dipende da cosa stai usando. Se usassi, ad esempio, un LCD 2x16, ci sono lellibririe in "C" che ti permettono di scrivere direttamente passando la variaabile.

Se invece hai altri diplaies nunmerici devi farti la conversione binario-->BCD.

Link al commento
Condividi su altri siti

Eramita Analogico

Grazie per la risposta,

come display userò l'originale della radio, quindi con comunicazione seriale direttamente nel driver LCD, e questo penso di poterlo fare da solo.

 

La variabile real sarebbe quella a 32 bit che ipotizzavo?

Cosa si intende e come si esegue un "casting"?

 

Sì, l'877A ha i suoi anni ma essendo ancora in produzione l'ho preferito un po' perché già lo conosco e un po' perché uno più moderno sarebbe stato probabilmente sprecato.

Link al commento
Condividi su altri siti

8 ore fa, Eramita Analogico ha scritto:

La variabile real sarebbe quella a 32 bit che ipotizzavo?

 

Le real sono in virgola mobile.

La lunghezza dipende dal compilatore: ci sono compilatori che permettono di dichiarare shrt real e long real. In "C" le variabili reali sono denominate "float" ed in genere sono in 32 bit (4 byte),   ci sono compilatori "C" per PIC che ammettono anche gli short float in 16 bit.

 

L'operazione di casting è la conversione di un dato da un tipo ad un altro. Se dichiari "A" come intero e "B" come float se fai A = B, il compilatore esegue il casting eguagliando A alla parte intera di B e troncando i decimali.

Link al commento
Condividi su altri siti

Eramita Analogico

Se ho capito tu suggerisci di gestire il valore della frequenza non come hertz (tipo 145650000 Hz) ma direttamente come megahertz usando le variabili a virgola mobile (quindi 145,650000 MHz)

Perdona la banalità delle mie domande, ma in questo modo sarebbe più conveniente?

 

Per quanto riguarda il processo di gestione, riassumo come farei così da capire se può essere un modo valido o se si può far di meglio.

 

Innanzitutto ho una variabile che contiene il valore della frequenza (virgola mobile o intero a 32 bit è da decidere)

Tramite i comandi della radio posso incrementare o decrementare questo valore in passi di sintonia predefiniti (ad esempio 5000 Hz, 12500 Hz, 25000 Hz o i corrispondenti a virgola mobile 12,500 ecc...)

Dopo aver verificato di non essere fuori banda applico le formule riportate nel messaggio iniziale per ricavare i fattori di divisione da inviare al PLL.

 

Ora mi trovo nella necessità di pilotare anche il display per visualizzare la frequenza contenuta nella variabile grossa, quindi tramite una seconda routine dovrei estrarre una variabile 8 bit per ciascuna cifra; una per le centinaia di MHz, una per le decine, una per le unità e così via, da convertire poi in una stringa adeguata da inviare al controllore del display.

 

Può essere corretto come sistema o conviene seguire un'altra strategia?

Grazie.

 

Link al commento
Condividi su altri siti

18 ore fa, Eramita Analogico ha scritto:

Perdona la banalità delle mie domande, ma in questo modo sarebbe più conveniente?

 

Non ho detto questo, ho suggerito di fare i calcoli in virgola mobile. Che le variabili siano introdotte con numeri interi o in numeri reali cambia poco.

Io, per praticità, userei come unità di misura il MHz evitando così la caterva di zeri.

 

La stategia che intendi usare è corretta, anche perchè non ci sono molte alternative

 

 

Modificato: da Livio Orsini
corretti errori di dattilografia
Link al commento
Condividi su altri siti

  • 1 month later...

Ciao,

magari nel frattempo avrai già fatto...

 

comunque in C su microcontrollore, personalmente, tratterei la variabile come Hz e quindi un unsigned int32. Per ottenere le singole cifre da inviare al display puoi fare una successione di divisioni con modulo (%) e divisioni (/), in basic mi pare che l'operatore % sia MOD

 

esempio :

 

unsigned int valore=145000234;
unsigned char cifra1,cifra2,cifra3,cifra4,cifra5,cifra6,cifra7,cifra8,cifra9;
cifra1 = valore % 10;
valore = valore / 10;
cifra2 = valore % 10;
valore = valore / 10;
cifra3 = valore % 10;
valore = valore / 10;
cifra4 = valore % 10;
valore = valore / 10;
cifra5= valore %10;
valore = valore / 10;
cifra6 = valore %10;

valore = valore / 10;
cifra7 = valore %10;

valore = valore / 10;
cifra8 = valore %10;

cifra9 = valore / 10;

 

cifra9 è la più significativa,

cifra 1 la meno significativa (unità)

 

Ciao,
Pier.

Link al commento
Condividi su altri siti

Eramita Analogico

Ciao, in effetti non ho ancora concluso, è un progetto che sto seguendo a bassa priorità.

Diciamo che la parte hardware è pronta, ora devo trovare il tempo di buttare giù qualche riga.

Grazie per l'esempio, sarà senz'altro utile per proseguire.

 

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...