Il progetto del generatore digitale DDS, basato sul chip Analog Devices AD9833, realizza un sintetizzatore di segnali analogici (onda sinusoidale e triangolare) e digitali (onda quadra)
mediante la sintesi diretta digitale, ovvero genera la frequenza d'uscita a partire da un valore numerico fornito in ingresso.
Questo consente di ottenere qualsiasi frequenza compresa tra gli estremi dichiarati con una risoluzione di 1 Hz (e potenzialmente, inferiore)
con ottima stabilità e precisione.
L'utilizzo di un microproccessore potente quale il PC18F2580 consente di
ottenere agevolmente prestazioni addizionali interessanti, quali la modulazione Sweep e l'uscita impulsiva Burst;
In dettaglio, le modalità di funzionamento (nella versione fw 10.2) sono:
I parametri di comando (da tastiera o da porta seriale), visualizzati a menù sul display, sono:
Uno degli obiettivi primari del progetto è stato di ottenere la massima flessibilità operativa e versatilità d'uso.
Sia l'hardware, con numerosi punti di accesso e personalizzazione, che il software, modulare e facilmente ampliabile, consentono
la modifica delle funzioni o l'introduzione di nuove prestazioni; tra queste cito:
Il cuore del circuito è l'integrato AD9833 di Analog Devices (sample disponibili) il cui schema a blocchi è riportato qui a fianco.
Essenzialmente l'IC utilizza un Accumulatore di Fase, pilotato dal Master Clock fino a 25MHz, per estrarre i campionamenti
della forma d'onda da una ROM interna. Un DAC provvede alla conversione ad analogico dei campioni.
Tramite comando si può selezionare la forma d'onda triangolare o sinusoidale. Escludendo il DAC si ottiene un'onda quadra, eventualmente
divisibile per 2 per renderla simmetrica.
I comandi sono inviati tramite una porta SPI a 2 segnali (SDO e SCL) più un pin di abilitazione alla ricezione (FSYNC).
La massima frequenza generata è la metà del Master Clock. La qualità dell'onda in uscita triangolare si mantiene accettabile
fino a circa un quarto di MCLK.
Il chip è in formato TSSOP a 10 pin (qui montato su adattatore DIP).
L'Accumulatore è a 28bit, suddivisi in 2 word da 14bit (+ 4 bit di controllo), per un valore
massimo di 2^28 = 268,435,456.
Per stabilire la frequenza d'uscita si calcola innanzitutto il valore K dato dal rapporto MCLK/2^28.
Nel caso presente di MCKL = 8MHz, si ottiene K=0.0298 circa; questo è lo step minimo di variazione della frequenza.
Per semplificare la vita, si stabilisce un moltiplicatore M tale che moltiplicato per K dia 1Hz di variazione.
Il valore esatto sarebbe di M=33.554432 ... valore scomodo che richiederebbe l'uso di calcoli in virgola mobile.
Ulteriore semplificazione, a me va bene così, pongo M=34 così mi basta una moltiplicazione di interi a 24bit.
Ovviamente c'è un errore di frequenza di circa -1.5%.
Le soluzioni, per chi è interessato, sono 2: scriversi una routine di moltiplicazione di 'float', oppure trovare
un cristallo (oscillatore) da 16,777,216 Hz (non l'ho trovato!); con quest'ultimo il moltiplicatore M diventa = 16... bello e facile!
Questa MCU è stata scelta per il numero di pin (25) disponibili, per l'elevata velocità (clock interno fino a 32MHz con PLL),
per l'abbondanza di EPROM e RAM, che consente di spaziare in funzionalità e dotazioni.
L'architettura utiilzzata prevede la disponibilità di:
Per i miei scopi, utilizzo prevalente in bassa frequenza, la frequenza massima di funzionamento non è cruciale.
Diciamo che anche 1MHz sarebbe sufficiente.
Ho pensato quindi di utilizzare il clock di sistema del PIC (8MHz x 4 del PLL = 32MHZ) prelevandolo dal pin OSC2 con
frequenza pari a un quarto, ovvero ancora 8MHz. Ciò fornisce un segnale valido fino ad 1-2 MHz.
Come alternativa, ho previsto l'uso di un oscillatore quarzato in chip (modello FOX Electronics) a 16MHz, raddoppiando
la frequenza di utilizzo. Volendo si può arrivare fino a 25MHz.
Per attuare questa modifica, occorre spostare il ponticello 'OSC' sulla scheda e ricompilare il programma inserendo
il nuovo valore del moltiplicatore M.
Questo connettore ha una duplice funzione: è utlizzato per la programmazione del PIC come ICSP ed è l'interfaccia per
un Encoder rotativo incrementale (vedere la pagina del progetto Encoder)
Al momento (Set 2010) le routine di gestione dell'encoder non sono ancora realizzate; sarà una futura espansione.
Qui sono presenti 4 segnali, di cui 2, AUX0 e AUX1 sempre disponibili e personalizzabili (es. frequenzimetro), mentre OSC1 e OPT (questo con un ponticello per fissarlo a 0, 5V o float) dipendenti da eventuali altri scelte realizzative.
Il doppio operazionale OPA2743 a larga banda (7MHz) amplifica il segnale del 9833 (circa 0.65V) per portarlo a 2Vpp (regolabile).
Segue il controllo d'ampiezza e il classico stadio separatore con uscita a bassa impedenza.
Ho usato questo perchè non ho sottomano Opamp a maggiore banda passante... sono sicuro di averli, ma no li trovo!
La piedinatura è comunque standard per cui può essere sostituito con altri modelli.
Ho previsto un pò di 'pad' di sezionamento per poter inserire altri componenti (es. capacità di blocco DC, filtri, etc);
Per il funzionamento, tre coppie di pad sono da ponticellare come indicato sulla serigrafia e nello schema.
Il tutto è alimentato da un'unica tensione a 5Vdc, proveniente dall'esterno e protetta con un diodo Schotky contre le
inversioni di polarità. Sulla scheda, questa tensione è suddivisa in tre percorsi, con filtri LC, per alimentare
le sezioni PIC, digitale ed analogica.
I 5V sono portati anche ai connettori Encoder, Seriale, Keyboard; 2 test point TPV e TPG permettono di collegare
eventuali altri dispositivi.
E' affascinante guardare il proprio (lungo) lavoro praticamente terminato e ricordare, anche visivamente,
quanti passaggi, quanti ostacoli, quanti ripensamenti, quanti 'colpi di genio', quanti errori e, soprattutto,
quante ore compongono questo prodotto.
In fondo, il bello dell'elettronica amatoriale è proprio questo; "Per aspera ad astra", buttarsi in una
sfida e arrivare alla soddisfazione personale, non per gli altri ne per i soldi, solo per se stessi.
Ho voluto raccogliere qui di fianco alcune immagini significative, per mia memoria futura, su come un'idea può diventare
realtà, anche nelle piccole cose.
Il circuito stampato è in vetronite a doppia faccia, fatto realizzare esternamente perchè non ho gli strumenti per
produrli in casa e anche perchè volevo un'aspetto finale rifinito e professionale.
NOTA: ho alcuni PCB pronti (vedere la pagina Mercatino PCB); chi fosse interessato mi invii un'email.
La basetta è divisa in orizzontale in 2 sezioni: nella parte di sopra ci sono le sezioni digitali, mentre sotto quelle analogiche.
Ciascuna sezione ha un proprio piano di massa (DGND e AGND) uniti in un solo punto tramite R7 da 0 Ohm (in realtà è un ponticello metallico)
E' anche prevista la possibilità di montare un pannellino metallico di isolamento elettromagnetico tra le 2 sezioni.
Il display LCD 4x20 può essere montato direttamente sullo stampato mediante il suo connettore LCD e 2 fori per viti di fissaggio;
in alternativa, classico cavo a 16 poli per remotizzarlo.
JUMPER | Posizione | Funzione |
CSEL | 1-2 | selettore sorgente di clock per il DDS. In posizione 1-2, clock dalla MCU a 8 MHz, in posizione 2-3, clock dal chip oscillatore IC4 |
RW | 1-2 | Seleziona tra il funzionamento con lettura del pin RW (Busy) dall CPU (posizione 1-2) oppure con pin RW a massa e uso di un delay di attesa (posizione (2-3) |
SEL | xxx | Seleziona la polarità inviata al pin Option (RC1) per funzioni ausiliarie |
Il programma è scritto quasi interamente in Basic, nella versione commerciale Pic18 Simulator IDE di OshonSoft,
con alcuni inserti in Assembler nelle parti più critiche in termini di velocità. In particolare, la routine di
comunicazione SPI col chip AD9833 è realizzata in software.
Per comodità di 'editing', il programma è suddiviso in un modulo Main, 4 moduli dedicati ad una funzione specifica (Keyboard, Display, Serial, SPI)
più un modulo Functions che raccoglie diverse routine di gestione e comando.
Lo schema a blocchi qui di fianco illustra la correlazione tra moduli e funzioni svolte.
Il cuore del programma è rappresentato dall'Interrupt Service Routine (ISR) a bassa priorità che risponde agli interrupt del Timer0 predisposto a 1 msec.
In questa area, in funzione del modo di funzionamento selezionato (Mode) viene calcolata, con le appropriate modulazioni, la frequenza da generare
e settato un flag che indica al loop principale di chiamare la routine di invio tramite SPI del comando al DDS.
La ISR ad alta priorità gestisce invece le richieste provenienti dalla tastiera e dalla porta seriale.
La porta seriale è stata realizzata tramite un modulo USB-RS232 di Pololu per collegare il DDS al PC su porta USB.
La tastiera utilizzata è un compromesso; dopo alcuni tentativi perfettamente riusciti con un modulo 'touch control' e superficie in vetro, acquistata
a un buon prezzo in Cina, questa idea è stata abbandonata in quanto meccanicamente richiedeva lavorazioni troppo difficili per me.
Ho quindi ordinato delle semplicissime tastierine a 16 tasti in policarbonato, non molto sensibili e che richiedono un certo
sforzo d'azionamento, però sono facilmente montabili incollandole sulla superficie del contenitore.
Questa tastiera è 'stupida' per cui ho dovuto realizzare un circuitino a parte con un PIC16F88 per gestire la
scansione e generare il codice a 4 bit + interrupt al modulo principale.
Dopo qualche prova, ho stabilito di inviare al 'grande' PIC i codici brutali del tasto premuto e lasciare che fosse
lui, mediante una tabella di conversione, a generare il corretto codice da utilizzare; questo consente di rimappare
facilmente i tasti alle funzioni volute.
» Scarica sorgenti ed eseguibile del DDS e del modulo Keyboard
» Schemi e PCB del DDS e del modulo Keyboard
Alcuni esemplari della versione 1 del DDS sono disponibili al Mercatino del PCB
Click su qualsiasi immagine per ingrandire
Schema elettrico
Disposizione componenti
Circuito stampato
Layout in 3D
Sweep in frequenza di onda triangolare
Burst di onda sinusoidaleS
Primo test del chip sulla breadboard
Scrittura del firmware su piattaforma di sviluppo
Inserimento degli elementi nel contenitore
Collaudo dell'interfaccia (tastiera e display)
Collaudo dei segnali e della programmazione
Il progetto (quasi) finito