ESERCITAZIONE # 12a
Comandiamo l' LCD senza la linea RW
Abbiamo accennato al fatto che è possibile risparmiare una linea di I/O del
microcontroller utilizzando un diverso approccio.
Invece di testare lo stato del flag BF con una operazione di lettura, che
richiede la linea RW a 1, possiamo procedere in un altro modo.
Dalle informazioni
contenute nel foglio dati del controller HD44780 possiamo rilevare che
l' esecuzione dei comandi richiede un certo tempo massimo; quindi, una volta
lanciata l' istruzione al display, basterà attendere il tempo richiesto per
essere ragionevolmente sicuri che l' operazione relativa sia stata portata a
termine.
Dalle tabelle fornite vediamo come ci siano due categorie di
"attesa":
- una attesa "lunga" per l' esecuzione di comandi di Clear e
Clear&Home
- una attesa "corta" per tutti gli altri
Istruzione |
Controllo |
Funzione |
Tempo
MAX |
RS |
R/W |
Clear display & Hpme |
0 |
0 |
Cancella il display e riporta il cursore alla posizione
iniziale |
1,6 ms |
Cursor Home |
Riporta il cursore alla posizione iniziale, ma non cancella il
display |
1,6 ms |
Direzione cursore e scrolling testo |
Movimento del cursore (I/D) e dei caratteri (S). |
40 us |
Controllo cursore e display |
Display visibile-On o no-Off (D)
Cursore visibile-On o no-/Off (C)
Cursore lampeggiante (B). |
Spostamento cursore o scorrimento del display |
Movimento del cursore o scrolling del display (S/C) e
direzione del movimento. |
Interfaccia, font e linee |
Interfaccia (DL), numero linee (N) e matrice (F). |
Indirizzo CGRAM |
Indirizzo CGRAM per leggere o scrivere un dato. |
Indirizzo DDRAM |
Indirizzo DDRAM per leggere o scrivere un dato. |
Scrittura dato |
1 |
0 |
Scrive un dato nella CGRAM o nella DDRAM |
40 us |
|
Da osservare che la scrittura di dati richiede una attesa "corta".
Le operazioni di scrittura richiedono la linea RW a livello 0, ovvero
collegata alla Vss, mentre RS serve a distinguere se si tratta di comandi o
dati.
Quindi, dovendo solamente scrivere dal microcontroller al display, basterà
collegare a massa la linea RW del display e implementare queste attese.
Va da se che, se la linea RW non viene utilizzata, non è possibile leggere il
contenuto della RAM del display. |
Comunque, se questa opzione non serve (e per una semplice presentazione di
testi, messaggi, dati, raramente la lettura viene effettuata), si è ottenuto il
risparmio di una linea di I/O del microcontroller che potrà essere usata per
altri scopi.
|
Dal punto di vista dei collegamenti con il PIC, basta semplicemente
scollegare il pin RW del display dalla connessione con il
microcontroller e inviarlo a massa.
Per i "puristi" va osservato che questo collegamento
richiederà un tempo di esecuzione delle routines di comando più lento
rispetto al precedente. Questo dipende dal fatto che solitamente i
controller eseguono le istruzioni in un tempo minore di quanto indicato
sul foglio dati (che è un tempo massimo).
Ne risulta che solitamente il comando inviato è eseguito prima dello
scadere dell' attesa e quindi il rimanente tempo di attesa è
inutilizzato (invece il test su BF, anche se più "laborioso",
fa terminare l' attesa al momento del rilascio di BF e non di un tempo
pre fissato).
|
Si può ovviamente trimmare le attese in funzione della risposta del display
usato, ma, come al solito, non si consiglia questo approccio, perchè troppo
aleatorio.
Comunque si tratta di tempi molto ridotti che solitamente non influiscono sulla
gestione del display, di per sè processo piuttosto lento.
Modifichiamo il driver
Ovviamente, nell' inizializzazione dei port, la linea RW scompare.
;**********************************************************
; LCDIoIni
; Inizializza i pin di controllo dell' LCD
;**********************************************************
LCDIoIni ; set I/O per LCD
bcf LCD_E
; EN pin clear
bcf LCD_RS
; RS pin clear
bcf LCD_Bckl
; Backlight pin clear (spento)
clrf LCDport
; data port clear
clrf LCDtris
; set bus come uscita
bcf LCD_Etris
; set linee di comando come uscite
bcf LCD_RStris
return |
Avendo già in mano un driver modulare, la modifica per l' uso senza la linea
RW è semplice: basta agire sulla routine che testa BF e sostituirla con la
temporizzazione richiesta. La routine di lettura non è più utilizzata.
Creiamo per prime due routines di tempo da 40 us e da 1.6 ms, genere
Delay16ms e Delay40us.
Quindi agiamo sul driver di scrittura. Qui occorrono due azioni diverse:
- selezionare se è stato inviato un dato o un comando
- selezionare se il comando inviato richiede attesa lunga o corta
Questo richiede di aggiungere un flag per "ricordare" alle routines
di cosa si sta trattando. Ci si può chiedere perchè, ma basta osservare che:
- i comandi con "tempo lungo" possono avere codici tra 01h e 03h
- i comandi con tempo corto vanno da 04h a FFh
- ma i dati possono avere qualsiasi valore tra 00he FFh
Di conseguenza modifichiamo LCDWrCmd - LCDWrDat
e inseriamo i ritardi.
Sostanzialmente, prima di rilasciare il controllo, le routine attendono il tempo
richiesto per l' esecuzione dell' istruzione inviata al controller del display.
La lunghezza del ritardo viene valutata automaticamente testando lo stato di RS
1= dato / 0=comando) e, se si tratta di un comando, viene verificato,
analizzando quanto inviato sul bus, se è un Clear o Clear&Home, con attesa
lunga, oppure uno degli altri comandi, con attesa breve.
;**********************************************************
; LCDWrCmd - LCDWrDat
; Trasmette un dato o un comando al display:
; Dato o comando sono in WREG.
;**********************************************************
; Trasmette un comando. Comando in WREG
LCDWrCmd:
bcf LCD_RSw
; RS=0 per comando
bra lcwr
; Trasmette un dato. Dato in WREG
LCDWrDat:
bsf LCD_RSw
; RS=1 per dati
lcwr movwf LCDportw ; byte sul PORT
rcall LCDclk
; clock E
; attesa fine esecuzione comando
btfsc LCD_RSr
; dato o comando ?
bra shtdly
; RS=1 - dato
; quale comando ?
movlw d'3'
; > 3 ?
cpfsgt LCDportr
rcall Delay1ms6
; si , attesa 1.560 ms
shtdly
rcall Delay40us
; attesa 40 us
; reset LCD bus e controlli
clrf LCDportw
; clear PORT
;bcf
LCD_RWw ; clear RW
bcf
LCD_RSw ; clear RS
return
|
Le routine non rilasciano il controllo al programma chiamante
fino all' esaurimento del tempo richiesto. Questo è necessario in quanto, non
potendo stabilire quante istruzioni saranno eseguite dal microcontroller,
occorre avere la certezza che il comando precedente sia completato prima
del prossimo invio sul bus del display.
Il resto della gestione è identico e identico all'
esercitazione precedente è anche il sorgente. Sono state aggiunte solo le
routines di tempo richieste.
Questo è da considerare con la dovuta attenzione: qui il driver sta cominciando
a rendere palesi i suoi vantaggi: il cambio della modalità di accesso al
display non influisce minimamente sul sorgente del programma utente; modifica
solamente le parti necessarie della gestione.
Dal programma utente saranno comunque chiamate le subroutines:
-
LCDWrCmd
-
LCDWrDat
-
LCDioini
-
LCDswini
-
LCDLine1
-
LCDLine2
Questi sono gli entry point del driver, identici al precedente, ovvero le funzioni che
possono essere richiamate dall' utente per svolgere una determinata funzione.
La modularità del driver sta nel poter essere configurato a seconda dell'
hardware e rispondere comunque alle stesse chiamate funzionali, senza che l'
utente debba preoccuparsi di come esso svolge le sue funzioni.
Ora proviamolo
sul campo.
Se si incontrano errori nella compilazione è opportuno verificarli con la
lista di descrizione degli errori e correggere dove si è sbagliato.
|