|
|
|
![]() |
Lezione 4
In questa pagina è presente un altra routine di gestione LCD più completa della precedente e realizzata da Nicola
|
|
|
|
|
Dopo la lezione sulla gestione semplice degli LCD, probabilmente molti utenti di questo sito vorranno approfondire l'argomento LCD. Nicola, altro utente del sito, si è preso la briga di mettere a punto una routine particolarmente completa e corposa, tanto che gli ho fatto i miei complimenti per la pazienza e lo devo ringraziare per aver messo a disposizione di tutti, il suo lavoro su questo sito.
|
|
Usi avanzati dell'LCD
In altra parte del sito, ho descritto un modulo per collegare gli LCD alle mie demoboard ed ho anche illustrato un semplice programma che utilizza la routine del Andrea.
Però avevo detto da subito che il modulo presentato poteva gestire i display in modalità 4 bit e in sola scrittura, senza sfruttare a fondo tutte le caratteristiche che i display con controller Hitachi hanno.
Questa pagina è dedicata a coloro che vogliano sfruttare i display anche in lettura, a 4 e a 8 bit.
Allo scopo, segnalo anche un link di un noto sito in inglese che sembra essere diventato un punto di riferimento per tutti gli aspiranti utilizzatori di LCD: http://home.iae.nl/users/pouweha/lcd/lcd.shtml
Riporto uno scorcio di mail che ho ricevuto da Nicola che ne descrive il funzionamento (così mi risparmio la fatica di copiare il testo).
Per le prove ho sviluppato in C (prendendo spunto da vari esempi sulla rete) una libreria abbastanza completa sulla gestione degli LCD.
La libreria permette, oltre a scrivere, anche di leggere caratteri dalla RAM e la posizione del cursore; inoltre si possono usare entrambe le modalità 4 e 8 bit.
Le porte di connessione non sono prestabilite; le linee RS, R/W ed EN possono essere connessi a qualsiasi pin; mentre le linee dati (D0-D7) hanno soltanto il vincolo di appartenere alla stessa porta (B, C, D, ecc).
Purtroppo non ho potuto testare il programma completamente per mancanza di altri pic oltre al 16F84A.
Fatto questo vado avanti.
La routine di Nicola è composta da due moduli, lcd.c e lcd.h .
Li ho compressi in un unico file che potete scaricare qui:
Routine_LCD.zip
Lo dovete scompattare e mettere entrambi nella cartella include del vostro compilatore.
Comandi per l'LCD
LcdInit(char, char, char) ---------> Inizializza LCD - chiamare prima di ogni cosa
LcdBusy(void) --------->Attende la fine dell'ultima operazione
LcdCommand(char) ----------> Scrive un comando
LcdClear(void) ------------------> Invia comando Clear & Home
LcdWrite(char, char) ------------> Scrive un byte unsigned nella DD RAM
LcdPutch(char) ----------------->Scrive un carattere nella posizione del cursore
LcdPuts(char *) -----------------> Scrive una stringa di caratteri
LcdRead(char)------------------>Legge un byte unsigned dalla DD RAM
LcdGetch(char) ----------------> Legge il carattere nella posizione attuale cursore
LcdSetCurs(char, char) ---------> Imposta il cursore a riga, colonna
LcdGetCurs (char, char) -------->Ritorna la riga, colonna attuale del cursore
LcdPulse(void) ----------------> Invia un impulso di Enable
int2ascii(int, char) -------------> Converte un intero in striga ASCII
Il programma di esempio
// --------------------------------------------------------------------------------------
// File: TLcd.c -
// Autore: Nicola Sellitto snico_one@yahoo.it -
// Versione: 1.2 -
// Data: 28 Marzo 2003 -
// Descrizione: Esempio di utilizzo display LCD tipo Hitachi HD44780 -
// Valorizzare opportunamente i parametri del LCD -
// LCD_ROWS numero di righe -
// LCD_COLS numero di colonne -
// LCD_BUS modalità 4/8 bit -
// LCD_RS pin per Register selector -
// LCD_RW pin per Read/Write -
// LCD_EN pin per Enable -
// LCD_TRIS_RS tris per Register selector -
// LCD_TRIS_RW tris per Read/Write -
// LCD_TRIS_EN tris per Enable -
// LCD_PORT_DATA pin porta per Data -
// LCD_TRIS_DATA tris per Data -
// presenti in lcd.h in modo da adattarlo alle caratteristiche del -
// singolo lcd. -
// Modificare la LcdInit con i parametri della propria configurazione. -
// Verifiche: Prove eseguite su LCD 2x16 -
// Note: Vedere lcd.c per le routine di gestione lcd -
// --------------------------------------------------------------------------------------
#include <pic.h>
#include "..\hi-tech\delay\delay.h"
#include "..\lcd\lcd.h"__CONFIG (WDTDIS & XT & PWRTEN & UNPROTECT);
main(void) {
byte i;
char c;
char row;
char col;
TRISA = 0x00; // Imposta linee PortA come output
PORTB = 0x00; // Azzera linee PortB
LcdInit(LCD_FONT_5x7,
LCD_CURSORMODE_NEXT,
LCD_DISPLAY_ON | LCD_CURSOR_ON | LCD_BLINK_OFF);
// Ritardo iniziale
for (i=0; i<4; i++) DelayMs(250);
// 1. Prova scrittura e lettura caratteri
LcdPuts("ABCDEFGHILMNOPQR");
for (i=0; i<16; i++) {
LcdSetCurs(1,16-i);
c = LcdGetch();
LcdSetCurs(2,i+1);
LcdPutch(c);
}
// Attesa di 1 secondi
for (i=0; i<4; i++) DelayMs(250);
// 2. Prova lettura cursore
LcdClear();
LcdSetCurs(2,5);
LcdPutch('X');
LcdGetCurs(&row, &col);
LcdPuts(int2ascii(row, 0));
LcdPuts(int2ascii(col, 1));
// Attesa di 2 secondi
for (i=0; i<8; i++) DelayMs(250);
// 3. Prova scrittura
LcdSetCurs(1,4);
LcdPuts("Wellcome ");
DelayMs(250);
DelayMs(250);
LcdSetCurs(2,1);
LcdPuts("Testin ");
LcdSetCurs(1,13);
DelayMs(250);
LcdPutch('!');
DelayMs(250);
LcdPutch('!');
DelayMs(250);
LcdSetCurs(2,9);
LcdPuts("LCD");
DelayMs(250);
for (i=0; i<5; i++) {
LcdPutch('.');
DelayMs(250);
}
LcdSetCurs(2,1);
LcdPuts("Test LCD passed ");
DelayMs(250);
DelayMs(250);
// 4. Prova scroll orizzontale controllato da hardware
LcdClear();
LcdPuts("Scroll hardware");
// Attesa di 1 secondi
for (i=0; i<4; i++) DelayMs(250);
for (i=0; i<15; i++) {
DelayMs(150);
LcdCommand(LCD_DISPLAY_SHIFT | LCD_SHIFT_LEFT);
}
/*
// 5. Prova scroll orizzontale controllato da software
// Questa parte del codice è commentata per mancanza di spazio ROM
// sul pic 16F84 limitata ad 1 KWord
static char msg[] = "Scroll testo orizzontale";
static byte msglen = 24; // Lunghezza messaggio
byte msgindx; // Indice messaggio
byte lcdpos; // Posizione lcd
byte tot1;
byte tot2;
byte tot;
LcdClear();
LcdPuts("Scroll software ");
DelayMs(250);
DelayMs(250);
DelayMs(250);
LcdClear();
lcdpos = LCD_COLS; // posizione lcd di inizio scrittura
msgindx = 1; // indice stringa da scrivere
while (lcdpos > 0) {
tot1 = LCD_COLS - lcdpos + 1; // numero caratteri che si possono scrivere
tot2 = msglen - msgindx + 1; // numero caratteri che si vuole scrivere
if (tot2 > tot1) tot = tot1;
else tot = tot2;
LcdSetCurs(1, lcdpos);
for (i=0; i<tot; i++) LcdPutch(msg[msgindx+i-1]); // scrittura caratteri
if (lcdpos > 1)
lcdpos --; // spostamento posizione lcd a sinistra
else { // siamo con lcdpos=1
msgindx ++; // spostamento indice msg a destra
if (msgindx > msglen) lcdpos = 0;
}
tot = LCD_COLS - (msglen - msgindx + 1);
for (i=0; i<tot; i++) LcdPutch(' ');
DelayMs(250);
}
}
Davvero devo fare i complimenti a Nicola e lo ringrazio di nuovo per la sua collaborazione al sito.
Spero con questo di aver risolto in modo esauriente tutte le vostre necessità di gestione di lcd.
|