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 »

Al principio l'idea era appunto quella di usare una schedina STM32L432KC che appunto ha FPU etc.

Più che altro tracciando le piste del PCB mi sono reso conto che il pinout è un po' incomodo per il routing tenendo conto anche di altri fattori (quali ad esempio posizionare comodamente il DDS, tracciare le linee differenziali di output di lunghezze uguali, spazio per i componenti, alimentazione etc. etc.). Ne risultano vias un po' di qua e di là e non mi piace molto... Con l'AVR8 ho avuto maggior libertà e le linee sono quasi tutte dirette, ottimizzando in qualche modo anche lo spazio.. Se la emulazione FPU funziona bene ancora meglio.

Mal che vada userò l'STM32.

Dettagli secondari e di minore importanza:
  • L'idea di usare la schedina per il DDS e doverla smontare ogni qualvolta ne avessi bisogno per altre prove non mi piace molto (vabbé, è anche vero che costa 10 € comprarne un'altra).
  • Mi piacerebbe usare il più possibile componenti (possibilmente validi allo scopo) che ho nel cassetto per motivi facilmente intuibili.
  • Non mi dispiace rivivere le emozioni di quando imparavo sugli 8 bit. :mrgreen:
Avatar utente
Foto Utenteboiler
26,4k 5 9 13
G.Master EY
G.Master EY
Messaggi: 5627
Iscritto il: 9 nov 2011, 11:27

Messaggio da Foto Utenteboiler »

Capisco :ok:
Avatar utente
Foto Utenteblueice80
663 1 2 5
Stabilizzato
Stabilizzato
Messaggi: 497
Iscritto il: 19 apr 2012, 22:22

Messaggio da Foto Utenteblueice80 »

Se è un progetto amatoriale, un'altra possibilità è usare la schedina Teensy creando una shield come questa.
Avatar utente
Foto Utentegvee
1.480 5 7
Sostenitore
Sostenitore
Messaggi: 532
Iscritto il: 11 feb 2018, 19:34

Messaggio da Foto Utentegvee »

Interessante ! Non la conoscevo, grazie per la segnalazione ! :-)
Avatar utente
Foto UtenteGioArca67
4.600 4 6 9
Master EY
Master EY
Messaggi: 4606
Iscritto il: 12 mar 2021, 8:36

Messaggio da Foto UtenteGioArca67 »

Ma pensi di usare SYSCLK a 180MHz o a 30 con 6x abilitato?
E qual è l'esigenza di precisione? Cioè vuoi poter impostare 178893457,04 Hz piuttosto che 178893457,08Hz?
Avatar utente
Foto UtenteGioArca67
4.600 4 6 9
Master EY
Master EY
Messaggi: 4606
Iscritto il: 12 mar 2021, 8:36

Messaggio da Foto UtenteGioArca67 »

Ma perché non usi solo moltiplicazioni?
I coefficienti (in un verso e nell'altro) li precalcoli e poi fai una moltiplicazione invece che dividere per 23,86...


Prova

Codice: Seleziona tutto

#include <stdio.h>
#include <stdint.h>
#include <math.h>

int main()
{
	const uint64_t two32 = pow(2,32);
	const double passo = 180000000.0/(two32);
	printf("Passo=%.12lf, %lu\n",passo,two32);
	uint64_t i=0;
	double fout=0;
	while(i<(two32)){
		if((i) % (2 << 28)==0)printf("%lu, %.12lf\n",i,fout);
		fout += passo;
		i++;
		
	}
	printf("i=%lu, fout=%.12lf\n",i,fout);


	i=0;
	fout=0;
	while(i<(two32)){
		fout = i*passo;
		if((i) % (2 << 28)==0)printf("%lu, %.12lf\n",i,fout);
		i++;
	}
	printf("i=%lu, fout=%.12lf\n",i,fout);
        return (0);
}
Avatar utente
Foto Utentegvee
1.480 5 7
Sostenitore
Sostenitore
Messaggi: 532
Iscritto il: 11 feb 2018, 19:34

Messaggio da Foto Utentegvee »

GioArca67 ha scritto:Ma pensi di usare SYSCLK a 180MHz o a 30 con 6x abilitato?
30 MHz con 6x multiplier. Lo chiedi per i tempi di esecuzione, o per l'effetto del moltiplicatore con PLL sul segnale di uscita?
GioArca67 ha scritto:E qual è l'esigenza di precisione?
Con 1 Hz mi accontento. :mrgreen:
Avatar utente
Foto Utentegvee
1.480 5 7
Sostenitore
Sostenitore
Messaggi: 532
Iscritto il: 11 feb 2018, 19:34

Messaggio da Foto Utentegvee »

E comunque per un incremento fine posso sempre incrementare la FTW di uno ovviamente.
Avatar utente
Foto Utentexyz
6.864 2 4 6
G.Master EY
G.Master EY
Messaggi: 1778
Iscritto il: 5 dic 2009, 17:37
Località: Italy Turin

Messaggio da Foto Utentexyz »

GioArca67 ha scritto:

Codice: Seleziona tutto

	const uint64_t two32 = pow(2,32);
:shock: :shock: :shock: :shock: E' la peggior cosa che ho visto in questo mese :D

NON usare mai quella funzione se non sai quando si usa. Quella funzione implica un calcolo con un logaritmo e di un esponenziale, si usa con i floating point con i numeri non interi e tu hai due numeri interi.

Un esperto programmatore C lo scrive in questo modo (occhio al 'LL'):

Codice: Seleziona tutto

	const uint64_t two32 = 1LL << 32;
Perché scomodi i 64 bit ? Il GCC per gli AVR che usi deve essere compilato con il supporto "long long" altrimenti non funziona. Credo che quasi tutti lo abilitano quando compilano il tool chain per gli AVR. Quel calcolo dopo non serve visto che usi i double, fai il calcolo diretto al double.

Poi francamente fai un loop con un dato a 64 bit quando usi un (veramente uno) solo bit dei 64 bit, tanto vale farlo a 32 bit con il limite 0xFFFFFFFF (2^32 - 1) o meglio usare la macro UINT32_MAX (leggere bene la documentazione della libreria AVR-libc).

Non hai letto ABI del GCC per gli AVR, molto importante da leggere sempre quando si programma per un micro-controllore:

https://gcc.gnu.org/wiki/avr-gcc

Il double coincide col float per il GCC fino alla versione 9. Dalla 10 dipende da come viene compilato il GCC ma tutti lo compilano con ABI con il double = float, il mio GCC AVR che uso è compilato in questo modo, francamente non mi è mai servito un double a 64 bit in un micro-controllore a 8 bit in vita mia.

P.S. Allego verifica del codice assembler generato dal GCC per gli AVR che uso.

Codice C:

Codice: Seleziona tutto

const double DOUBLE = 1;
const float FLOAT = 1;
Come viene generato il codice assembler dal GCC per gli AVR:

Codice: Seleziona tutto

.global DOUBLE
DOUBLE:
        .byte   0
        .byte   0
        .byte   -128
        .byte   63
.global FLOAT
FLOAT:
        .byte   0
        .byte   0
        .byte   -128
        .byte   63
Avatar utente
Foto UtenteGioArca67
4.600 4 6 9
Master EY
Master EY
Messaggi: 4606
Iscritto il: 12 mar 2021, 8:36

Messaggio da Foto UtenteGioArca67 »

xyz ha scritto:
GioArca67 ha scritto:

Codice: Seleziona tutto

	const uint64_t two32 = pow(2,32);
:shock: :shock: :shock: :shock: E' la peggior cosa che ho visto in questo mese :D
Hai perfettamente ragione, ma lo SHL non mi compilava e per velocità ho messo il mostro.
Non ho GCC avr sotto mano per cui chiedevo di provare.
Rispondi

Torna a “Firmware e programmazione”