Sul web ed anche su questo stesso sito, sono apparsi vari articoli
inerenti le potenzialità dei microcontrollori della Microchip ed in
particolare delle loro periferiche.
In questa occasione desidero proporvi un circuito che ho ottenuto dopo
vari affinamenti, che mi è servito unicamente ad approfondire le mie
conoscenze sulle caratteristiche dei moduli ADC e PWM di questi
eccezionali microcontrollori, dai quali con delle semplici istruzioni,
mi è stato possibile ottenere delle buone prestazioni.
Il circuito accetta in ingresso un segnale analogico di ampiezza non
superiore a 1Vpp, i cui valori campionati sono inviati direttamente al
blocco modulatore PWM. Quest’ultimo, produrrà in uscita una bella onda
quadra con Duty-Cycle variabile, il cui valor medio opportunamente
filtrato, restituirà all’uscita il segnale analogico originariamente
iniettato all’ingresso.
A tale scopo è d’obbligo la presenza del filtro passa basso collegato al
pin 9 del PIC, che oltre ad estrarre il segnale analogico dal PWM,
attenua notevolmente tutte le frequenze oltre i 5 KHz circa, ed elimina
quasi totalmente la frequenza di lavoro residua del PWM.
Il
campionamento è eseguito con una frequenza di 20 KHz circa, quindi ne
viene fatto uno ogni 50 uS circa. Se cambiate il quarzo con uno da 10
MHz, si passa ad una frequenza di campionamento di 10 KHz, cioè uno ogni
100 uS circa, con una qualità di riproduzione peggiore rispetto alla
precedente. Ogni campionamento è eseguito in un tempo di 5 uS circa, ed
è restituito con un dato a 10 bit, cioè con 1024 livelli di
quantizzazione ottenibili.
Anche la generazione del periodo del segnale PWM è a 10 bit, quindi il
segnale digitalizzato prima, può essere inviato direttamente al
modulatore PWM senza alcun condizionamento preventivo.
Quello visibile nella figura che segue, rappresenta lo schema a blocchi
del generatore PWM, così come consultabile sul sito della Microchip.
Il registro denominato PR2 contiene 8 bit, nel quale possiamo scrivere
un valore massimo pari a 255 che determina il periodo dell’onda quadra,
calcolabile come suggerito dalla Microchip con la seguente formula:
Dove si riconoscono benissimo il registro PR2, Tosc periodo del clock
del quarzo pari a 1/f, dove f è il valore di frequenza del quarzo usato,
ed infine il valore del prescaler.
Oppure, con la seguente formula derivata dalla precedente:
dove inserendo il valore di Fosc in MHz, si ottiene il valore del
periodo direttamente in uS.
Il registro denominato CCPR1L contenente gli 8 bit più significativi, è
associato ai 2 bit meno significativi residenti nelle posizioni 4 e 5
del registro CCP1CON, per un totale di 10 bit, nel quale possiamo
scrivere un valore massimo pari a 1024, che determina il valore di Ton
della nostra onda quadra, calcolabile come suggerito dalla Microchip con
la seguente formula.
Dove riconosciamo il registro CCPR1L contenente gli 8 bit più
significativi, CCP1CON che contiene gli altri 2 nelle posizioni 4 e 5,
Tosc come abbiamo visto prima periodo del clock del quarzo, ed il valore
del prescaler.
Oppure, con la seguente formula derivata dalla precedente:
dove inserendo il valore di Fosc in MHz, si ottiene il valore di Ton
direttamente in uS.
Il registro infine che governa tutto il sistema è il TMR2. Esso è
incrementato dal clock interno, e quando il suo conteggio eguaglia il
valore impostato sul registro PR2, il comparatore evidenziato in verde
pone ad 1 la sua uscita. Tale condizione va a resettare TMR2 il cui
conteggio riparte da zero, trasferisce il contenuto a 10 bit del
Duty-Cycle register nel registro CCPR1H sempre a 10 bit, va a settare il
Flip-Flop che porta l’uscita PWM a livello alto.
Nel procedere col suo conteggio, TMR2 eguaglierà adesso il valore
contenuto nel registro CCPR1H a 10 bit, e quando ciò accade, il
comparatore evidenziato in giallo pone ad 1 la sua uscita, che va a
resettare il Flip-Flop che porta l’uscita PWM a livello basso.
Continuando ancora il conteggio, TMR2 eguaglia nuovamente il valore
impostato sul registro PR2, e tutto si ripetere come prima
indefinitamente finché ci sarà alimentazione. Va ricordato che gli 8 bit
del registro TMR2 sono associati ad altri 2 bit concatenati al clock
interno a cui non abbiamo accesso, per un totale di 10 bit, pari ad un
valore massimo di 1024.
Quello che segue è lo schema a blocchi dell’ ADC.
L’ingresso possiamo sceglierlo tra 7 possibili evidenziati in verde, e
lo possiamo selezionare attraverso i 3 bit CHS2-CHS1-CHS0 residenti nel
registro ADCON0 e naturalmente selezionandolo anche nel registro ANSEL.
Le tensioni di riferimento inferiore e superiore per la conversione
dell’ ADC, le possiamo scegliere tra 4 possibili combinazioni diverse,
selezionabili tramite i 2 bit VCFG1- VCFG0 residenti nel registro
ADCON1.
a) bit = 00 : Vref+ = valore positivo d’alimentazione.
Vref- = valore d’alimentazione massa.
b) bit = 01 : Vref+ = valore positivo d’alimentazione.
Vref- = valore in ingresso su RA2.
c) bit = 10 : Vref+ = valore in ingresso su RA3.
Vref- = valore d’alimentazione massa.
d) bit = 10 : Vref+ = valore in ingresso su RA3.
Vref- = valore in ingresso su RA2.
Dopo ogni conversione il dato a 10 bit è salvato su due registri
chiamati ADRESH e ADRESL, e come si vede nella figura che segue, può
essere giustificato a destra oppure a sinistra. Nel primo caso, parte
sinistra della figura, gli otto bit meno significativi sono disponibili
nel registro ADRESL, mentre i due più significativi nel registro ADRESH
bit 0 e 1. Nel secondo caso, parte destra della figura, gli otto bit più
significativi sono disponibili nel registro ADRESH, mentre i due meno
significativi nel registro ADRESL bit 7 e 6. Questo può tornare utile
quando ad esempio servono solo otto bit della conversione, scegliendo
rapidamente tra i più significativi o i meno significativi. Tale opzione
è attivabile tramite il bit chiamato ADFM del registro ADCON1.
Per semplificare la stesura del firmware in asm, la frequenza di
campionamento dell’ADC ho preferito renderla uguale alla frequenza del
PWM. A tale scopo, viene fatto generare un interrupt ogni qual volta si
resetta TMR2, ed al verificarsi di tale evento viene fatta eseguire
anche una conversione ADC.
Occorre però verificare che il tempo di conversione sia compreso entro i
limiti suggeriti dalla Microchip, cioè tra 1,6 e 6,4 uS. Ma questo
evidentemente dipende principalmente dalla frequenza del quarzo usato, e
qualora i tempi dovessero essere fuori i limiti suggeriti prima, allora
occorre impostare i bit ADCS0 e ADCS1 di ADCON0, assieme al bit ADCS2 di
ADCON1. Scegliendo dei valori opportuni per tali bit, è possibile
dividere il clock da inviare all’ADC per 2; 4; 8 e così via, in modo da
rispettare le direttive di prima ed ottenere delle conversioni prive di
errori.
Il file ASM scaricabile QUI, è corredato da molte indicazioni che vi
aiuteranno a comprenderne più facilmente il funzionamento ed
eventualmente ad apportare delle modifiche.
Il circuito elettrico riportato all’inizio è ridotto all’essenziale.
Tutte le operazioni sono svolte dal pic 16F88 che programmerete col
file HEX scaricabile QUI. Poiché non vi sono punti di taratura, data
alimentazione il circuito dovrà funzionare immediatamente.
Come sorgente di segnale ho usato il mio ricevitore FM, dalla cui presa
per la cuffia ho prelevato il segnale di BF da inviare all’ingresso del
mio circuito; dalla cui uscita invece, ho prelevato il segnale di BF
demodulato e filtrato che ho inviato alle casse amplificate del mio PC.
In assenza di segnale in ingresso, occorre solo regolare il
potenziometro P1 fino ad ottenere all’uscita sul pin 9 un onda quadra
con il 50% di Duty-Cycle. Se non si dispone di un oscilloscopio, tale
operazione può essere portata a termine ad orecchio. Basta iniettare
all’ingresso un segnale non superiore a 1Vpp, e ruotare il potenziometro
P1 da un’estremità all’altra per tutta la sua escursione. Troverete due
posizioni che segnerete con un pennarello, oltre le quali il segnale
ascoltato in uscita risulta essere fortemente distorto. Basta a questo
punto posizionare il potenziometro al centro tra i due limiti segnati
prima ed è fatta.
Per il resto provate a variare sia il valore del periodo che del
Duty-Cycle dell’onda quadra, per costatarne immediatamente le
ripercussioni sulla qualità del segnale riprodotto. Naturalmente la
qualità non sarà elevata, ma credo che questa sia una buona base di
partenza per progetti più sofisticati ed evoluti.
Credo che con poche mirate modifiche, il circuito si possa adattare a
varie altre applicazioni. Ad esempio se lo corrediamo di una memoria RAM
esterna sufficientemente capiente, è possibile realizzare un
registratore / riproduttore vocale, un eco digitale, un generatore di
forme d’onda, oppure uno scrambler, etc.
Bene, con questo vi saluto e spero che questa esperienza possa assere
utile anche a voi.
Naturalmente, visto il periodo buon ferragosto a tutti.