Codificatore per tastiera 4x3
|
Può essere comodo disporre di una tastiera con uscita già codificata; questo
permette di risparmiare tempo nello scrivere il programma per un
microcontroller ospite che, magari, non dispone di pin sufficienti per la
scansione della matrice.
Certamente esistono encoder per keypad, come 74C922 (fino a 16 tasti) e 74C923
(fino a 20 tasti), ma hanno sempre avuto un costo assai elevato e questo sconsiglia
il loro uso, sopratutto da quando possiamo effettuare la stessa operazione utilizzando un piccolo
microcontroller, molto più economico.
In particolare, ci indirizziamo verso il PIC16F505, un 14 pin Baseline.
La scelta di questo componente non certo recentissimo e ben poco performante
è voluta per due semplici motivi: il primo è che si tratta probabilmente del
PIC a 14 pin con il costo più basso; questo (meno di 0.8€ su
MicrochipDirect) fa si che la sua introduzione nel circuito pesi veramente
poco, anche perchè bastano solo altri 5 componenti, oltre alla tastiera. Si
sarebbe potuto utilizzare anche 16F54, ancor meno dispendioso, ma è un 18 pin
e necessita di un oscillatore esterno, il che, tutto sommato, annulla la
piccola differenza nel costo del chip.
Il secondo è che, per questa applicazione, non serve alcuna prestazione
particolare. In effetti, utilizziamo solamente la funzione di risveglio da sleep
per cambio di livello sui pin (IOC).
Il circuito.
Il circuito è previsto per una tastiera a matrice 4x3, di uso piuttosto comune. Si potrà
comunque codificare qualsiasi numero di tasti inferiore.
Ci basiamo sulla funzione IOC, che è programmabile su RB0,1,3,4 e dove sono
attivabili i weak
pull-up integrati, il che consente di risparmiare le resistenze esterne.
Le resistenze in serie alla tastiera sono opzionali ed hanno lo scopo di
limitare problemi ESD al contatto tra tasti e operatore. Il valore tipico è
100 ohm.
Anche le resistenze in serie alle linee dati sono opzionali e servono per
proteggerle sia da ESD che da cortocircuiti. Anche qui siamo attorno ai 100
ohm, valore non critico.
JP1 è il connettore di accesso i dati e comprende anche l'alimentazione, che
può andare da 2 a 5.5V. Le resistenze RN1 sono dei pull down (100k) (Vedere la spiegazione più
avanti).
SP1 è un altoparlante miniatura da 50-120 ohm oppure un elemento piezo o un
buzzer (vedere spiegazione più avanti). Il diodo D1 è necessario solo se si
tratta di un elemento elettromagnetico; per un elemento piezo si sostituirà
con una resistenza da 1k circa.
I
condensatori C1 sono il solito 100nf vicino ai pin del chip e un 47uF
elettrolitico.
E' presente la presa ICSP per modificare on board il firmware del micro.
Il circuito è sperimentabile sulla LPCuB:
4 jumper volanti collegano i pin di uscita dati con i LED 0,1,2,3 per
visualizzarne lo stato.
Un cavetto a 7 poli collega la tastiera.
Il jumper volante "rosa" collega il buzzer sulla scheda.
Il programma.
Il chip è normalmente in condizione di sleep a bassissimo consumo, cosa
che permette di non caricare l'alimentazione anche in circuiti low power.
L'uscita dati è in three-state ed è mantenuta a livello basso con un pull-down. Il
processore host, leggendo le linee dati, troverà 0000 se nessun tasto è
premuto.
Quando viene premuto un tasto, si genera un wake-up e il microcontroller
scandisce le colonne.
Se il tasto è premuto per meno del tempo di debounce o si tratta di un
disturbo, il microcontroller attende il rilascio di tutti tasti e
ritorna in sleep. Il processore host continua a leggere 0000 sulle line dati.
Se è premuto un tasto valido, il suo valore viene riportato alle linee dati,
che vengono configurate come uscita; il processore host leggerà un valore
diverso da 0. Il cicalino emette un breve beep.
Le linee dati ritornano in three-state quando il tasto è rilasciato.
Se sono premuti contemporaneamente più tasti su diverse colonne, ad esempio 1
e (colonna 1) e 2 (colonna2) il programma rileva solamente il tasto della
colonna più bassa, in questo caso il tasto 1. Volendo, è possibile
modificare il programma per ricevere più tasti.
Per semplificare al massimo l'interfaccia dati si è evitato il ricorso ad una linea Data Available con cui avvisare l'host
della presenza di un tasto premuto e si è scelta la seguente soluzione:
- le linee dati sono a 0 se nessun tasto valido è premuto
- se è premuto un tasto, le linee dati indicano il valore del tasto +1
Quindi:
D3 |
D2 |
D1 |
D0 |
Tasto |
0 |
0 |
0 |
0 |
nessuno |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
2 |
0 |
1 |
0 |
0 |
3 |
0 |
1 |
0 |
1 |
4 |
0 |
1 |
1 |
0 |
5 |
0 |
1 |
1 |
1 |
6 |
1 |
0 |
0 |
0 |
7 |
1 |
0 |
0 |
1 |
8 |
1 |
0 |
1 |
0 |
9 |
1 |
0 |
1 |
1 |
* |
1 |
1 |
0 |
0 |
# |
Quando l'host verifica un dato diverso da 0, lo preleva e lo elabora
semplicemente sottraendo 1 per ottenere il valore del tasto premuto.
Questi valori fanno parte di una lookup table che contiene tutte le
64 possibili combinazioni dei livelli dei 5 pin di PORTB.
movf
keyold,w ; verifica se 0
; se 0 nessun tasto valido è premuto
; se !=0 è premuto un tasto oppure nessuno
skpnz
; no - test successivo
goto kbnook
; =0 - tasti non validi
; verifica se 0xF = nessun tasto è premuto
xorlw 0x0F
; inverti per verificare tasto non premuto
skpz
; se 0 vai alla prossima colonna
goto kbok
; se non 0 debounce tasto
goto scl1
; scansione prossima colonna |
L' uso di una
tabella retlw consente di minimizzare le operazioni di decodifica del
tasto e dà la possibilità di variare facilmente i valori a seconda delle
necessità. Non vanno
modificate le locazioni a 0 e a Fh dato che questi valori sono usati dal
programma per le selezioni:
; TABELLA TASTIERA
;
; layout della tastiera EOZ ECO.12150.06
; <pin #>
; col0 col1 col2
; <x1> <x2> <x3>
; <y1> 1 2 3 row0
; <y2> 4 5 6 row1
; <y3> 7 8 9 row2
; <y4> * 0 # row3
;
; 0 = nessun tasto ammissibile
; Fh = nessun tasto premuto
; I tasti da 0 a 9 sono aumentati di 1
; * -> B , # -> C
KeyTable
addwf PCL,F
; 0 1 2 3 4
5 6 7 8 9 A B C
D E F
dt 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,0xC ; 00-0F
dt 0, 0, 0, 0, 0, 0, 0,0xA, 0, 0, 0,
0, 0, 7, 4,0xF ; 10-1F
dt 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xB, 0, 0, 0, 1
; 20-2F
dt 0, 0, 0, 8, 0, 0, 0, 9, 0, 5, 2,0xF, 0, 6, 3,0xF
; 30-3F |
Si possono implementare altre alternative per quanto riguarda
l'uscita; ad esempio, se ci sono problemi di pilotaggio di un tratto di cavo
tra tastiera e host, le linee dati si possono lasciare in sleep configurate come uscite
dopo averle portate a 0. In questo caso i pull-down non servono e vanno omessi. In tal caso
occorre modificare la parte finale del programma:
; tasti rilasciati - sleep
ToSleep
clrf PORTC
; azzera pin uscita
clrf PORTB
; col0-2 = 0
bcf col1
; col1 = 0
goto $+1
; stabilizzazione
goto $+1
movf PORTB,w
; clear flag ioc
sleep |
Il cicalino per il beep può essere un micro speaker, da 50-120 ohm. Se il
valore della resistenza è basso, occorrerà mettere una piccola resistenza in
serie oppure usare un buffer. Il diodo serve ad evitare la sovratensione alla
diseccitazione della bobina.
Si potrà usare un elemento piezo; in tal caso al posto del diodo si userà
una resistenza (1k circa).
Il programma genera un'onda quadra da 2-3kHz.
Se occorre un suono robusto, si potrà ricorrere ad un buzzer. In tal caso
non occorre il segnale di pilotaggio, ma basterà comandare il pin per il
tempo voluto.
; comando buzzer con driver
interno
Beep
bsf
buzz
call
Delay100ms
bcf
buzz
retlw 0 |
Senza buffer, la corrente massima nel buzzer non dovrà superare la portata
del pin (25mA).
Il sorgente non prevede comandi per l'aggiustamento delle pagine o il rinvio
indiretto delle subroutines, dato che tutto il programma è contenuto nella
pagina 0 e tabelle e subroutines non superano le prime 256 locazioni.
La selezione iniziale permette la compilazione per 16F505/506/526, ma il tutto
è facilmente
portabile su qualsiasi altro PIC con un sufficiente numero di pin.
La costruzione.
Nulla di particolare, data la semplicità del circuito. Per il prototipo è
stato realizzato uno stampato della stessa dimensione della tastiera (EOZ ECO.12150.06),
ma si potrà facilmente utilizzare qualsiasi altro modello, tenendo presente
che si tratta comunque di un keypad a matrice.
Il progetto MPLAB completo.
|