Controllare un LCD alfanumerico con interfaccia I2C

I display LCD alfanumerici rappresentano un'ottima interfaccia grafica per mezzo della quale rappresentare dei dati di uscita o semplicemente visualizzare delle informazioni in un formato direttamente leggibile dall'utente. Sebbene questa soluzione introduca dei costi maggiori rispetto ad una semplice visualizzazione d'informazione ottenuta con semplici LED, spesso non ci sono alternative. Unico inconveniente di questa interfaccia è, oltre all'aspetto economico, il numero elevato di linee necessarie per controllarla. Per superare questo limite si possono usare display alfanumerici con interfaccia SPI o I2C riducendo il numero di linee di controllo da circa 8 a solo 2-3 linee. Questa soluzione aggiunge però un ulteriore problema, ovvero la difficile reperibilità dei moduli LCD e costi ancora maggiori! In questo articolo si introdurrà una soluzione intermedia composta da un normale LCD abbinato ad un PCF8574 (I2C I/O expander).

 

Analisi del progetto

Come detto la soluzione proposta consiste semplicemente nell'utilizzare un LCD alfanumerico standard (interfaccia parallela) e un PCF8574, I/O expander controllato via I2C. Il progetto non è molto complicato qualora si sia utilizzato già un modulo LCD. Prima di procedere oltre, vi consiglio di leggere il Capitolo dedicato ai moduli LCD del testo “C18 Step by Step”, e la Brief Note BN0013 dedicata all'integrato PCF8574. Detto questo, vi considero esperti di moduli LCD, per cui passo subito alla descrizione dello schema elettrico di Figura 1.

Figura 1: Schema elettrico per il collegamento di un modulo LCD a un PCF8574.

Figura 1: Schema elettrico per il collegamento di un modulo LCD a un PCF8574.

Si noti subito che il PCF8574, avendo solo 8 linee, richiede che il display sia comandato in modalità a 4bit. Le linee di controllo del display sono anche collegate direttamente all'integrato PCF8574 per cui l'intero modulo LDC può essere comandato via I2C. Oltre ai collegamenti del modulo LCD sono presenti diversi componenti, alcuni dei quali sono presenti poiché il modulo LCD modificato con interfaccia I2C è stato pensato per poter essere posizionato ad una certa distanza dal microcontrollore che lo controlla (10cm-20cm).

Vediamo in dettaglio la ragione di ogni componente:
 

Componente C1

Il condensatore C1, di tipo ceramico, deve essere collegato nelle vicinanze del PCF8574 e rappresenta un condensatore di disaccoppiamento che permette di ridurre il rischio di malfunzionamento dell'integrato a causa di rumore sulla linea di alimentazione.
 

Componente C2

La presenza del condensatore C2 di tipo elettrolitico discende dal fatto che il modulo LCD potrebbe essere posizionato ad una certa distanza dal microcontrollore, ovvero dalla scheda dove è presente anche l'alimentatore. Il condensatore limita il rumore sulle linee di alimentazioni del modulo stesso a causa dell'attività del modulo LCD (in particolare accensione dei LED di retroilluminazione)  ovvero di repentine richieste di corrente. Si ricorda infatti che le linee di collegamento tra il modulo LCD e il sistema principale rappresentano degli induttori a tutti gli effetti, per cui rendono difficili rapidi rifornimenti di energia dalla scheda principale al modulo LCD. La presenza del condensatore C2 rappresenta una scorta di energia che compensa i rallentamenti di approvvigionamento energetico legati alle lunghe linee di alimentazione.
 

Componente SW1

La presenza del dip switch SW1 discende dal fatto che il PCF8574 possiede un indirizzo selezionabile dall'utente. Probabilmente se si sta usando un'interfaccia I2C vuol dire che non si hanno molti pin a disposizione sul microcontrollore, non è dunque improbabile che sul bus I2C sia anche presente un secondo PCF8574. Per tale ragione è necessario avere premura che i due o più PCF8574 abbiano un indirizzo differente.  

Componenti R1, R2, R3
Al fine di garantire che gli interruttori nello SW1 funzionino correttamente e possano selezionare sia il livello 0 che 1 sono presenti i resistori di Pull-down. In particolare un interruttore posto su ON vale 1 mentre un interruttore aperto vale 0. Usando dei resistori di pull-up si avrebbe la situazione inversa. I tre switch danno la possibilità di avere sullo stesso bus fino ad 8 PCF8574 (senza considerare altri 8 se si dovessero usare i PCF8574A).  
 

Componenti R4

Il resistore R4 rappresenta il resistore di pull-up sulla linea delle interruzioni (la linea INT è un open drain). In particolare può essere sia inserita che disinserita. La possibilità di disinserirla discende dal fatto che tale resistore potrebbe essere già presente su altre schede, per cui, se già presente è possibile eliminarlo.
 

Componenti R5, R6

Tali resistori rappresentano i resistori di pull-up necessari per il bus I2C. Allo stesso modo di R4 potrebbero essere già presenti sulla scheda principale del sistema, visto che il bus I2C potrebbe essere condiviso tra più periferiche. Qualora siano già presenti sulla scheda principale, i resistori R5 e R6 devono essere eliminati per evitare che vadano in parallelo con quelli presenti sul sistema (valori troppo bassi sul bus I2C potrebbero causare problemi di comunicazione).
 

Componenti R7, R8,10

Questi resistori da 120ohm hanno lo scopo di limitare la rapidità con cui variano i fronti di salita dei segnali digitali (formano un filtro passa basso con le capacità parassite). Questo è importante vista la lunghezza delle linee di sistema che comportandosi come induttori, potrebbero anche causare extratensioni tali da danneggiare il sistema. Un'altra importante ragione per cui si utilizzano resistori in serie alle linee di trasmissione è per limitare le radiazioni di sistema e il cross-talk tra le linee stesse. Non avendo fatto alcuna misura reale sul sistema, tali valori non sono ottimizzati.
 

Componenti R9

La resistenza di base di TR1 è necessaria per garantire una corretta polarizzazione del transistor ed evitare che la giunzione Base-Emettitore sia direttamente pilotata dal PCF8574.
 

Componenti TR1

Il transistor TR1 rappresenta un buffer di corrente per l'uscita del PCF8574 che non riesce direttamente a pilotare la retroilluminazione del display, che può infatti richiedere correnti di diverse decine di mA (100mA non sono inusuali). Si noti che il transistor è di tipo PNP per cui il display risulta attivato ponendo a 0 l'uscita del PCF8574 e non ponendola ad 1 come sarebbe stato necessario con un NPN. Sebbene la logica faccia propendere ad utilizzare per transistor NPN questo non è possibile vista la ridotta corrente erogabile dal PCF8574 a meno di non utilizzare transistor NPN ad elevato guadagno (si veda la Brief Note BN0013 per maggiori dettagli).
 

Componenti RV1

Il trimmer RV1 permette di regolare il contrasto del display al fine di ottimizzare la lettura dei caratteri visualizzati.
 

Componenti J4

Il connettore J4 ha molti più pin del necessario vista la presenza di numerose linee di GND. Questo  è stato fatto al fine di schermare le linee dati nei confronti di disturbi esterni ma anche per limitare il cross-talk (disturbo tra le linee stesse).
 

La Libreria Software


Una volta realizzato il nostro hardware, al fine di poter scrivere effettivamente sul display è necessario fornirsi di una libreria ad hoc. Dal momento che le librerie LaurTec per PIC18 supportano già il display con controller Hitachi H44780 e il PCF8574, ho praticamente fuso le due librerie e realizzato la nuova libreria LCD_44780_I2C. Si capisce dunque che la libreria che viene ora presentata  è per PIC18 ed è scritta in C18.

Per poter fondere le due librerie ho creato due nuovi file .h e .c praticamente identici alla vecchia libreria LCD_44780. Partendo da questa non ho dovuto cambiare tutta la libreria ma semplicemente la parte relativa alla generazione dell'impulso, all'invio dei dati e inizializzazione, mantenendo il nome delle funzioni inalterato. Questo significa che tutti i programmi scritti facendo uso della libreria LCD_44780 funzioneranno anche con la libreria LCD_44780_I2C. Unico prerequisito richiesto per la libreria LCD_44780_I2C è la necessità di inizializzare il modulo I2C a 100KHz prima di poter usare la libreria stessa.

Dal momento che alcuni valori costanti usati nelle due librerie differiscono tra loro ho inserito delle nuove costanti. Per esempio TURN_ON è stata eliminata e sostituita con TURN_ON_LED e TURN_ON_CURSOR. Cosa analoga per la variabile TURN_OFF. Le costanti dichiarate all'interno del file header sono:

#define LEFT             0b00000000
#define RIGHT            0b00000100
#define TURN_ON_CURSOR   0b00000010
#define TURN_OFF_CURSOR  0b00000000
#define TURN_ON_LED      0b00000000
#define TURN_OFF_LED     0b10000000
#define BLINK_ON         0b00000001
#define BLINK_OFF        0b00000000


Per mantenere la compatibilità tra la libreria LCD_44780_I2C e la libreria LCD_44780 anche quest'ultima è stata aggiornata nella libreria LaurTec Versione 2.3. Per portare un codice da una libreria ad un'altra, bisogna far uso di queste nuove costanti e non usare più TURN_ON o TURN_OFF.

Le costanti:

#define LCD_D0  0b00000001
#define LCD_D1  0b00000010
#define LCD_D2  0b00000100      
#define LCD_D3  0b00001000      
#define LCD_E   0b00010000      
#define LCD_RW  0b00100000
#define LCD_RS  0b01000000      
#define LCD_LED 0b10000000

Presenti per rendere chiaro il codice, non è necessario ridefinirle come poteva essere fatto nella libreria LCD_44780, infatti il collegamento con il PCF8574 i collegati sono predefiniti come visualizzato nello schema di Figura 1. Nella libreria LCD_44780 si poteva avere l'esigenza di ridefinire le costanti in base ai pin utilizzati.

Come visto dallo schema elettrico è possibile impostare l'indirizzo della scheda. Questo deve essere fatto nella libreria per mezzo della costante

#define PCF8574_ADDRESS_L 0x00

Sebbene l'indirizzo sia facilmente selezionabile durante l'esecuzione del programma, ho preferito non supportare tale funzione e imporre l'indirizzo a tempo di compilazione in modo da avere la compatibilità tra la libreria LCD_44780_I2C e LCD_44780.

Oltre a questa costante, dal momento che  è possibile usare sia un PCF8574 che un PCF8574A,  ho  definito l'altra costante che va impostata in base al modello del PCF8574 utilizzato. In particolare se si usa un normale PCF8574 bisogna fare questa definizione:

//PCF8574
#define PCF8574_ADDRESS_H 0x40


//PCF8574A
//#define PCF8574_ADDRESS_H 0x70


mentre se si usa il PCF8574A si deve commentare il primo #define e togliere il commento sul secondo:

//PCF8574
//#define PCF8574_ADDRESS_H 0x40


//PCF8574A
#define PCF8574_ADDRESS_H 0x70
 

Esempio di utilizzo della Libreria LCD via I2C


Un semplice esempio di utilizzo della libreria è riportato di seguito (il quarzo utilizzato  è di 20MHz). Si noti che per utilizzare la libreria  deve essere incluso sia il file .h che il file .c. in particolare si includono anche le librerie PCF8574.c e delay.c (i file header non sono inclusi poiché già inclusi nel file file LCD_44780_I2C.h).  Si ricorda che includere due volte un file header non  è in generale un problema mentre due file .c creano errori di doppia dichiarazione di variabili e funzioni.

#include <p18f4550.h>
#include "LCD_44780_I2C.h"
#include "LCD_44780_I2C.c"
#include "PCF8574.c"
#include "delay.c"


#pragma config FOSC = HS        
#pragma config WDT = OFF        
#pragma config LVP = OFF        
#pragma config PBADEN = OFF


//OSC = HS      Impostato per lavorare ad alta frequenza
//WDT = OFF     Disabilito il watchdog timer
//LVP = OFF     Disabilito programmazione LVP
//PBADEN = OFF Disabilito gli ingressi analogici


void main (void){


// Imposto PORTA tutti ingressi
LATA = 0x00;
TRISA = 0xFF;
// Imposto PORTB tutti ingressi
LATB = 0x00;
TRISB = 0xFF;
// Imposto PORTC tutti ingressi
LATC = 0x00;             
TRISC = 0xFF;

// Imposto PORTD tutti ingressi

LATD = 0x00;  
TRISD = 0xFF;
// Imposto PORTE tutti ingressi
LATE = 0x00;
TRISE = 0xFF;

// Inizializza il modulo I2C a 100KHz @20MHz

OpenI2C(MASTER, SLEW_OFF);
SSPADD = 49;


// Inizializzo il display LCD con quarzo a 20MHz
OpenLCD (20);

BacklightLCD (TURN_ON_LED);

WriteStringLCD ("  Hello World");


// Ciclo infinito
while (1) {             

}

}

Eseguendo il programma di esempio sulla scheda di sviluppo Freedom II e montando lo schema elettrico di Figura 1 su una scheda di espansione PJ7011 con scheda millefori, si ottiene il risultato voluto!

Figura 2:  Esecuzione del programma di esempio su Freedom II con espansione PJ7011.

Figura 2: Esecuzione del programma di esempio su Freedom II con espansione PJ7011.

Esempio e realizzazione di una scheda

Un esempio di una scheda che utilizza il progetto presentato è riportato nel file ZIP di progetto (vedi sotto). Il file include il PCB e l'immagine per il montaggio dei componenti.
 

Ringraziamenti

Si ringrazia l'utente Pinna per aver collaborato nella fase di Test della libreria e aver realizzato praticamente lo sbroglio del circuito ovvero il PCB del progetto stesso.
 

Bibliografia:

1 : PCF8574: Datasheet Texas Instrument

 

Tipo File Scarica File Descrizione

Formato File zip

Download

Esempio di utilizzo della Libreria

Formato File zip

Download Esempio Scheda LCD e PCB

Formato File zip

Download Libreria C18 LCD_44780_I2C

 

 

 

 

 

 

 

 

 

 

 

 

 

 


You don`t have permission to comment here!