Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

AVR 8 bit: unsigned integer e FPU SW emulation

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

3
voti

[21] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteGuidoB » 1 dic 2021, 2:12

Se vuoi moltiplicare a virgola fissa, e hai a disposizione al massimo interi a 32 bit (uint32_t), e la frequenza massima che vuoi ottenere è di 50 MHz (50.000.000 Hz)... non puoi moltiplicarla per numeri maggiori di 85, altrimenti hai un overflow :( (il risultato supererebbe 2^{32}).

Quindi non puoi moltiplicare 50.000.000 per 1527 e poi dividere per 64.

Però, se ti basta una granularità di regolazione di 100 Hz, puoi moltiplicare 500.000 per 1527, dividere per 64 e moltiplicare per 100, o più in generale:

\Delta_\phi = \frac {\left \lfloor \frac{f_\text{out}}{100} \right \rfloor \times 1527} {64} \times 100

Però la frazione \frac{1527}{64} si discosta da \frac{2^{32}}{180\times10^{6}} per 65 parti per milione.

Una frazione che la approssima a meno di 0,1 parti per milione è \frac{3603}{151}:

\Delta_\phi = \frac {\left \lfloor \frac{f_\text{out}}{100} \right \rfloor \times 3603} {151} \times 100

La routine della divisione intera (al posto dello shift a destra di 6 bit) non è poi così terribile. Si può anche eseguire. La precisione ottenibile è circa pari a quella dei float (a 32 bit), che hanno 7 cifre significative.
L'operazione dovrebbe risultare più veloce, e il programma più snello al non includere le routine di calcolo dei float.

Volendo arrotondare il risultato della divisione all'intero più vicino, anziché troncarlo, raddoppiamo numeratore e denominatore (riusciamo ancora a stare dentro i 32 bit), e aggiungiamo 1 al numeratore:

\Delta_\phi = \frac {\left \lfloor \frac{f_\text{out}}{100} \right \rfloor \times 7206 + 1} {302} \times 100

Magari potresti provare a fare una simulazione esaustiva su PC su tutte le frequenze da 100 Hz a 50 MHz, a passi da 100 Hz, e vedere che differenze ti danno il calcolo con i double, i float e quello con la frazione. Probabilmente sotto i 10 MHz i calcoli coincidono sempre. Bisogna anche vedere che precisione serve. Se andiamo oltre la precisione del quarzo che ti genera il clock, dovrebbe bastare.

Non ci sono i double nel compilatore che usi? O gli interi a 64 bit?

C'è un altro modo per fare le moltiplicazioni, spezzando moltiplicando e moltiplicatore in "parte alta" e "parte bassa" ed eseguendo quattro moltiplicazioni e tre somme:
a\times b = \left ( a_{H} + a_{L} \right ) \times \left ( b_{H} + b_{L} \right ) = a_{H}b_{H} + a_{H}b_{L} + a_{L}b_{H} + a_{L}b_{L}
Mi pare che così si riesca ad avere il prodotto su un numero doppio di bit (64 anziché 32 per esempio), ma non ricordo bene il procedimento.

O_/
Big fan of ƎlectroYou!       Ausili per disabili e anziani su ƎlectroYou
Caratteri utili: À È É Ì Ò Ó Ù α β γ δ ε η θ λ μ π ρ σ τ φ ω Ω º ª ² ³ √ ∛ ∜ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ∃ ∄ ∆ ∈ ∉ ± ∓ ∾ ≃ ≈ ≠ ≤ ≥
Avatar utente
Foto UtenteGuidoB
16,5k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 2526
Iscritto il: 3 mar 2011, 16:48
Località: Madrid

1
voti

[22] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteGioArca67 » 1 dic 2021, 10:05

gvee ha scritto:
Il datasheet dice che f_\text{out} è in MHz,

No, se esprimi fck in MHz ottieni fout in MHz, se lo esprimi in Hz ottieni four in Hz....

gvee ha scritto: ma facendo due calcoli con l'esempio di pag. 14 i conti non tornano. Secondo questo esempio, la FTW è:

FTW = 0x0e38e38e = 238609294 da cui f_\text{out} = 10e6 (Hz) e non 10 (MHz), quindi nella formula f_\text{out} è unsigned int.



Dal conto con quella Tuning Word è corretto 180*238609294/2^23=9,99999...

Ma con che risoluzione devi generare le frequenze?
Avatar utente
Foto UtenteGioArca67
2.218 3 4 9
Master
Master
 
Messaggi: 2033
Iscritto il: 12 mar 2021, 9:36

1
voti

[23] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteGuidoB » 1 dic 2021, 10:20

La notte porta consiglio, e mi sono reso conto che moltiplicare e dividere per 100, per frequenze basse introduce un errore ben più alto di 0,1 ppm.
Anche l'arrotondamento, richiedendo di dividere per un denominatore doppio, fa perdere un bit di risoluzione, quindi tanto vale evitarlo e tenersi quel bit di risoluzione in più.

Quindi riformulo la proposta così: fino alla frequenza f_\text{out} di 1.192.053 Hz utilizzare la formula

\Delta_\phi = \frac {f_\text{out} \times 3603} {151}

Per f_\text{out} più grandi, dividere f_\text{out} per 2 (shift a destra) tante volte quante sono necessarie per rientrare nel limite di 1.192.053 Hz, effettuare il calcolo e poi moltiplicare (shift a sinistra) per lo stesso numero di volte.
Big fan of ƎlectroYou!       Ausili per disabili e anziani su ƎlectroYou
Caratteri utili: À È É Ì Ò Ó Ù α β γ δ ε η θ λ μ π ρ σ τ φ ω Ω º ª ² ³ √ ∛ ∜ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ∃ ∄ ∆ ∈ ∉ ± ∓ ∾ ≃ ≈ ≠ ≤ ≥
Avatar utente
Foto UtenteGuidoB
16,5k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 2526
Iscritto il: 3 mar 2011, 16:48
Località: Madrid

0
voti

[24] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto Utentegvee » 1 dic 2021, 10:21

Ciao Guido,

GuidoB ha scritto:Quindi non puoi moltiplicare 50.000.000 per 1527 e poi dividere per 64.

No, ma teoricamente potrei prima dividere per 64 e poi moltiplicare per 1527 perché i risultati ci stanno in 32 bits.

Avevo intenzione di valutare oggi gli errori su tutto il range. Più tardi mi leggo il post con calma, intanto ti ringrazio. :-)

GioArca67 ha scritto:No, se esprimi fck in MHz ottieni fout in MHz

Analog Devices ha scritto:System Clock = direct input reference clock (in MHz)

Ops ! Avevo letto di fretta ! Quindi è una moltiplicazione tra float.

gvee ha scritto:Avete ragione sul fatto di fare uno shift a sinistra, (...)

Avrei dovuto scrivere a destra. :roll:
Avatar utente
Foto Utentegvee
970 2 7
Stabilizzato
Stabilizzato
 
Messaggi: 354
Iscritto il: 11 feb 2018, 20:34

0
voti

[25] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteEcoTan » 1 dic 2021, 10:28

Ma insomma 'sti float si possono usare o no?
Se sì usiamoli, se no quello che ho scritto in [13] non mi pare tanto sballato (né tanto diverso da quanto letto).
Avatar utente
Foto UtenteEcoTan
6.613 4 11 13
Expert EY
Expert EY
 
Messaggi: 4528
Iscritto il: 29 gen 2014, 8:54

0
voti

[26] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto Utentegvee » 1 dic 2021, 10:39

EcoTan ha scritto:Ma insomma 'sti float si possono usare o no?

Secondo quanto detto da Foto Utentexyz direi di sì.

EcoTan ha scritto:Se sì usiamoli, se no quello che ho scritto in [13] non mi pare tanto sballato (né tanto diverso da quanto letto).

Ma quella non è la rappresentazione binaria secondo l'IEEE 754.

Comunque appena avró tempo farò qualche prova con un Arduino e avr-libc.
Avatar utente
Foto Utentegvee
970 2 7
Stabilizzato
Stabilizzato
 
Messaggi: 354
Iscritto il: 11 feb 2018, 20:34

0
voti

[27] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteEcoTan » 1 dic 2021, 10:47

gvee ha scritto:Ma quella non è la rappresentazione binaria secondo l'IEEE 754

non è float ma è pur sempre binaria, potrei chiamarla Integer se non fosse per la presenza della virgola.
Avatar utente
Foto UtenteEcoTan
6.613 4 11 13
Expert EY
Expert EY
 
Messaggi: 4528
Iscritto il: 29 gen 2014, 8:54

0
voti

[28] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto UtenteGioArca67 » 1 dic 2021, 11:56

Per tenere conto della precisione totale dell' AD9851 0,04Hz circa (180MHz/2^32) un float non è sufficiente.
Ad es se in un float immagazzina fout maggiore di 33554432Hz non riesce ad avere una granularità migliore di 4 Hz, infatti il numero immediatamente successivo è 33554436 (che ottiene aggiungendo 1 ad una mantissa di tutti 0).

Ma se lavora con GCC per avr ha comunque i double.

Non ho forse ben capito il problema.
Ci sono vincoli di velocità nel calcolo? Occorre cioè velocità fra una impostazione e la successiva?
Ma comunque l'invio al DDS è limitato in velocità, servono almeno 18 cicli di SYSCLK, che a 180MHz sono circa 140 ns, 6 volte di più con CLK a 30MHz.

Ma cosa devo fare?

comunque il coefficiente non è 23,86, ma 23,8609294.
Occorre capire che risoluzione serva fra una frequenza e la successiva
Avatar utente
Foto UtenteGioArca67
2.218 3 4 9
Master
Master
 
Messaggi: 2033
Iscritto il: 12 mar 2021, 9:36

0
voti

[29] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto Utentegvee » 1 dic 2021, 12:46

La questione principale era se usando dati a virgola mobile (float o double, usando ovviamente le librerie avr-libc ed avr-gcc) ci fossero stati possibili problemi di risultati, p.e. valori completamente sbagliati etc..

GioArca67 ha scritto:comunque il coefficiente non è 23,86, ma 23,8609294

Sì, era per arrotondare, ho già tenuto conto di questi errori di arrotondamento. :ok:

A parte le questioni teoriche che non fanno male ovviamente, i risultati finali, che si voglia o no, si vedono con una implementazione pratica di come avr-gcc con le avr-libc emula il floating point, singola precisione o doppia. Al momento non lo so con certezza, solo posso fare affidamento su quanto detto da Foto Utentexyz in [18].

Per questo farò qualche prova con un piccolo FW apposta usando Arduino, parcheggiato nel cassetto anche lui da qualche anno. La velocità di esecuzione/configurazione non è un problema, se poi vedo che divento vecchio durante i tempi di risposta allora ci ripenserò.

Ovviamente quanta più risoluzione riesca ad ottenere meglio è. Il circuito mi servirà per il mio laboratorio personale, tanto per uso professionale dove vada bene (in caso contrario ci sono gli strumenti professionali del laboratorio in azienda), como per uso hobbystico. Per il momento mi accontento un po' del meglio che riesco ad ottenere, altrimenti lo strumento lo compro e faccio prima.
Avatar utente
Foto Utentegvee
970 2 7
Stabilizzato
Stabilizzato
 
Messaggi: 354
Iscritto il: 11 feb 2018, 20:34

0
voti

[30] Re: AVR 8 bit: unsigned integer e FPU SW emulation

Messaggioda Foto Utenteboiler » 1 dic 2021, 13:04

Per mia curiosità, c'è un motivo per cui vuoi tenere un AVR8 invece di orientarti verso un microcontroller con un'architettura un po' piú moderna?

Boiler
Avatar utente
Foto Utenteboiler
20,8k 5 7 13
G.Master EY
G.Master EY
 
Messaggi: 4080
Iscritto il: 9 nov 2011, 12:27

PrecedenteProssimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 6 ospiti