Esercitazioni
PIC Baseline
|
20Aw - Encoder incrementale e display in multiplex
Una variazioni sulla Esercitazione 20A
L' hardware
Utilizziamo l' hardware di base dell' esercitazione 20A per realizzare un contatore
up/down su due cifre a sette segmenti:
PORTC e un bit del PORTB
sono usati per i sette segmenti, mentre
due pin sono dedicati al comando dei gate dei MOSFET che pilotano i catodi
comuni delle due cifre in multiplex; altri due pin sono utilizzati dai segnali
dell' encoder. Ruotando in senso orario l' albero dell' encoder il display
conterà a crescere da 00 a 99; l' opposto se il senso è antiorario.
Il pulsante di RESET azzera il risultato, facendo ripartire il programma
dall'inizio.
In questa applicazione tutti i pin del chip sono utilizzati !
La LPCuB
semplifica le connessioni, anche se occorre sempre un supporto a parte per l'encoder:
I jumper "gialli" collegano i segmenti da a a f.
Il jumper volante "giallo" collega il segmento g.
I jumper volanti "verde" e "nocciola" collegano i segnali
dalla scheda dell' encoder.
I jumper volanti "marrone" e "rosso" collegano i gate dei
MOSFET.
Il pulsante RES è utilizzato come RESET; quindi occorrono i jumper
"rosso" e "viola"
Se si utilizza il filtro RC antirimbalzi sui contatti dell' encoder, durante la programmazione occorre scollegare
si RB0 e RB1, dato che la capacità collegata renderebbero difficoltosa
l'operazione. |
L' encoder trova posto su una schedina Smart
Proto Board di Mikroelektronika, inserita nel connettore JMK,
come in precedenza.
I segnali A e B sono accessibili dai pin D4 e D6
del connettore. L' encoder usato (Tyco) dispone anche di un pulsante che
è accessibile da D7, ma non viene usato in questa applicazione.
I componenti RC dell' antirimbalzo non sono indispensabili, dato che il
software campiona con un tempo maggiore di quello che il foglio dati assegna
ai bounces.
Una foto della realizzazione: pull-up e RC sono installabili su contatti a
tulipano per poter effettuare cambiamenti con facilità. In questa versione
sono installati solo i pull-up da 10k; i condensatori non sono presenti
(contati a tulipano in bassi a sinistra) e le resistente dell' RC sono
sostituite da due ponticelli (rossi).
Una foto dell' insieme durante lo sviluppo con un Pickit3:
Il programma
Il sorgente è compilabile per 16F505/506/526 con il solito sistema visto
nelle esercitazioni.
Le routines e la lookup table del display sono nella prima metà della pagina 0.
Il programma principale consiste solamente in un loop con la chiamata delle
varie subroutines, cadenzate da un ritardo fisso generato con l' ausilio del
Timer0:
;-------------------------------------------------------------------
; Ciclo principale
mainlp:
movf counter,w
; aggiorna dato per display
movwf counterd
; Digit unità
displp btfss bittmr ; 4ms ?
goto displp
; no - attesa
call Chck_Encoder ; verifica encoder e aggiorna contatore
dslp_1 btfsc bittmr ; 4ms ?
goto dslp_1
; no - attesa
call Chck_Encoder ; verifica encoder e aggiorna contatore
movf counterd,w
andlw 0x0F
; nibble basso
call Segtbl
; lookup table
call Display
; salva in temporaneo
UNITon
; cifra unità accesa
dslp_2 btfss bittmr ; 4ms ?
goto dslp_2
; no - attesa
call Chck_Encoder ; verifica encoder e aggiorna contatore
UNIToff
; si - spegni unità
; Digit decine
; Nibble basso<->nibble alto
swapf counterd,w
andlw 0x0F
; solo nibble basso
call Segtbl
; lookup table
call Display
; salva in temporaneo
DECon
; accendi decine
dslp_3 btfsc bittmr ; 4ms ?
goto dslp_3
; no - attesa
call Chck_Encoder ; verifica encoder e aggiorna contatore
DECoff
; si - spegni decine
goto mainlp
; loop
|
La cadenza, di 4ms circa, serve sia ad applicare una azione di debounce sui
test dell' encoder, sia a modulare il ciclo del multiplex dei display.
La routine di tempo è una di quelle già
viste nelle Esercitazioni, con l' impiego del Timer0 in free run e con il test di
un bit.
Variando il bit in test si varierà la cadenza; alcuni valori sono già
inseriti nel sorgente.
Il ciclo principale comprende 4 tempi da 4ms:
- 4ms
- lettura encoder
- 4ms
- lettura encoder, attivazione prima cifra display
- 4ms
- lettura encoder, spegnimento prima cifra, accensione seconda cifra
- 4ms
- lettura encoder, spegnimento seconda cifra e ripresa del loop dal punto
1
Variando la struttura si potrà assegnare al multiplex una diversa cadenza.
Il valore da presentare sui display è tratto da una copia del contatore up/down
principale, copia che è aggiornata una volta all'inizio di ogni ciclo, per evitare
sfarfallii dovuti al cambio di una cifra durante la presentazione.
La routine di verifica dello stato dell' encoder è analoga a quella vista
nell' Esercitazione 20A; l' unica differenza consiste nel fatto che il
contatore, a un byte intero, lavora in BCD nella forma packed, ovvero su numeri
intesi come decimali, da 00 a 99.
Questo facilita il trasferimento sul display, senza la necessità di ricorrere
ad una conversione da esadecimale a BCD. Per contro, si deve utilizzare un piccolo algoritmo per incrementare e
decrementare il contatore direttamente in BCD:
;*************** IncBcd ********************
; incrementa contatore in BCD
IncBcd:
movlw 0x67
addwf counter,f
movlw 0x60
skpdc
movlw 0x66
skpc
subwf
counter,f
retlw 0
;*************** DecBcd ********************
; decrementa contatore in BCD
DecBcd:
movlw 1
subwf counter,f
addwf counter,w
movlw 0x6
skpnc
movlw 0x66
skpndc
subwf counter,f
retlw 0 |
Le due routines sono speculari. Quella di incremento utilizza una somma con
67h (complemento di 99h) e poi la sottrazione con 60h se si è verificato un
overflow del flag DC, ad esempio all'incremento del contatore che contiene 09,
in modo da rendere 10 e non 0A. Se non c'è overflow del Decimal Carry si
sottrae 66h. In questo modo, su un
byte, il conteggio va da 00 a 99, dove le cifre sono impegnate sono solamente quelle da 0 a
9, escludendo le combinazioni relative alle lettere A-F del modo esadecimale.
All'incremento successivo a 99, il contatore va in overflow e torna a 00 (99+1=100), generando
però un carry che può
servire a concatenare incrementi su contatori composti da più bytes.
Analogamente il decremento, ricordando che l'opcode subwf
opera d=f-W , dove la destinazione d può essere W
o il file stesso. Anche qui, all'overflow si genera un Borrow che consente di
estendere il decremento a contatori composti da più bytes.
Incremento e decremento BCD sono sotto forma di subroutines, chiamate dalla Chck_Encoder,
a sua volta subroutine, raggiungendo così il limite massimo dello stack del
Baseline.
La lookup table per le maschere dei sette segmenti può quindi fare a meno
delle righe relative alle lettere da A a F.
retlw b'01111111' ; "8" -|G|F|E|D|C|B|A
retlw b'01101111' ; "9" -|G|F|-|D|C|B|A
;retlw b'01110111' ; "A" -|G|F|E|-|C|B|A
;retlw b'01111100' ; "b" -|G|F|E|D|C|-|-
;retlw b'00111001' ; "C" -|-|F|E|D|-|-|A
;retlw b'01011110' ; "d" -|G|-|E|D|C|B|-
;retlw b'01111001' ; "E" -|G|F|E|D|-|-|A
;retlw b'01110001' ; "F" -|G|F|E|-|-|-|A |
Non è il caso di cancellarle, dato che possono tornare utili in eventuali
estensioni del programma; per escluderle dalla compilazione basta trasformarle
in linee di commento.
Come abbiamo detto in precedenza, la divisione delle azioni in subroutines consente di modificare con facilità
il programma.
Da osservare che il programma è
trasferibile, con le solite piccole modifiche relative all' inizializzazione
degli I/O, su qualsiasi altro PIC senza problemi, dato che tutti possono
eseguire il set di istruzione dei Baseline.
File compresso contenente il progetto MPLAB.
|