Molti utenti lamentano il fatto che le routine di gestione degli LCD basati sui controller HD44780 e compatibili, spesso non funzionano. Abbiamo già visto che il problema deriva soprattutto dalla fase di inizializzazione. Capita difatti che, seppure i vari tipi di controller siano compatibili tra loro, potrebbero avere delle “tempistiche” differenti per cui ecco che il codice scritto per un modello non funziona su un altro a patto di piccole modifiche.
La libreria in oggetto apporta una modifica a quella che abbiamo trovato nella lezione 7 del corso di programmazione. Illustro brevemente la modifica effettuata: siamo abituati a tenere il pin R/W del display a massa, utilizzando quindi il display in sola lettura. Sfruttando anche questa linea di comunicazione è possibile leggere lo “stato” del display ovvero il flag Busy che ci permette di sapere se il display è ancora impegnato nelle sue operazione o è pronto a ricevere dati/comandi.
Per poter utilizzare il display anche in lettura è necessario, oltre a collegare anche il pin R/W ad un IO del picmicro, gestire anche le linee dati per poter essere configurate come ingressi anzichè come uscite: portando il pin R/W a livello alto, il display restituisce lo stato sulla linea dati D7, nelle funzioni di scrittura possiamo quindi rimanere in attesa fino al momento in cui il display si libera.
La libreria aggiornata fa tutto da sè, l’unica modifica circuitale necessaria è quella di collegare anche il pin R/W del display ad un IO del picmicro. Per evitare problemi sui PIC16 è conveniente collegare tutte le linee dati ai pin di un solo banco di porte.
Download
| Libreria LCD con controllo del flag Busy (3.68 kB - 206 downloads) |
Articoli che potrebbero interessarti
Se desiderate che SettoreZero continui a rimanere gratuito e fruibile da tutti, non copiate il nostro materiale e segnalateci se qualcuno lo fa.

Questo sito e tutto il suo contenuto sono distribuiti sotto la licenza










#1 da gcupini il 28 dicembre 2011
Grazie per i lavori preziosi che compationo nel forum.
Questo suggerimento mi sembra molto utile per realizzare una libreria LCD che funzioni per diverse classi di PIC.
Saluti e buon lavoro
#2 da prinaldi il 4 gennaio 2012
Una piccola precisazione vorerei sapere che compilatore hai usato (presumo Hitec ma vorrei la conferma).
grazie per il bel lavoro.
Pierluigi
#3 da Giovanni Bernardo il 4 gennaio 2012
Si
#4 da FritzBeast il 5 gennaio 2012
Ciao. complimenti per la libreria, hai risolto un bel problema! Pensi che si possa adattare ad un dsPIC30? Il mio tentativo è fallito miseramente…e non so perchè. (premetto che ho cambiato i delay in modo da usare la libreria dei dsPIC e i vari RBx in _RBx).
grazie. saluti.
Alessandro
#5 da Giovanni Bernardo il 5 gennaio 2012
Ovvio che si può adattare…
#6 da FritzBeast il 5 gennaio 2012
lo immaginavo, però…ho sbagliato qualcosa!
le modifiche che ho fatto sono le seguenti:
//aggiunto underscore (per ogni define)
#define LCD_D4 _RF4
#define LCD_D4_TRIS _TRISF4
//modificati i “bit” in “int” della funzione busy (al C30 bit non piace…)
int LCD_BUSY (void)
{
static int busyFlag;
static int tempRS;
(il resto della funzione non l’ho toccato)
Il file main non credo di averlo toppato…comunque lo scrivo.
//dichiarazione frequenza ciclo istruzioni =Fck/4
#define FCY 20000000UL
#include //libreria pic
#include //libreria funzioni
#include “settings.h” //file settings pic
#include “lcd_busy.h” //libreria display
void settings(void);
int main(void){
settings();
LCD_INIT(); //inizializza display
LCD_PUTS(“prova”);
while(1){
__delay_ms(500);
LCD_PUTCH(‘x’);
}
return 0;
}
può essere qualche periferica sulla portra F a “disturbare”?
ringrazio anticipatamente
#7 da Giovanni Bernardo il 5 gennaio 2012
Le uniche periferiche che possono disturbare sono gli ingressi analogici, che hanno la precedenza sui digitali. Se sulla porta F del tuo dsPic ci sono ingressi analogici, disattivali.
#8 da FritzBeast il 5 gennaio 2012
gli analogici sono tutti sulla porta B…non ho più idee!
usare LAT invece di PORT per le letture può aiutare?
#9 da Gabriel Rapetti il 5 gennaio 2012
Ciao, sono l’autore dell’articolo. Ho guardato il tuo codice. Oltre alle variabili interne busyFlag e tempRS hai cambiato a INT anche la funzione LCD_BUSY (void)?
Poi, nel mio main io posiziono prima il cursore.
Trascrivo una parte del mio codice de test. Spero che tu possa trovare la soluzione.
//——————————————————————–
// Settings
//——————————————————————–
void settings(void)
{
ANSEL = 0b00000000; // Set all digital input
TRISA = TrisMapA; // Set In / Out (Tris) PORT A
TRISB = TrisMapB; // Set In / Out (Tris) PORT B
CMCON = 7; // Comparator Module OFF
ADCON0 = 0b10000000; // Programming ADC Module OFF
OPTION_REG = 0b11000011;
INTCON = 0b00000000;
PORTA = 0;
PORTB = 0;
}
// ————————————————————————–
// Main
// ————————————————————————–
void main(void)
{
settings();
LCD_INIT();
LCD_LAMP = 1;
DelayMs(100);
LCD_CLEAR();
LCD_GOTO(1,1);
LCD_PUTS(“Test del Display”);
LCD_GOTO(2,1);
LCD_PUTS(“con lcd.c modificata”);
while(1)
{
}
}
#10 da FritzBeast il 5 gennaio 2012
si, ho messo int LCD_BUSY (void)
impostando il cursore visibile ho notato che riesco a spostarlo come desidero, ma quando uso PUTCH o PUTS o PUTUN il cursore “salta” ma non scrive nulla!
ora controllo che non ci sia qualche falso contatto in giro (in caso di esito positivo vinco un premio demenza, ma almeno avrò risolto)
#11 da FritzBeast il 6 gennaio 2012
ho risolto! ho avuto l’illuminazione quando mi stavo chiedendo il perchè lo stesso display, con la stessa libreria (e gli stessi ritardi) su un altro tipo di pic non andava bene; mi sono risposto che il dsPIC è un razzo confronto all’altro e quindi ho presupposto che leggeva/scriveva/impostava le porte troppo velocemente per far si che il driver del display riuscisse a leggerle. Morale della favola: con l’aggiunta di 3 ritardi (due da 1us e uno da 8us) ho finalmente risolto!
Vi ringrazio comunque per gli aiuti che mi avete dato e la vostra disponibilità!
Se siete interessati alle modifiche non ho problemi a postarvele.
saluti
#12 da rossotony88 il 13 gennaio 2012
ciao, senti è possibile utilizzare un diisplay di un cellulare a come display di un progetto.. se si, cm faccio?
#13 da Giovanni Bernardo il 13 gennaio 2012
1) si, anche se non sempre è conveniente farlo
2) cerchi informazioni su internet per capire che tipo di controller monta quel display, ti leggi il datasheet. Magari in giro c’è pure una libreria già fatta.
#14 da rossotony88 il 14 gennaio 2012
beh io avevo intenzione di utilizzare lo schermo di un nokia n70, però non ho ben chiaro il funzionamento di questi display..
#15 da OrazioBellassai il 26 gennaio 2012
Ciao a tutti :) Scrivo qui perchè non riesco a fare funzionare la libreria :( Può essere utile postare il main e le impostazioni della libreria?
#16 da gcupini il 29 giugno 2012
Ciao Giovanni
Chiedo aiuto per una anamalia riscontrata usando la Libreria lCD. Lo stesso ho segnalato a Maoro Laurenti in quanto l’anomalia riguarda solo LCD su EASY USB.
Uso, sia EasyUSB che FreedomII con le routine LCD di Giavanni Bernardo con C HITECH.
Ecco la strana anomalia:
Routine LCD di Giovanni Perfettamente funzionante su Freedom II con LCD 2×16.
Stessa Routine su EasyUSB ed ecco l’anomalia:
Tutte le routine di display caratteri e numeri funzionano escluso la LCD_PUTS(“..”).
CODICE:
unsigned char LUN;
const char * AA=”PIPPO”;
void main(void){
init_OSC();
init_PORT();
LCD_INIT();
LCD_PUTS(“OK”); // NON mostra nulla
while (1) {
LCD_BACK(1); // OK
LCD_CLEAR(); // OK
LCD_PUTCH(‘Q’); // OK
LCD_PUTCH(‘ ‘); // OK
LUN=strlen(AA);
LCD_PUTUN(LUN); // mostra sempre 0 su LCD
LCD_PUTCH(‘ ‘); // OK
LCD_PUTS(AA); // Non Mostra NULLA
attesaSc(2);
LCD_BACK(0); // OK
attesaSc(2);
}
}
Dal codice che allego si nota che:
La stringa inserita nella LCD_PUTS() ha sempre lunghezza 0 !! e quindi è normale che non venga mostrata. (l’unica diversità che segnalo è quella relativa ai PIN settati in LCD.h : sono diversi per Easy e Freedom)
Ne deduco che l’anomalia non è nelle routine LCD di Giovanni che con FREEDOM funzionano!
Le possibili anomalie dovrebbero stare o nel BootLoader di Microchip oppure nel C HI TECH (puntatori?)
Avete indicazioni da darmi ? Ci sono casi analoghi segnalati?
Saluti Giovanni
#17 da Giovanni Bernardo il 30 giugno 2012
Evidentemente MPlab C18 tratta il puntatore in maniera diversa rispetto ad Hitech-C. Sul C18 prova a mettere LCD_PUTS(&AA);
#18 da zano93 il 4 luglio 2012
ciao!
complimenti per l’ ottima guida chi mi è stata molto d’aiuto.
vorrei porre una domanda per quanto riguarda il controllo dell’address counter e del busy flag che non riesco a far funzionare.
Utilizzo un display 20×4 con driver st7066u compatibile hd44780 in modalità a 4 bit e micro 16f876A. Prendendo spunto dalla libreria messa a disposizione in questa guida ho provato a scriverne una simile ma che controlla anche l’address counter per tener traccia della posizione del cursore (se non ho capito male).La domanda è: la sequenza delle istruzioni è corretta? perchè non riesco ad acquisire il dato AC6-AC0.
Ecco la funzione:
void ADDRAM(char cursore)
{
static bit busyflag;
TRISB=0b11110000; //RB7\RB6\RB5\RB4 settati come ingressi
DelayUs(2);
LCD_RS=0; //selezione registro
LCD_RW=1; //modalità lettura
LCD_EN=1;
DelayUs(5); //attiva enable
busyflag=RB7; //display occupato?
if(busyflag=0)
{
cursore = LCD_DATA; //acquisisci i bit 7-6-5-4
LCD_EN=0;
DelayUs(2);
cursore = (cursore<<4); //sposta il nibble piu alto nella posizione bassa
LCD_EN=1; //attiva enable
DelayUs(2);
cursore = LCD_DATA; //acquisisci i bit 3-2-1-0
LCD_EN=0;
DelayUs(10);
TRISB=0b00000000; //RB7\RB6\RB5\RB4 settati come uscita
cursore=(cursore & 0x7f); //maschera i bit per l'indirizzo
}
else
{
LCD_EN=0;
}
}
spero sia chiaro,essendo ancora alle prime armi con il C
grazie in anticipo dell'aiuto.
#19 da zano93 il 8 luglio 2012
nessuno che mi può cortesemente dare una mano?