Go Down

Topic: Capire i datasheet (Read 579 times) previous topic - next topic

blow

May 06, 2012, 03:31 pm Last Edit: May 06, 2012, 03:50 pm by blow Reason: 1
Ciao, sto cercando di capire come si sviluppa una libreria partendo dal datasheet di un determinato componente.
Ho pensato quindi di riscrivermi la libreria per comandare l'LCD, ma sto avendo qualche problema con l'inizializzazione.

Per prima cosa vorrei inizializzare l'LCD per farlo funzionare a 4 bit.
Guardando questo post, Display LCD HD44780: reset software vedo che è stata usata questa routine:
Code: [Select]
// Reset, 4 bits operation:
 delay(20);
 command(0x30);  // function set: 8 bits
 delay(10);
 command(0x30);  // function set: 8 bits
 delay(10);
 command(0x30);  // function set: 8 bits
 delay(10);
 command(0x20);  // function set: 4 bits
 
 command(0x28);  // function set: 4 bits, 1 line, 5x8 dots
 command(0x0C);  // display control: turn display on, cursor off, no blinking
 command(0x06);  // entry mode set: increment automatically, display shift, right shift
 clear();


Il problema è che non capisco come mai siano state fatte quelle scelte, perché dal datasheet , io leggo(o forse capisco?) tutt'altro.

Prima cosa, nel post viene detto questo "Eseguendo un reset software ora non c'è più alcun problema, è sufficiente inserire nel source file LiquidCrystal.cpp il reset software raccomandato alle pgg. 40 e 41 prima di inizializzare." ma a quelle pagine viene mostrata l'inizializzazione usata dal circuito di reset interno, che però funziona solo se la tensione di alimentazione ha determinate caratteristiche; mentre l'inizializzazione software viene documentata poco più sotto, a pag. 45 e 46 ed è diversa...
Detto questo, i timing usati qui sopra risultano errati, o meglio mi sembrano molto più alti del necessario e anche la sequenza di comandi mi pare errata.

La mia sequenza:
Code: [Select]

digitalWrite(LCD_E, LOW); // Si assicura che Enable sia 0
digitalWrite(LCD_RS, LOW); // Abilita RS per comando
delayMicroseconds(42000); // Dopo l'alimentazione, aspetta un minimo di 40 ms (datasheet fig.24 pag 46)
lcdWriteH(3); // scrive 0011 su DB7,DB6,DB5,SB4 (datasheet fig.24 pag 46)
delayMicroseconds(4500); // aspetta un min di 4,1ms (datasheet fig.24 pag 46)
lcdWriteH(3);
delayMicroseconds(150); // aspetta minimo 100us (datasheet fig.24 pag 46)
lcdWriteH(3);
lcdWriteH(2); // scrive 0010 su DB7,DB6,DB5,SB4 (datasheet fig.24 pag 46)
// Now is 4 bit mode
lcdSetFunction(0, 1, 0); // 4 bit, 2 lines, 5x8 fonts
lcdSetDisplay(0,0,0); // display off,  no cursor, no blink
lcdClear();
lcdSetMode(1,0); // move cursor right, no display shift

Se stampo su seriale i bit che mando come comando risultano perfettamente uguali a quelli del datasheet.
NOTA: dopo ogni write c'è ovviamente un impulso su Enable.
Code: [Select]

DB7|DB6|DB5|DB4
0|0|1|1|
0|0|1|1|
0|0|1|1|
0|0|1|0|
-----------------
0|0|1|0|
1|0|0|0|
-----------------
0|0|0|0|
1|0|0|0|
-----------------
0|0|0|0|
0|0|0|1|
-----------------
0|0|0|0|
0|1|1|0|
-----------------

Non capisco però come mai non funziona, lo schermo si comporta in modo random, eppure mi sembra di aver seguito quello che il datasheet dice.
Le funzioni che uso per mandare i comandi o dati all'lcd sono corrette, perché se uso l'inizializzazione della libreria LiquidCrystal, poi posso scrivere quello che voglio sull'lcd con i miei metodi.

Guardando la libreria LiquidCrystal, vedo che l'inizializzazione è simile alla mia, per i 4bit:
Code: [Select]
   // this is according to the hitachi HD44780 datasheet
   // figure 24, pg 46

   // we start in 8bit mode, try to set 4 bit mode
   write4bits(0x03);
   delayMicroseconds(4500); // wait min 4.1ms

   // second try
   write4bits(0x03);
   delayMicroseconds(4500); // wait min 4.1ms
   
   // third go!
   write4bits(0x03);
   delayMicroseconds(150);

   // finally, set to 4-bit interface
   write4bits(0x02);

anche qui non capisco alcune scelte fatte:

  • Come mai aspetta per ben due volte 4500us quando invece il datasheet dice di attendere prima almeno 4100us e poi solo 100us?

  • Coma mai dopo il terzo comando 0x3 aspetta nuovamente 150us quando il datasheet invece non fa riferimento a nessun tempo di attesa prima di mandare il comando 0x2?



Con questo post non voglio assolutamente dire che le scelte fatte qui sopra siano sbagliate, anzi, voglio proprio capire come mai siano state fatte, da dove posso capire leggendo solamente la documentazione dell'HD44780 come poter prendere certe decisioni invece che altre.

Probabilmente mi sta sfuggendo qualcosa...

blow

Trovato il problema... la mia funzione che scriveva i comandi non metteva a LOW il segnale RS, per cui veniva sempre interpretato come dato.
Ora funziona, rimane comunque il fatto che non capisco come mai siano state fate quelle scelte, io reputo la mia routine la più corretta, o almeno la più corretta se consideriamo il datasheet.

lucadentella

ciao

ti rispondo per la parte timing: sicuramente sono stati scelti valori più "sicuri" per la grande eterogeneità di controller per display che si trovano sul mercato e che si dicono "hitachi compatibili". A volte infatti ci si accorge che rispettando "alla lettera" i timing dati nel datasheet non si ottengono i comportamenti voluti.
lucadentella.it

blow

Ciao, ti ringrazio, una risposta più che ragionevole.

uwefed

Il HD44780 avrebbe un Bit che segnala che é ancora occupato per esempio per eseguire un reset. Visto che per risparmiare PIN non si usa il pin che definise lettura/scrittura non si puó sapere lo stato di quel PIN. Per questo si aspetta un tempo sicuro perche il HD44780 abbia eseguito il comando.
Ciao Uwe

Go Up