Generatore DTMF con micro RENESAS

Questo articolo descrive come creare un generatore multifrequenza dual tone attraverso la tecnica PWM e utilizzando i micro Renesas H8/300H.

Il DTMF è un sistema diffuso in telefonia per la codifica di codici numerici in segnali sinusoidali in banda audio. Ogni volta che premiamo un tasto sul telefono di casa o componiamo un codice di carta di pagamento, un apposito circuito converte la cifra in due sinusoidi di frequenze opportunamente scelte, adatte ad essere trasmesse su lunghe distanze sino alla centrale o ai server di gestione del traffico bancario. Prima del DTMF veniva utilizzato il  sistema ad impulsi: nei vecchi apparecchi telefonici  il disco (combinatore) che facevamo ruotare azionava un interruttore che interrompeva la linea telefonica un numero di volte corrispondente alla cifra impostata: in tal modo ad ogni numero telefonico era associato un insieme di impulsi che raggiungeva la centrale di commutazione.  Questo metodo si poteva però solo impiegare per tale scopo, essendo inadatto per altri servizi, tipo il telecontrollo, tutti i sistemi antifurto, o servizi di integrazione pc/telefono; inoltre esso era assolutamente incompatibile con la trasmissione via satellite o ponte radio, essendo ancorato al doppino in rame. Fu così che il  DTMF divenne il  principale sistema di codifica già a partire dagli anni ’60. Esso prevede l’utilizzo di una tastiera standardizzata, quella presente sui nostri telefoni (essa ha lo stesso aspetto di quella dei cellulari ed è simile a quella delle tastiere dei pc, ma in questi ultimi la prima e la terza riga sono invertite!); alle dieci cifre iniziali (0…9), vennero in seguito aggiunti anche il tasto # e *, utili per interfacciare  il telefono ai sistemi informatici, ed un gruppo di tasti per la selezione di menù e opzioni A,B,C e D (questi ultimi per gestire funzioni interne alle centrali di smistamento, o associare vari livelli di priorità alle chiamate, come avviene presso l’esercito statunitense col sistema Autovon). La figura 1 evidenzia  il modo in cui vengono associate le due frequenze ad ogni cifra della tastiera: questa è una matrice 4x4; alle righe corrispondono le frequenze basse, mentre alle colonne frequenze più alte.

Figura 1: layout della tastiera DTMF

Figura 1: layout della tastiera DTMF

Per esempio, al tasto 7 corrispondono il tono basso 852 Hz e il tono alto 1209 Hz. La scelta dei particolari valori dei toni è dettata da precise esigenze tecniche; le armoniche e i  valori di intermodulazione non devono essere troppo vicini a quelli delle frequenze stesse: detto in altri termini nessuna delle frequenze deve essere un multiplo intero delle altre e la somma o la differenze delle frequenze associate ad un qualsiasi tasto deve assumere valori non troppo vicini a qualche altro tono della tastiera. Nella prossima sezione vedremo come generare via software le frequenze che ci interessano attraverso un micro H8/36014.

Implementazione tramite micro

La figura 2 mostra un esempio di interfaccia Keyboard-micro per la generazione dei toni DTMF tramite la tecnica PWM.

Figura 2: configurazione hardware.

Figura 2: configurazione hardware.

Conversione D/A

Come si può notare il segnale PWM, in uscita dal pin FTIOB, viene filtrato dal passa-basso attivo LPF1, che ha una frequenza di cut-off di 3 kHz: tale valore è sufficientemente più basso di quello del segnale PWM (31,25 KHz); tuttavia, essendo disegnato su un Op-Amp, esso non funziona bene alle altissime frequenze, per cui è seguito da un filtro CR passivo che blocca anche le frequenze dell’ordine del MHz. Il livello  del segnale in uscita è determinato dal valore del duty-cycle dell’onda PWM secondo la regoletta Vout = V x H/T, dove V è l’ampiezza dell’onda, H è il  periodo in cui essa rimane a livello alto e T il periodo. Essendo le frequenze in uscita nella banda udibile esse possono essere riprodotte da uno speaker.

Generatore DTMF

Il  generatore DTMF usa le porte P70…P73, come output, ponendole in successione a livello alto; poi esegue una scansione delle tre rimanenti porte, come input, e se ne trova una alta riconosce il tasto premuto, determinando così le due frequenze da generare. Le sinusoidi corrispondenti sono ricavate da una sinetable, i cui valori vengono letti e poi scritti negli opportuni registri del modulo WPM del micro; le diverse frequenze sono ricavate dalla lettura dei campioni della sine-table, con una spaziatura tra essi che dipende proprio dalla frequenza desiderata. Facendo nuovamente riferimento alla figura 1, si nota che premendo per esempio il tasto 1 vengono generate le due frequenze 697Hz e 1209Hz, la cui somma è poi inviata verso l’altoparlante.

Struttura del firmware

La figura 3 mostra le varie parti, o funzioni, che compongono la struttura del programma del microcontrollore.

Figura 3: diagramma a blocchi delle funzioni del firmware

Figura 3: diagramma a blocchi delle funzioni del firmware

Al timer W compete la generazione dell’onda PWM; settando ad 1 il  bit PWMB del registro TMR W (registro  mode del timer), il  bit FTIOB della porta d’uscita (Port 8) associata al timer stesso (ma volendo anche i  bits FTIOC e FTIOD) viene usato come uscita PWM. In tale modalità il registro GRA può diventare un contatore di ciclo e il registro GRB (ma anche quelli GRC o GRD) può essere usato per impostare il valore del dutycycle: modificando quest’ultimo si cambia così la frequenza generata. I  pin dal P10…P12 della porta 1 sono usati come input nella scansione della tastiera, mentre i pin P70…P73 della porta 7 sono posti ad alto livello sequenzialmente. Nella figura 4 è riprodotto più in dettaglio il meccanismo di formazione dell’onda PWM a partire dal timer W: il periodo di questa è scandito dal valore scritto nel registro GRA.

Figura 4: formazione dell’onda PWM.

Figura 4: formazione dell’onda PWM.

Come si vede ogni volta che il contatore TCNT raggiunge il  valore impostato in GRA (HFF nell’esempio)  il pin FTIOB passa a livello logico alto (compare match interrupt di GRA) dando inizio ad un nuovo periodo del PWM. Quando lo stesso contatore arriva al valore scritto in GRB1 (compare match interrupt di GRB), FTIOB passa a livello basso; poi, al nuovo periodo, FTIOB torna a zero in corrispondenza del valore GRB2 e così via ad ogni ciclo. Via software è necessario  riazzerare il flag IMFA del registro TSRW, che gestisce le richieste di interrupts; in questo modo, quando si ripresenta un evento che fa scattare l’interrupt (il  raggiungimento del valore del registro GRA o input capture/compare matchA) esso può nuovamente essere servito. In seguito vengono letti gli opportuni valori sulla sine-table, ovvero i due campioni delle due sinusoidi corrispondenti alla frequenza alta e bassa, e la loro somma viene inviata al registro GRB, destinato alla regolazione del duty-cycle nella maniera vista.

Moduli  software, registri impiegati Routine main

Alla routine main è solo affidato il compito di:

➤ inizializzare le variabili relative alla posizione di lettura sulla sine-table e gli incr ementi da cui dipendono le frequenze;

➤ inizializzare i registri associati  alle porte 1 e 7 per definire i pins di input e di output per la scansione;

➤ inizializzare  il registro di controllo del timer per selezionare  la fonte di clock, selezionare la condizione di azzeramento del contatore (nell’esempio TCNT è azzerato in corrispondenza del match interrupt generato dal raggiungimento del valore impostato in GRA) e selezionare il livello iniziale del pin d’uscita FTIOB prima dell’arrivo del primo match interrupt di GRB;

➤ inizializzare  il registro di controllo degli interrupts (TIERW), abilitando le richieste generate dal flag IMFA del registro di stato degli interrupts (TSRW);

➤ inizializzare la chiave relativa al tasto premuto sul keypad;

➤ nel caso si sia premuto un nuovo tasto sulla tastiera, ricavare gli incrementi della posizione di lettura sulla sine-table, calcolati in funzione della chiave relativa al tasto, altrimenti mascherare le richieste di interrupts e reinizializzare a zero le variabili posizione e incremento.

Routine  di scansione

La routine di scansione ricava una chiave in corrispondenza di ogni tasto premuto (valori da 0 a 11), altrimenti ritorna il valore -1.

Routine  di interrupt del timer  W

Calcola la nuova posizione di lettura sulla sinetable e aggiorna l’uscita PWM in funzione dei valori letti per le due frequenze.

Registri  associati al firmware

TMRW: registro di impostazione delle funzioni del timer W. I bit da impostare sono il 7 (CTS) e lo 0 (PWMB);

TCRW: registro di controllo di W. I bit che interessano sono il bit7 (CCLR) di azzeramento del contatore TCNT in corrispondenza dell’interrupt matchA, i bit 6,5,4 di selezione della fonte di clock e il bit1 (TCB) di selezione del livello iniziale di FTIOB;

TIERW: registro di abilitazione degli interruptus. Il  bit da controllo è lo 0 (IMIEA);

TSRW: registro di controllo dello stato delle richieste di interruptus.  I bit di interesse sono il bit 1 (IMFB) relativo al compare match flag B e il bit 0 (IMFA) relativo al compare match flag A;

TCNT: contatore associato al timer W;

GRA e GRB: registri general purpose che in modalità PWM diventano rispettivamente registro di ciclo (periodo PWM) e registro di impostazione del duty-cycle;

PCR1 e PDR1: registri rispettivamente di impostazione dei pin di input o output della porta1 e di buffer dati della stessa porta;

PCR7 e PDR7: come sopra per la porta7.

Variabili RAM usate

INC1 e INC2: variabili che servono per immagazzinare gli incrementi da apportare di volta in volta nella lettura della sine-table;

POS1 e POS2: posizioni sulla sinetable;

KEY_DATA: buffer di raccolta dei valori della chiave  della tastiera  ( per confrontarli di volta in volta con i successivi);

KEY: variabile di acquisizione della chiave.

Variabili ROM

PB: memorizza l’incremento della sinetable relativamente alla chiave premuta;

SINE[ ]: array popolato dai valori campionati della funzione seno.

Diagramma di flusso del firmware

Nelle figure 5, 6 e 7 sono riportati i diagrammi di flusso della funzione main, della routine di scansione della tastiera e della routine di interrupt del timer W.

Figura 5: diagramma di flusso di una parte del main (senza le inizializzazioni).

Figura 5: diagramma di flusso di una parte del main (senza le inizializzazioni).

 

Figura 6: diagramma di flusso della routine di scansione della tastiera.

Figura 6: diagramma di flusso della routine di scansione della tastiera.

 

Figura 7: diagramma dell’interrupt del timer W.

Figura 7: diagramma dell’interrupt del timer W.

 

Come si può notare, all’interno del main è presente una struttura condizionale per cui, in caso di pressione di una cifra della tastiera, vengono caricati i nuovi valori degli incrementi inc1 e inc2, relativi alle due frequenze associate alla cifra premuta. Tali valori sono ricavati direttamente dall’array bidimensionale PB, la cui struttura è del tipo PB[12][2]:  il primo valore corrisponde al numero delle cifre della keyboard, mentre il secondo valore è ovviamente  il numero delle frequenze generate da ogni tasto premuto. In caso contrario (nessun nuovo tasto premuto)  il programma entra in un loop di attesa, all’interno del quale vengono mascherate le richieste di interrupt e reinizializzate a zero le variabili POS1, POS2 e INC1, INC2. Nella routine di acquisizione della cifra premuta sulla tastiera sono presenti due cicli annidati, il più interno dei quali corrisponde alla scansione della porta di input PORT1; i primi 3 bit sono posti uguali ad 1 in successione, fino a quando il valore contenuto nel registro PDR1, relativo alle colonne della tastiera, non supera il valore 4; quando viene superata tale cifra si incrementa  la variabile j del ciclo più esterno, quello relativo alla porta PDR7, ovvero alle righe, fino a quando essa raggiunge il valore 8; a questo punto il programma ritorna al main. Infine la routine di interrupt del timer W consiste nel riazzerare i flag dei match interrupt A e B, in modo da renderli nuovamente attivi, e di aggiornare le variabili pos1 e pos2 con i nuovi incrementi inc1 e inc2; infine la somma dei due valori della sine table vengono scritti nel registro del duty-cycle.

 

 

Scrivi un commento

EOS-Academy