Newsgroup: it.hobby.elettronica.digitale
Titolo: cerco algoritmo divisione multibyte 64/32 bit

..senza segno...che possa operare su uC a 8 bit,magari in C con
compilatore(Keil limited) in grado di trattare al massimo long da 32 bit
grazie per link o aiuti
ciao e Buon Natale
Diego

On Dec 23, 10:42 am, "blisca" <bliscachiocciolinatiscalipuntoit>
wrote:

Tipo questo trovato sul forum  CCS  a firma di Jean-Louis VERN
jlv...@wanadoo.fr
  ?
// Ndds = ((Fout x 2^32)/Fref
#include <16F873.h>
#define LSB 0
#define MSB 1
int32 acca;
int32 accb[2];
// Divise accb (64bits) / acca (32bits), résultat dans accb[LSB]
(32bits)
void divab( void )
{
unsigned char count;
count = 32;
do
  {
  // multiplie le numérateur par deux et laisse la place pour le
résultat
  if( shift_left(accb, 2 * sizeof(int32), 0) || ( accb[MSB] >= acca ))
    {
    // supérieur ou égal, soustrait
    accb[MSB] -= acca;
    // pousse 1 dans le résultat
    accb[LSB] |= 1L;
    }
  } while( --count );
}
main()
{
// accb = fout x 2^32
accb[MSB] = 50000000L;
accb[LSB] = 0L;
// acca = Fref
acca = 180000000L;
// Divide 64/32, result 32 !! (Fout < Fref)
divab();
// printf("ndds=\%lu", accb[LSB]);
// (result == 1 192 046 471)
for(;;);
}
--------------------------------------------------------
This message was ported from CCS's old forum
Original Post ID: 4850
Devi gestire un DDS ? A me e' servito per questo.
Giorgio

 Diego
Tipo questo trovato sul forum  CCS  a firma di Jean-Louis VERN
jlv...@wanadoo.fr
  ?
// Ndds = ((Fout x 2^32)/Fref
#include <16F873.h>
#define LSB 0
#define MSB 1
int32 acca;
int32 accb[2];
// Divise accb (64bits) / acca (32bits), r�sultat dans accb[LSB]
(32bits)
void divab( void )
{
unsigned char count;
count = 32;
do
  {
  // multiplie le num�rateur par deux et laisse la place pour le
r�sultat
  if( shift_left(accb, 2 * sizeof(int32), 0) || ( accb[MSB] >= acca ))
    {
    // sup�rieur ou �gal, soustrait
    accb[MSB] -= acca;
    // pousse 1 dans le r�sultat
    accb[LSB] |= 1L;
    }
  } while( --count );
}
main()
{
// accb = fout x 2^32
accb[MSB] = 50000000L;
accb[LSB] = 0L;
// acca = Fref
acca = 180000000L;
// Divide 64/32, result 32 !! (Fout < Fref)
divab();
// printf("ndds=\%lu", accb[LSB]);
// (result == 1 192 046 471)
for(;;);
}
--------------------------------------------------------
This message was ported from CCS's old forum
Original Post ID: 4850
Devi gestire un DDS ? A me e' servito per questo.
Giorgio
grazie,ci hai azzeccato!!probabilmente ci sono altri modi di aggirare
l'ostacolo,tra cui forse l'uso di variabili float,ma volevo evitare di
perdere bits cos�,per amor di precisione
Buon Natale

 perdere bits cos�,per amor di precisione
Scusate la curiosità, ma a che cosa servono le moltiplicazioni
e divisioni per gestire un DDS?
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 l'ostacolo,tra cui forse l'uso di variabili float,ma volevo evitare di
Ti sei deciso ad accendere il giocattolino? Bravo!


per generare almeno i primi 32 bit di una parola di configurazione
frequenza-fase,questa si calcola
cos� se non vado errato:
tuning_word=F_out*2^32/Clk
volendo guardare Fout e Clk non impegneranno 32 bit,2^32 necessiterebbe di
33bit,ma naturalmente si raddoppia Fout e si moltiplica per 2^31

 ha scritto nel messaggio
news:535c3d15-0118-42e4...@m25g2000yqc.googlegroups.com...

ciao,no...il dds che mi hai dato tu � troppo bellino
� per un signore amico radioamatore  che ha un apparecchio d'epoca al quale
deve sostituire il quarzo per cambiare gamma,e bastava un ad9850 per i 20Mhz
che gli servono

 e divisioni per gestire un DDS?
Servono per calcolarti con che N caricare l'accumulatore di fase se
non sai con esattezza che Fclock userai o se gia' metti in preventivo
che Fclock e' variabile.
Io infatti uso sempre un oscillatore di riferimento fisso e me la cavo
comodamente con dei picchetti da 2 euri facendogli fare solo addizioni
(mi calcolo prima tutto a manina su carta).
Per es : calcolo lo step minimo con Fclock di 1 MHz e accumulatore da
32 bit  ---> 1.000.000 / (2^32) ----->  0,0002328 Hz
Per 1 Hz ---->  1 / 0,0002328 ---->    N = 4295, 53
Per 10Hz ---> N = 4295,53
Per 1KHz --> N= 429553
e cosi' via.....
A questo punto per generare 100KHz basta moltiplicare (fare tot
somme....) 4296 * 100.000 (accettando un piccolo errore)
L'errore della frequenza in uscita lo puoi minimizzare drasticamente
usando registri piu' larghi quando moltiplichi.
Questo e' il sistema che uso per esempio con i PIC16Fxxxx.


Ho fatto dei grossolani errori di calcolo per la fretta, ma il
procedimento e' quello...

 > Scusate la curiosit�, ma a che cosa servono le moltiplicazioni


Grazie Massimo
Giusto,in effetti avevo previsto la fclock programmabile,ma alla fine andr�
con una freq fissa..quindi l'approccio che suggerisci mi semplificherebbe le
cose .solo che mi sono impuntato con sti 64bit e per impratichirmi con
l'assembly dell'8051(AduC842...recuperato da schede rottame ,per principio)
sto vedendo di implementare un algoritmo 64/32 a tutti i costi,e ora se
riesco provo a inventarne uno che andr� di + moda dei pantaloni col cavallo
basso edelle palline clic clac negli anni '70
http://www.youtube.com/watch?v=FHV5SVTXpX0


Ok ho capito. Io, le volte che ho usato i DDS, ho
usato frequenze di riferimento "comode" per cui
il calcolo si è ridotto a semplici shift e alla
conversione dec->bin.


 che gli servono
Un'osservazione: i DDS sono stupendi e comodissimi, ma
il lato negativo è che hanno una mare di spurie
e rumore di fase. Se devi sostituire l'oscillatore
di un trasmettitore, forse questo non è tanto grave,
ma se fosse l'oscillatore di un buon ricevitore, allora
le differenze rispetto a un oscillatore a quarzo
sarebbero molto evidenti.



ah ecco,non l'avevo mai testato per questo uso
il progettino lo finisco comunque,e penso a altre soluzioni tipo vcxo
anyrate allora,

 grazie per link o aiuti
Una volta avevo iniziato a fare questo:
http://www.develer.com/~batt/div64.c
Contiene la funzione di divisione piï¿œ altre cose che magari possono 
esserti utili (shift, somme, confronti, etc...).
Gli ho solo dato una "testata" veloce (vedi il codice a fondo file) e 
non sono sicuro al 100% che funzioni... ma in ogni caso ï¿œ un punto di 
partenza.
L'algoritmo di divisione si basa su quello fatto da un mio collega:
http://lxr.free-electrons.com/source/lib/div64.c
E' incluso nel kernel di Linux, quindi almeno l'algoritmo direi che ï¿œ 
abbastanza collaudato.
-- 
  _|/ Francesco Sacchi - Develer S.r.l., R&D dept.
   |\ 
http://www.develer.com/
 - 
http://www.bertos.org