Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

22
voti

LO HAI MAI REALIZZATO CON UN PIC? - I PICMicro e i display LCD alfanumerici (parte 2)

Dopo aver visto, nel primo articolo di questa serie sugli LCD, le caratteristiche dei display alfanumerici attrezzati con il controller HD44780 di Hitachi, si prosegue con le modalità di interfacciamento e di comando.


Indice

La modalità a 4 bit

Il controller HD44780 permette l'interfacciamento tra LCD e microcontrollore con un databus a 4 bit oppure a 8 bit. Al fine di limitare il numero dei pin del microcontrollore impegnati sul comando del display, in questo articolo si è preferito adottare la modalità a 4 bit, secondo lo schema seguente.

Per poter comandare il display, è importante agire tanto sul databus quanto sui bit di controllo: E, RS, R/W. Il controller HD44780 necessita di una ben precisa sequenza di comandi e di dati, con tempistiche da rispettare "alla lettera", pena il mancato funzionamento del progetto. Il flow chart del setup è illustrato in figura.

Un estratto del codice C che esegue quanto indicato, è il seguente


void LCD_Init (void)
{
        char k;

        Delay_ms(5);

// Reset Sequence
        LCD_EN = 0;
        LCD_RS = 0;
        LCD_RW = 0;

        for (k=1;k<=3;k++)
        {
            LCD_DB4 = 1;
            LCD_DB5 = 1;
            LCD_DB6 = 0;
            LCD_DB7 = 0;

            LCD_EN_Strobe();

            Delay_ms(5);
        }
        PORTB = 0x00;

//Four bit mode

        LCD_DB4 = 0;
        LCD_DB5 = 1;
        LCD_DB6 = 0;
        LCD_DB7 = 0;

        LCD_EN_Strobe();

// 4-bit mode, 2 lines display, font 5x8 pixels

        LCD_SendCommand(0x28);


// Increment, no shift

        LCD_SendCommand(0x06);

// Display ON, Cursor OFF, Blink OFF

        LCD_SendCommand(0x0C);
        LCD_SendCommand(0x01);
        LCD_SendCommand(0x03);
      
}

Per inviare un comando al display, è necessario avere RS ed R/W entrambi a valore 0 ed inviare prima il nibble più basso e poi il nibble più alto. Ciascun invio deve essere seguito da uno strobe di E che deve eseguire la transizione basso-alto-basso.

I comandi

Il display accetta, oltre alla fase di inizializzazione, anche altri comandi; alcuni di essi deveono essere seguiti da un dato. Un comando e un parametro differiscono solamente per il fatto che quando si inviano comandi RS vale 0, invece quando si inviano dati RS vale 1.

// Sends command to LCD
void LCD_SendCommand(char Command)
{
        LCD_RS = 0;
        LCD_SendByte(Command);
}

// Sends data to LCD
void LCD_SendData(char Data)
{
        LCD_RS = 1;
        LCD_SendByte(Data);
}

I comandi che possono essere inviati al display sono riassunti in questa tabella.

I comandi che si possono impartire al display

I comandi che si possono impartire al display

Caratteri speciali programmabili

Ogni display ha a disposizione un set di caratteri piuttosto ampio. In figura è riportato un set tratto da un datasheet.

Set di caratteri display LCD

Set di caratteri display LCD

Ora, ciascun carattere rispecchia (quasi) interamente la tabella ASCII ma, come si può notare, sono disponibili anche caratteri non latini, alcuni simboli greci ed alcuni simboli che si rifanno ad alfabeti orientali. Il controller HD44780 permette la memorizzazione di alcuni caratteri definiti dall'utente, fino ad un massimo di 8 caratteri. Il gioco è piuttosto semplice: si parte da una matrica 5x8 pixel (questa è la dimensione "classica" di un carattere);


A questo punto si inizia ad oscurare ciascun pixel dando forma al carattere che vogliamo. Nell'esempio che segue è riportato un ombrellino


Per ogni riga, si calcola il valore che emerge dalla colorazione dei pixel, secondo un semplice calcolo in potenza di 2, considerando il pixel meno significativo quello a destra. In questo modo è possibile costruirsi caratteri e simboli altrimenti non disponibili.

Le memorizzazione dei caratteri speciali avviene scrivendoli in un'area della memoria RAM del display, a partire dall'indirizo 0x40, infatti, ha sede la CGRAM, Charachter Generator RAM. Un comando di scrittura all'indirizzo desiderato, seguito dagli otto byte che costituiscono il carattere. Uno stralcio di codice è il seguente:

void LCD_PutCGRAMCharPos (char* GraphicChar, char DisplayPosition)
{
    char count;

    LCD_SendCommand (0x40+8*DisplayPosition);
    for (count = 0; count<=7; count++)
    {
        LCD_PutChar(GraphicChar[count]);
    }
}

Benché 8 caratteri possono sembrare pochi, questo vincolo non deve scoraggiare e può essere abilmente aggirato, avendo cura di raggruppare insiemi di 8 caratteri in modo omogeneo. Nel video che segue è mostrato come, oltre ai caratteri già disponibili si possano disegnare e rappresentare simboli diversi, molto più che 8.

Ho voluto preparare una semplice applicazione per OpenOffice Calc, grazie alla quale è possibile creare i caratteri custom e poi utilizzarli nel proprio codice. L'applicazione calcola automaticamente i valori dei byte da inviare alla CGRAM del display.

Applicazione OpenOffice Calc per i simboli personalizzati

Applicazione OpenOffice Calc per i simboli personalizzati

Ed ecco alcune immagini che ho realizzato:

Simboli personalizzati (1)

Simboli personalizzati (1)


Simboli personalizzati (2)

Simboli personalizzati (2)


Simboli personalizzati (3)

Simboli personalizzati (3)


Un microcontrollore PIC "stilizzato"

Un microcontrollore PIC "stilizzato"


Il teschio dei pirati

Il teschio dei pirati

Firmware

Il codice per pilotare il display l'ho scritto in linguaggio C. Si sa, il C è portabile e questo aspetto è fondamentale quando si vuole compilare il progetto con compilatori diversi oppure "portarlo" su altre piattaforme hardware. Avrei potuto utilizzare un PIC18 ed usare C18, ma dato che i PIC16 sono ancora molto richiesti, ho preferito utilizzare SDCC, stavolta "mettendolo alla prova" con un compito più significativo che non quello semplice di accendere un LED. Ecco uno stralcio delle funzioni che ho implementato:

extern void LCD_Init (void);
extern void LCD_GotoXY (unsigned char, unsigned char);
extern void LCD_PutCharXY (unsigned char, unsigned char, unsigned char);
extern void LCD_PutChar (unsigned char);
extern void LCD_PutStringXY (unsigned char, unsigned char, char* );
extern void LCD_PutString (char*);
extern void LCD_EN_Strobe (void);
extern void LCD_SendCommand(char);
extern void LCD_SendData(char);
extern void LCD_SendByte (char);
extern unsigned char LCD_read_byte (void);
extern void LCD_PutCGRAMCharPos (char*, char );
extern void LCD_Clear (void);
extern void nop (void);
extern void Delay_ms (unsigned int);

The "pirate display"

Ed ecco qui, il risultato di quanto illustrato in questi due articoli. La demo mostra l'utilizzo del display con un PIC16F876A, qualche carattere personalizzato e...

File download

Il codice è scaricabile dal mio sito PICexperience, al seguente link. Il pacchetto zip contiene i seguenti file:

  • DemoLCD.c: il firmware che si vede in esecuzione nel video;
  • LCD.c: funzioni di gestione LCD;
  • LCD.h: file di include che contiene i prototipi di funzione;
  • Make.bat: file da lanciare su sistemi MS-Windows per compilare con SDCC il firmware;
  • CustomChar_LCDDisplay.ods: applicazione OpenOffice Calc per la determinazione dei simboli personalizzati.

Licenza

Questo articolo ed il software rilasciato rientrano nell'ambito della licenza CREATIVE COMMONS BY-NC-ND 3.0, secondo quanto indicato nelle note legali qui riportate.

Licenza Creative Commons

Licenza Creative Commons

Sintesi delle note legali (italiano)

Note legali (italiano)

Legal code (international)

Commons deed (international)


Bibliografia

Pillole di Microcontrollori PIC

Pillole di Microcontrollori PIC

12

Commenti e note

Inserisci un commento

di ,

Grazie desk7 per la segnalazione del refuso.

Rispondi

di ,

Grazie mille per la guida! Volevo segnalare un errore nella formula della seconda riga del 4 carattere: la formula è B14*16+C14*8+D14*4+E14*2+F14 e non B14*14+C14*8+D14*4+E14*2+F14

Rispondi

di ,

È un rischio che si corre purtroppo...

Rispondi

di ,

Io la sequenza giusta dell'inizializzazione del display l'ho trovata nel datasheet del controller HD4480, come tante altre cose, perchè tutti i datasheet cinesi che ho consultato erano bacati.

Rispondi

di ,

Grazie a questa guida ho capito che l'inizializzazione per istruzioni, nel datasheet ufficiale, era sbagliata! (c'era una sequenza in meno) Dovrei imparare a cercare le errate...

Rispondi

di ,

Grazie, davidde! Sei molto gentile. Lieto di averti dato un aiuto. Ok per la svista: non me ne ero proprio accorto!

Rispondi

di ,

Oggi di prima mattina e con poca fiducia ero partito per l'impresa di scrivere qualcosa su uno di questi display; pensavo alla classica settimana di delirio. Invece grazie a te neanche a mezzogiorno avevo finito... Articolo dettagliato e chiaro come nel tuo stile! Sei un grande! Ciao e grazie!!! P.S. Una svista banale ma ormai te la dico, nel disegno dell'ombrello la sequenza dovrebbe essere: 4,14,31,4,4,4,5,2 mi sa che hai lasciato indietro un uno alla seconda riga.

Rispondi

di ,

Grazie mir!

Rispondi

di ,

Non vorrei essere ripetitivo Paolino, ma......Complimenti gran bel lavoro.

Rispondi

di ,

@DADO91 - Grazie per i complimenti, Con la funzione "LCD_SendCommand(0x28);" il valore 0x28 è, in binario, 101000, il che vuol dire che DL (DataLength) è pari a 0 (mod. 4 bit), N = 1 cioè il numero di righe è maggiore di 1 e F = 0, la scelta del font 5x8. Grazie per il refuso: l'ho corretto. Prova a scaricare l'intero codice. @carlomariamanenti - Grazie, Carlo. :-)

Rispondi

di ,

Bravo Paolino!

Rispondi

di ,

Complimenti per l'articolo!! A breve volevo fare alcune prove anch'io con un LCD e dei PIC e sicuramente seguirò i tuoi ottimi articoli. Volevo chiederti una cosa, non ho ben capito l'ultima parte del diagramma a blocchi per l'inizializzazione degli LCD, precisamente dove si specifica il font e il numero delle righe, in pratica non ho capito come si struttura quell'ultima parte di comunicazione (per es. su quanti bit viene inviato il numero di righe?). P.S. Ti segnalo anche una svista, il link al datasheet del PIC, non funziona perchè ti è rimasto un * in fondo al link. Grazie!

Rispondi

Inserisci un commento

Per inserire commenti è necessario iscriversi ad ElectroYou. Se sei già iscritto, effettua il login.