AVR 8 bit: unsigned integer e FPU SW emulation

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

Avatar utente
Foto Utentegvee
1.480 5 7
Sostenitore
Sostenitore
Messaggi: 532
Iscritto il: 11 feb 2018, 19:34

Messaggio da Foto Utentegvee »

Ciao a tutti,

Avrei bisogno di implementare una operazione con floating point in un ATmega328P, concretamente una moltiplicazione tra uint32_t e float:

\Delta_\phi = f_\text{out} \times 23.86

e prima di usare definitivamente il microcontrollore in questione, vorrei rassicurarmi in qualche modo che tale operazione non sia troppo "complicata" e dia risultati troppo sbagliati. La velocità di esecuzione non è un fattore critico.

Purtroppo non posso effettuare un debug in runtime perché uso un ISP MK2 quindi al momento non so bene come evaluarlo se non rappresentando byte a byte sui GPIO e verificare con l'oscilloscopio pin a pin con una schedina di test (un analizzatore logico sarebbe molto comodo a questo scopo). È un procedimento un po' macchinoso e scomodo, ma se necessario...

Da quanto leggo qui, qualche problema si può avere, ma nel mio caso essendo solo una operazione non mi aspetto grandi problemi, ma non si sà mai...

Non ho mai usato micro a 8 bit con emulazione FPU SW, negli ultimi anni ho sempre usato micro a 32 bit con FPU HW...

Qualcuno ha usato la emulazione FPU per operazioni simili con questo micro ?
In tal caso, ci sono stati problemi ?

L'uso di una variabile a 32 bit non mi preoccupa molto, immagino che il compilatore la gestisca bene..

Ringrazio in anticipo.

O_/
Avatar utente
Foto UtenteGuidoB
17,8k 7 12 13
G.Master EY
G.Master EY
Messaggi: 2812
Iscritto il: 3 mar 2011, 15:48
Località: Madrid
Contatta:

Messaggio da Foto UtenteGuidoB »

Ciao Foto Utentegvee, non capisco bene il tuo problema.
È vero che molti numeri che hanno una parte decimale finita, in binario ce l'hanno illimitata periodica e quindi c'è un errore di arrotondamento. Se si fanno più operazioni di seguito, questo piccolo errore può accumularsi.

Non capisco se è il tuo caso.

In alternativa, non potresti farlo in "virgola fissa"?
Nel tuo caso, moltiplicare per il numero intero 2386 e ricordarti che il risultato è in centesimi.
Big fan of ƎlectroYou!       Ausili per disabili e anziani su ƎlectroYou
Caratteri utili: À È É Ì Ò Ó Ù α β γ δ ε η θ λ μ π ρ σ τ φ ω Ω º ª ² ³ √ ∛ ∜ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ∃ ∄ ∆ ∈ ∉ ± ∓ ∾ ≃ ≈ ≠ ≤ ≥
Avatar utente
Foto Utentegvee
1.480 5 7
Sostenitore
Sostenitore
Messaggi: 532
Iscritto il: 11 feb 2018, 19:34

Messaggio da Foto Utentegvee »

Ciao Foto UtenteGuidoB,

Grazie per il tuo interesse.

La conversione lo devo fare perché devo programmare una tuning word di un DDS.

La prova più veloce che posso fare è quello di scrivere un piccolo firmware e restituire il valore calcolato sulla seriale byte a byte, e leggerli opportunamente con un piccolo programmino seriale in C, python o Octave...

Dato che ho aperto il post, posterò qui i risultati, il tutto appena avrò un po' di tempo libero.

O_/
Avatar utente
Foto Utenteboiler
26,4k 5 9 13
G.Master EY
G.Master EY
Messaggi: 5629
Iscritto il: 9 nov 2011, 11:27

Messaggio da Foto Utenteboiler »

Il risultato è un integer?
Se sì, \frac{f_{out} \cdot 1527}{64} dovrebbe fornirti un'approssimazione non malaccio ;-)
Se sia accettabile, dipende dall'applicazione.

Boiler
Avatar utente
Foto Utenteboiler
26,4k 5 9 13
G.Master EY
G.Master EY
Messaggi: 5629
Iscritto il: 9 nov 2011, 11:27

Messaggio da Foto Utenteboiler »

Oppure ovviamente, puoi moltipicare per 2386 e poi dividere per 100.
Non ho dimestichezza con l'architettura AVR8, ma probabilmente non fa differenza dividere per 100 o per una potenza di 2.

Ciao, Boiler
Avatar utente
Foto UtenteMarcoD
12,2k 5 9 13
Master EY
Master EY
Messaggi: 6697
Iscritto il: 9 lug 2015, 16:58
Località: Torino

Messaggio da Foto UtenteMarcoD »

Per delle considerazioni mirate, occorrerebbe conoscere la
- la massima risoluzione del DDS (minimo intervallo di frequenza)
- la massima frequenza che si vuole impostare
Avatar utente
Foto Utentefairyvilje
15,0k 4 9 12
G.Master EY
G.Master EY
Messaggi: 3047
Iscritto il: 24 gen 2012, 18:23
Contatta:

Messaggio da Foto Utentefairyvilje »

boiler ha scritto:Non ho dimestichezza con l'architettura AVR8, ma probabilmente non fa differenza dividere per 100 o per una potenza di 2.
Credo di si. La potenza di 2 si riduce ad uno shift register, mentre la divisione arbitraria va implementata via software dal momento che l'ATmega328P non ha FPU, supporto per le divisioni, e nemmeno un supporto nativo per la codifica BCD. Almeno a quanto ricordo.
"640K ought to be enough for anybody" Bill Gates (?) 1981
Qualcosa non ha funzionato...

Lo sapete che l'arroganza in informatica si misura in nanodijkstra? :D
Avatar utente
Foto UtenteIlGuru
5.482 2 10 13
G.Master EY
G.Master EY
Messaggi: 1924
Iscritto il: 31 lug 2015, 23:32
Contatta:

Messaggio da Foto UtenteIlGuru »

In alternativa invece che moltiplicare per 23,86 * 100 = 2386 e poi dividere per 100, potresti moltiplicare per 23,86 * 128 = circa 3054 (3054,08) e poi shiftare a destra 7 bit
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Avatar utente
Foto Utentedadduni
2.073 2 7 12
Expert EY
Expert EY
Messaggi: 1370
Iscritto il: 23 mag 2014, 16:26

Messaggio da Foto Utentedadduni »

Mi sembra che il risultato migliore si ottenga moltiplicando per 1527 e poi dividendo il risultato per 2^6.

Questo porta un errore di approssimazione di soli 0.04 e non di 0.08 come nel caso di 2^7.

Davide
Avatar utente
Foto UtenteIlGuru
5.482 2 10 13
G.Master EY
G.Master EY
Messaggi: 1924
Iscritto il: 31 lug 2015, 23:32
Contatta:

Messaggio da Foto UtenteIlGuru »

Giusto e si risparmia anche uno shift
\Gamma\nu\tilde{\omega}\theta\i\ \sigma\epsilon\alpha\upsilon\tau\acute{o}\nu
Rispondi

Torna a “Firmware e programmazione”