http://tomasella.altervista.org/it/elettronica/microcontrollori/frequenzimetro.html

Frequenzimetro digitale

immagine del frequenzimetro mentre compie una misura

Questo progetto descrive come realizzare un frequenzimetro digitale quarzato, capace di misurare frequenze che vanno da 1Hz a 50MHz, utilizzando componenti comuni e relativamente poco costosi. Il circuito in sè è molto semplice ed il numero di componenti necessari è ridotto al minimo. Il grosso del lavoro viene svolto, ancora una volta, da un microcontrollore classicissimo, ovvero dal nostro amato PIC16F84.

Ad essere sinceri, come illustrerò in seguito, esiste una seconda versione del circuito (quella che effettivamente uso io da anni), la quale integra anche un Real Time Clock (RTC), per fare in modo che, nel tempo in cui il frequenzimetro rimane inutilizzato, lo strumento possa fungere da semplice orologio/datario. Questa versione necessita però, oltre di alcuni componenti aggiuntivi, di un programma molto più esteso. Per questo motivo, al posto del PIC16F84, è necessario usare il "fratello maggiore" PIC16F628 (che fra l'altro ha una piedinatura compatibile).

L'immagine in cima alla pagina mostra il display 2x20 mentre esegue una misura. Nella prima riga si può leggere la frequenza misurata (nell'immagine il frequenzimetro sta misurando la frequenza del clock del PIC), mentre nella seconda compaiono ora e data. Nelle foto seguenti si può vedere il circuito alloggiato all'interno della scatola (ho usato una di quelle per conservare i cibi) e il display durante il funzionamento da orologio/datario. Le foto del circuito stampato non mostrano esattamente il circuito che verrà descritto in seguito in quanto si riferiscono alla mia realizzazione del 2006, alla quale ho successivamente apportato delle modifiche soprattutto per quanto riguarda lo stadio di ingresso.

immagine dell'interno del frequenzimetro con LCD collegato  immagine dell'esterno del frequenzimetro con LCD scollegato
immagine del frequenzimetro mentre compie una misura

Schema elettrico

Lo schema elettrico completo del frequenzimetro è mostrato nella seguente figura, mentre il disegno completo del PCB e lo sbroglio del circuito è scaricabile in formato FidoCad (qui trovate la libreria componenti necessaria) oppure pdf.

schema elettrico completo del frequenzimetro digitale

Esso comprende naturalmente lo stadio di alimentazione, lo stadio di pre-condizionamento del segnale, il microcontrollore che ha il compito di eseguire la misura, il display LCD testuale (compatibile con il chip Philips HD44780), un circuito a pompa di carica per generare la tensione di contrasto per il display ed infine un Real Time Clock (RTC). Analizziamo ora i singoli stadi.

Stadio di alimentazione

È formato semplicemente da un ponte a diodi di Graetz per raddrizzare il segnale sinusoidale, da uno stabilizzatore di tensione lineare 7805 e da 4 condensatori di filtro. Può accettare in ingresso una tensione sinusoidale di ampiezza compresa fra 7 e 10V (fornita ad esempio da un trasformatore), oppure una tensione continua di ampiezzza compresa fra 9 e 14V (fornita ad esempio da un alimentatore o da una batteria). L'alimentazione può essere collegata tramite un morsetto a due poli oppure con un jack. La polarità con cui viene collegata la tensione di ingresso è ininfluente poiché il raddrizzatore si occupa di fornire allo stabilizzatore sempre una tensione di segno positivo. I diodi D8÷13 possono essere indifferentemente siglati 1N4002, 1N4003, 1N4004, 1N4005, 1N4006 o 1N4007.

Stadio di ingresso

Il circuito di ingresso presenta un accoppiamento in corrente alternata ed è ad alta impedenza. Infatti il FET BF245A funge da buffer di tensione, che poi verrà amplificata dal transistor 2N2222A. Ho cercato di impiegare transistor comuni in modo tale che fosse semplice per tutti reperirli. Per quanto riguarda il transistor 2N2222A ritengo che possa funzionare ugualmente bene un 2N2222, mentre per il FET credo possano andare bene anche le varianti BF245B e BF245C, o, in alternativa, il J310.

Microcontrollore

Come già accennato in precedenza, il frequenzimetro può funzionare sia con un PIC16F84 che con un PIC16F628. Avendo questi la stessa piedinatura, possono essere montati indifferentemente nel circuito. In entrambi i casi il microcontrollore necessita di un quarzo esterno e, per questo, sono state previste due possibilità. La prima, che è quella preferibile, è quella di utilizzare un oscillatore quarzato (vedi XTAL1) il quale è internamente stabilizzato e fornisce in uscita il segnale di clock desiderato. La seconda opzione è quella di montare un quarzo tradizionale con relativi condensatori (vedi XTAL2 e i condensatori all'interno della zona evidenziata). Nel primo caso non vanno montati i componenti evidenziati (XTAL2, C12 e C13), mentre nel secondo non va montato XTAL1 e C14. Il quarzo da montare deve avere una frequenza di 4MHz, poiché le misure di frequenza si basano proprio su questo. Non sono quindi accettabili valori nominali differenti, anche se simili. La rete formata da R12, C11 e D7 serve a resettare il microcontrollore all'accensione, mentre i pulsanti S1, S2 ed S3, assieme alle resistenze R13, R14 ed R15, servono a selezionare il range di misura e ad impostare l'ora e la data dell'orologio. Per facilitare la programmazione è stato previsto il connettore JP2 per la programmazione In Circuit. Per programmare il PIC si dovrà collegare il cavo per la programmazione ai pin pari del connettore, mentre per il funzionamento normale si dovranno cortocircuitare i jumper JP2-2, JP2-4 e JP2-5.

Display LCD testuale

Il frequenzimetro impiega un display LCD testuale per visualizzare il valore di frequenza rilevato. Possono essere collegati display che montano il chip Philips HD44780 o compatibili. Prima di collegare un display verificatene la piedinatura. La comunicazione tra il microcontrollore ed il display è a 4 bit di dati, con l'aggiunta di 2 bit di controllo.

Pompa di carica

I display LCD necessitano di una tensione particolare per la regolazione del contrasto. Questa tensione varia da display a display e per alcuni di essi deve essere negativa. Per questo motivo è stato previsto un circuito a pompa di carica che permette di ottenere una tensione negativa di circa -4V. Il principio sul quale si basa il suo funzionamento è semplice: prendendo un condensatore carico ad una tensione positiva e connettendo a masssa il suo polo positivo, al polo negativo si misura una tensione negativa di valore pari a quello a qui il condensatore era stato caricato in precedenza. Naturalmente se ora al condensatore venisse collegato un carico, questo si scaricherebbe, perciò è necessario ricaricare ripetutamente il condensatore. Per far questo ho impiegato un circuito integrato che contiene 6 invertitori logici a trigger di Schmitt. La porta logica siglata IC2D, assieme ad R1 e C2, realizza un oscillatore alla frequenza aprossimativa di 10kHz, che viene trasferita in ingresso alle porte IC2A ed IC2E che lavorano in parallelo per poter fornire una maggiore corrente. L'uscita di queste porte viene trasferita in ingresso alle porte IC2B ed IC2F, anch'esse in parallelo. Nella fase in cui l'uscita di IC2A è alta (+5V) l'uscita di IC2B è bassa (0V), il condensatore C4 risulta avere il polo positivo a +5V e quello negativo a 0V tramite D1, quindi si carica a 5V meno la caduta di tensione sul diodo D1. Nell'altra fase l'uscita di IC2A è bassa e quella di IC2B alta, il polo positivo di C4 ora si trova connnesso a 0V, dunque a quello negativo si può misurare una tensione negativa pari, in valore assoluto, a 5V-VD1. Questa viene trasferita al condensatore C5 tramite il diodo D2. In questo modo ai capi di C5 si trova una tensione abbastanza stabile pari a 5V-VD1-VD2. Per minimizzare le cadute di tensione sui diodi si sono scelti diodi Schottky siglati BAT42, ottenendo così una tensione di circa -4V. Se non riusciste a procurarvi tali diodi potrete sostituirli con dei comuni 1N4148 o 1N4150, riuscendo ad ottenere una tensione di circa -3.6V, che dovrebbe risultare comunque più che sufficiente per questa applicazione.

Il pin dell'LCD per la regolazione del contrasto viene collegato ad un trimmer, in modo da poter selezionare una tensione compresa fra -4V e +5V (i pin 1 e 2 del jumper JP1 devono essere cortocircuitati). Nel caso in cui foste certi che il display che utilizzerete non necessiti di una tensione di contrasto negativa, potete non montare i componenti evidenziati nel riquadro denominato "pompa di carica" e cortocircuitare i pin 2 e 3 del jumper JP1. In questo modo la tensione di contrasto sarà regolabile fra 0V e +5V.

Real Time Clock

Questa parte del circuito serve per poter utilizzare il display come orologio quando il frequenzimetro non è in funzione, dunque non è necessaria per poter effettuare le misure. Inoltre il PIC16F84 non ha sufficiente memoria per poter fungere sia da frequenzimetro che da orologio e quindi non sarà in grado di gestire l'RTC.

Un Real Time Clock è un circuito autonomo capace di fungere da orologio/datario. Contiene dei registri, alcuni dei quali servono per l'impostazione di alcuni parametri e altri per la lettura/scrittura delle informazioni riguardanti l'ora e la data corrente. In particolare è stato scelto il PCF8593 della Philips (ora NXP Semiconductors) che comunica tramite un particolare bus a 2 fili denominato I2C e per funzionare ha bisogno di un quarzo a 32.768kHz (tipico per gli orologi). Il condensatore variabile C21 è opzionale e serve a tarare la frequenza di oscillazione del quarzo. Consiglio di saldare il chip direttamente al circuito stampato senza fare uso di zoccoli, poiché questi introducono delle capacità parassite non trascurabili che potrebbero alterare la frequenza di oscillazione del quarzo. Le resistenze R16 ed R17 servono come pull-up per il bus I2C.

Al posto del PCF8593 possono essere montati altri RTC compatibili. Uno di questi è il DS1337 prodotto da Maxim, il quale ha la stessa piedinatura e funzionamento, per il quale consiglio di non montare il condensatore variabile C21.

Dato che è probabile che risulti necessario togliere alimentazione al circuito per portarlo in un altro luogo o perché salta la corrente (cosa che a casa mia capita spesso), ho previsto una serie di componenti di contorno per fare in modo che l'RTC continui a funzionare anche in assenza di alimentazione, evitando così di dover regolare l'orologio ogni volta. Questi sono essenzialmente i diodi D14 e D15, la resistenza R19 ed il condensatore C22. Sostanzialmente, in assenza di alimentazione esterna, l'RTC viene alimentato dal condensatore C22 tramite il diodo D15. In presenza di alimentazione esterna il chip è alimentato dallo stabilizzatore a +5V tramite il diodo D14 ed il condensatore si carica tramite la resistenza R19.

Il condensatore C22 è ad alta capacità per fare in modo che l'RTC possa continuare a funzionare per vari giorni senza alimentazione esterna. È del tipo usato generalmente allo stesso scopo nei videoregistratori e non sempre è facile reperirne, perciò in alternativa potete montare qualsiasi altro condensatore, ricordando che più la sua capacità sarà elevata, maggiore sarà il tempo in cui l'orologio potrà continuare a funzionare senza alimentazione. Un'altra opzione potrebbe essere quella di montare al suo posto una batteria a bottone da 3V, che vi garantirà certamente una durata molto maggiore, ma in questo caso non dovrete montare R19.

Mentre collaudavo il circuito mi sono reso conto che spesso accendendolo l'orologio mostrava codici strani invece che le cifre dell'ora. Ho quindi scoperto che ciò era dovuto al fatto che lo spegnimento del circuito avveniva mentre il PIC comunicava con l'RTC. Per evitare che questo si verifichi ho implementato un circuito (visibile nel riquadro chiamato "presenza alimentazione") che rileva la presenza di alimentazione esterna, in modo tale da poter inibire la comunicazione fra i circuiti integrati quando l'alimentazione esterna viene a mancare.

Nel caso non intendiate utilizzare la funzione orologio/datario potrete fare a meno di montare i componenti evidenziati nei riquadri denominati "RTC" e "presenza alimentazione" e sostituire il diodo D12 con un semplice pezzo di filo.

Firmware

Blocchi principali

Verrà qui brevemente illustrato il ruolo delle routine principali. Si farà riferimento al file "freq_230_2x20.asm" contenuto nell'archivio di download, dato che questa risulta essere la versione più completa. Il firmware è stato scritto interamente in linguaggio assembly, sia per ottimizzare il codice macchina prodotto, sia per rispettare rigorosamente le tempistiche richieste.

Ricordo che le routine di comunicazione per il bus I2C e per il display, nonché quelle per la misura della frequenza, sono state scritte per PIC che montano quarzi da 4MHz. Questo significa che le routine di comunicazione funzionano correttamente anche a frequenze inferiori, ma non è garantito il funzionamento a frequenze maggiori perché potrebbero non rispettare le tempistiche necessarie. Le routine per la misura della frequenza invece sono specifiche per quarzi a 4MHz, cioè forniscono un risultato non corretto se vengono montati quarzi di valore differente.

Inizializzazione

La prima parte del file è dedicata all'impostazione di alcuni flag per definire la modalità di funzionamento del microcontrollore, alla dichiarazione delle variabili utilizzate e alla scrittura di due macro per l'abilitazione e disabilitazione del Timer0, utilizzato per la misurazione della frequenza.

La prima parte del firmware ha il compito di selezionare la direzione I/O dei singoli pin del microcontrollore e di impostare la modalità di funzionamento del Timer0, quindi richiama la routine di inizializzazione del display LCD, visualizza sul display la versione del firmware e verifica la presenza o meno dell'RTC. Fatto questo, se l'RTC è presente e compatibile viene eseguito il ciclo di visualizzazione dell'ora corrente, altrimenti viene eseguita immediatamente la routine di misura della frequenza.

Funzioni per il bus I2C

Dato che i PIC utilizzati non dispongono di una porta I2C hardware, sono state scritte delle funzioni per implementarla via software. Queste sono:

RTC_start
apre la comunicazione sul bus;
RTC_sendByte
trasmette un byte sul bus;
RTC_getByte
riceve un byte dal bus;
RTC_getStop
chiude la comunicazione sul bus durante la ricezione;
RTC_stop
chiude la comunicazione sul bus durante la trasmissione.

Per semplicità le routine appena descritte non effettuano alcuna verifica della correttezza dei dati trasmessi o ricevuti. L'unico controllo che viene effettuato è sulla conferma di ricezione da parte del dispositivo slave (l'RTC in questo caso) del dato trasmesso dal microcontrollore. Nel caso in cui lo slave non confermi la ricezione la routine si limita a scrivere il valore "1" sul registro RTCerror che, in condizioni normali, ha valore pari a "0".

Funzioni per la gestione dell'RTC

La routine getTimeDate ha il compito di ottenere dall'RTC l'informazione riguardante l'ora e la data correnti, nonché di salvarne i valori corrispondenti in apposite variabili.

Le routine printTime, printWeekday e printDate visualizzano sul display rispettivamente l'ora, il giorno e la data correnti, mentre printTimeDate visualizza l'insieme di queste tre nella corretta posizione del display.

Le funzioni setWeekday, setdDay, setDay, setdMon, setMon, setMillennium, setCentury, setdYear, setYear, setdHours, setHours, setdMin, setMin, setdSec e setSec servono a regolare i vari valori dell'ora e della data e a salvarli nell'RTC.

Le routine setTimeDate, placeCursor, goLeft, goRight e modifyTimeDate servono per la gestione del display e dei pulsanti per la modifica dell'ora e della data, mentre toggleOrologio e menuOrologio costituiscono il menu di selezione per le modalità "Frequenzimetro" o "Imposta data/ora".

Funzioni per il display LCD

Per semplificare l'uso del display LCD testuale sono state scritte delle funzioni specifiche, quali:

LCDinit
inizializza il display stabilendo una comunicazione del tipo a 4 bit di dati;
LCDclear
pulisce il display e posiziona il cursore in alto a sinistra;
LCDlocate
posiziona il cursore in una particolare posizione del display definita dal contenuto del regitro W in cui i 4 bit più significativi indicano la riga ed i rimanenti 4 la colonna (i valori ammessi vanno da 0 a 15);
LCDsendData
trasmette al display il contenuto del registro W come dato;
LCDsendCommand
trasmette al display il contenuto del registro W come comando;
LCDsendByte
trasmette al display il contenuto del registro W;
LCDprintNum
visualizza sul display la cifra corrispondente al valore contenuto nel registro W (i valori corretti vanno da 0 a 9);
printDot
visualizza un punto sul display.

Queste funzioni stabiliscono con il display una comunicazione in modalità a 4 bit di dati e due bit di controllo, E per l'enable ed RS per la selezione del registro (istruzioni o dati). Questo significa che ogni dato o comando da inviare al display, che è formato da 8 bit, deve essere suddiviso in due gruppi da 4 bit (nibble) che vengono inviati separatamente (per primi i 4 bit più significativi e poi i rimanenti 4 bit meno significativi). Non viene utilizzato il bit R/W per la selezione della modalità di lettura o scrittura, in quanto viene utilizzata solamente quella in scrittura verso il display.

Funzioni per la misura della frequenza

La routine principale per la misura della frequenza è denominata, molto fantasiosamente, frequenzimetro. Questa si occupa di richiamare la funzione di misura vera e propria, di visualizzare sul display il valore misurato, di verificare che non sia avvenuto un overflow durante il conteggio, nonché di valutare le eventuali pressioni dei tasti.

La funzione rangeSelect, assieme a incRange e a decRange, viene richiamata ogni qualvolta si desideri selezionare un differente range di misura.

La routine measure è la vera responsabile delle misure, infatti, in base al range selezionato, richiama a sua volta la routine specifica per quel range. Ognuna di queste routine (kHz5, kHz_50, kHz_500, MHz_5 e MHz_50) ha un funzionamento molto semplice: azzera ed abilita il Timer0, attende un preciso tempo predefinito specifico per quel range di misura, quindi disabilita il Timer0; successivamente richiama la funzione getfreq, la quale provvede ad immagazzinare in appositi registri il valore a 16 bit corrispondente alla misura.

Analizziamo con maggiore dettaglio la procedura di misura. Per prima cosa faccio notare che i pin 2 e 3 del microcontrollore (rispettivamente RA3 ed RA4) sono cortocircuitati fra loro ed entrambi sono collegati allo stadio di ingresso del frequenzimetro tramite la resistenza R11. Inoltre il Timer0 è assegnato al pin RA4 con un prescaler fissato a 256. Questo significa che il valore del Timer0 viene incrementato di una unità ogni 256 impulsi rilevati all'ingresso del pin RA4. Per non interferire con la misura il pin RA3 viene impostato come ingresso e risulta totalmente ininfluente. Dall'istante in cui il Timer0 viene abilitato, fino a quando viene disabilitato, questo conteggia gli impulsi rilevati al suo ingresso. Trascorso il tempo prestabilito, il pin RA3 viene impostato come pin di uscita e, mantenendo il suo valore fisso, viene di fatto inibito il conteggio di eventuali ulteriori impulsi presenti all'ingresso del frequenzimetro. A questo punto il Timer0 contiene il valore della misura, il quale però, dato che il valore del prescaler non è visualizzabile da alcun registro accessibile, è solamente ad 8 bit. Per aumentare a 16 bit la risoluzione della misura è necessario sfruttare anche l'informazione contenuta nel prescaler ad 8 bit, ricavandola con un metodo indiretto. Per fare ciò si utilizza il pin RA3, infatti, facendo commutare il suo stato e contanto il numero di commutazioni necessarie per ottenere un incremento del valore del Timer0, è possibile risalire al numero di impulsi conteggiati dal prescaler durante la misura. Per questa procedura ho preso spunto dall'application note AN592 della Microchip, anche se poi ho dovuto modificare il codice per risolvere certi problemi. Abbiamo così ottenuto un numero a 16 bit che corrisponde al conteggio del numero degli impulsi rilevati da RA4 durante il tempo in cui il timer era abilitato, ma che legame ha questo valore con la frequenza del segnale? Se la durata della misura è di un secondo esatto (e non si sono verificati overflow) il valore indica esattamente la frequenza del segnale fornito in ingresso al frequenzimetro, ma questo valore può variare da 0 a 65535 (216-1), quindi come è possibile misurare frequenze maggiori? Semplicemente modificando il tempo di misura! Infatti se ad esempio il tempo di misura fosse di 0,1 secondi si potrebbero misurare frequenze che vanno da 0 a 655350 Hz con la risoluzione di 10Hz, con tempi di 0,01 secondi frequenze fino a 6553500 Hz con risoluzione di 100Hz e così via. L'unico limite è dato dalla frequenza massima alla quale il Timer0 è in grado di funzionare, che, secondo il datasheet del costruttore, è di 50MHz per segnali con duty-cycle del 50%. Naturalmente nulla vieta di usare un prescaler digitale da anteporre al frequenzimetro, ad esempio del tipo montato dai televisori per la selezione del canale UHF-VHF (con frequenze di funzionamento che arrivano oltre al GHz).

La routine checkLower indica se il dato della misura a 16 bit risulta inferiore al valore di 5000 o meno. Questa verifica è utilizzata nelle routine di selezione automatica del range di misura, dove il valore di 5000 è utilizzato come valore di soglia per passare al range inferiore.

Le routine delay1ms, delay10ms, delay100ms, delay1s e delay10s sono responsabili della corretta e precisa durata dei periodi di misura.

Per ultima, la routine convert si occupa di convertire un dato binario a 16 bit nelle singole 5 cifre decimali visualizzabili sul display. Nella mia prima versione del 2006 l'algoritmo di conversione ricalcava il procedimento tradizionale che si seguirebbe per effettuare la conversione con carta e penna. Alcuni giorni fa (metà agosto 2009) mi sono imbattuto in un algoritmo veloce, chiamato "double dabble", specifico per questo tipo di conversione anche per dati a molti bit, facendo uso solamente di somme e traslazioni, che quindi non necessitano di moltiplicazioni o divisioni. Questo mi ha permesso di semplificare di molto questa routine, impiegando molto meno spazio nella memoria programma. L'implementazione di questo algoritmo in linguaggio assembly l'ho praticamente copiata, con qualche modifica, da un certo Mike Keitz, poiché l'ho trovata molto efficiente.

Uso del frequenzimetro

Considerando la versione "completa" (con il PIC16F628 e l'RTC), al momento dell'accensione verrà visualizzata l'ora e la data correnti. Per inciso, alla prima accensione del sistema dopo averlo montato ed ogni qualvolta viene ri-acceso dopo che il condensatore (o la batteria) tampone del Real Time Clock si è scaricato, verranno visualizzati valori casuali senza alcun senso, per cui sarà necessario impostare i valori corretti.

foto del display 2x16 durante la visualizzazione dell'ora  foto del display 2x16 durante la visualizzazione del menu di selezione

Premendo il pulsante "Menu" si entrerà appunto in un menu dal quale sarà possibile scegliere se entrare nella modalità di settaggio dell'ora e della data, oppure nella modalità "frequenzimetro". Con i pulsanti di direzione (SX e DX) si potrà selezionare l'opzione desiderata e premendo nuovamente "Menu" confermare la selezione. Scegliendo di impostare data e ora verrà visualizzata una schermata dove con in pulsanti "DX" e "SX" si potrà navigare fra i vari valori, con "Menu" si potrà selezionare quello che si vuole modificare, quindi modificarlo con i pulsanti di direzione e confermarlo premendo "Menu". Dopo aver impostato i valori a proprio piacimento si potrà tornare alla schermata principale selezionando "Ok" e premendo "Menu". Scegliendo invece la voce "Frequenzimetro" apparirà una schermata dalla quale sarà possibile visualizzare il valore di frequenza misurato.

foto del display 2x16 durante l'impostazione della data e dell'ora  foto del display 2x16 durante la visualizzazione della frequenza misurata

Per impostazione di default, appena entrati in modalità "Frequenzimetro" verrà visualizzata la frequenza misurata con range 1kHz÷50MHz. Premendo i tasti di direzione sarà possibile selezionare il range desiderato e confermarlo premendo "Menu". I range disponibili sono: 50MHz (1kHz÷50MHz), 5MHz (100Hz÷5MHz), 500kHz (10Hz÷500kHz), 50kHz (1Hz÷50kHz) e 5kHz (0.1Hz÷5kHz). In aggiunta a queste ci sono due modalità automatiche denominate "Auto" e "Vel." (che sta per veloce), la prima delle quali selezionerà in modo automatico il range che permetterà di misurare la frequenza con la massima definizione prossibile; la seconda è analoga alla prima, salvo il fatto che non utilizzerà la portata 5kHz. Il motivo di ciò sta nel fatto che quest'ultima portata impiega 10 secondi per essere compiuta (questo per poter misurare segnali a bassa frequenza fino a 0.1Hz) e può risultare scomodo avere una portata automatica che impiega così tanto tempo per effettuare una misura (cosa che accadrebbe ad esempio quando la sonda di misura non è collegata al segnale e quindi rileva una frequenza di 0Hz, o comunque per segnali a frequenza inferiore a 5kHz). Nel caso la frequenza del segnale fosse maggiore di quella massima misurabile con la portata selezionata verrà visualizzato un messaggio di overflow, ad indicare che il valore riportato non è corretto.

foto del display 2x16 durante l'impostazione del range di misura  foto del display 2x16 mentre la misura di frequenza è in overflow

Per terminare la misura di frequenza e tornare alla visualizzazione dell'ora e della data è sufficiente premere nuovamente "Menu". Per rispettare rigorosamente le tempistiche necessarie a compiere una misura precisa, le pressioni dei tasti che avvengono durante la misura vengono ignorate. Ciò produce un ritardo nella risposta del frequenzimetro alla vostra richiesta. Risulta perciò necessario mantenere premuto il tasto desiderato e rilasciarlo non appena il sistema risponde alla richiesta. Questo effetto risulta più accentuato durante le misure per le quali il range selezionato è basso (soprattutto per quello di 5kHz, dato che in questo caso la misura ha una durata di 10 secondi).

Versioni del firmware

Come già accennato in precedenza, sono state sviluppate varie versioni del firmware per il frequenzimetro. La versione "base" (1.X0) è quella che fa uso del PIC16F84 (o una delle sue varianti) e implementa solamente il frequenzimetro. È disponible in tre varianti, per display 1x8, 1x16 e 2x16.

La versione più completa (2.X0) necessita del PIC16F628 (o una delle sue varianti) e, oltre che da frequenzimetro, funge anche da orologio/datario. Sono disponibili due varianti per display 2x16 e 2x20.

Esiste infine un'ultima versione (1.X1), che non pensavo fosse possibile realizzare prima che trovassi l'algoritmo "double dabble" per la conversione dal dato binario alla notazione decimale, che consente di far funzionare lo stesso PIC16F84, oltre che come frequenzimetro, anche da orologio (ma non come datario). Ho fatto un po' di fatica ad implementare tutto il codice necessario avendo a disposizione solamente 1024 word di memoria programma (sfruttata completamente fino all'ultimo bit) e 64 byte di EEPROM: ho dovuto penalizzare lievemente certi aspetti marginali ma il risultato ottenuto mi sembra decisamente molto soddisfacente (per lo meno io ne sono molto orgoglioso). Questa versione è disponibile nelle varianti per display 1x16 e 2x16.

Per quanto mi riguarda utilizzo la versione per PIC16F628 con display 2x20, che è la più completa. Fatte salve alcune lievi modifiche, è la stessa versione che utilizzo dal 2006, cioè da quando ho sviluppato la prima versione del frequenzimetro. Le altre versioni derivano da questa. Se invece optaste per l'utilizzo del PIC16F84, consiglio la variante per display 1x16 adatta a gestire anche l'RTC. In ogni caso tutte le versioni del firmware funzionano correttamente come frequenzimetro anche se l'RTC non viene montato.

Queste prime versioni del firmware non sono ancora in grado di gestire l'RTC DS1337 perciò, se si desidera utilizzare anche la funzione orologio/datario, sarà necessario montare un PCF8593. Probabilmente in futuro proporrò anche delle versioni compatibili con il DS1337, ma non garantisco di farlo ne, tantomento, di farlo in breve tempo. Nel caso aveste delle particolari esigenze posso vedere se riesco a rilasciare una nuova versione o a darvi una mano perchè possiate modificare voi stessi il mio codice per adattarlo ad altri RTC (contattatemi via mail).

Download

In un unico archivio in formato rar ho raccolto tutti i file contenenti i codici macchina da caricare nei microcontrollori, i relativi sorgenti in assembly, lo schema elettrico, la lista componenti ed il disegno del PCB sia in formato FidoCad che pdf.



torna all'inizio     Stampa



Progetto creato nel luglio-agosto del 2006.

Ultimo aggiornamento avvenuto il 29/08/2009.

Valid HTML 4.01 Transitional    Valid CSS