Riassumendo, ho scritto un programma per testare un display alfanumerico HD44780 16x2.
Tutto funziona, anche il controllo del flag BF per sapere se il display è inattivo, ma ho problemi quando faccio il controllo per far tornare il cursore nella home, cioè è come se non ci fosse.
Per rispettare i tempi, mi metto sul lato sicuro e e setto dati e segnali (RS, RW) contemporaneamente e rispetto i tempi di esecuzione del "clock" E. Vi mostro l'esempio:
Nel main ho questo:
- Codice: Seleziona tutto
write_comm(LCD_FUNCTIONSET|LCD_8BITMODE|LCD_2LINE|LCD_5x8DOTS);
while (write_comm(LCD_BUSYCHECK) != 0);
write_comm(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKON);
while (write_comm(LCD_BUSYCHECK) != 0);
write_comm(LCD_ENTRYMODESET|LCD_ENTRYLEFT);
while (write_comm(LCD_BUSYCHECK) != 0);
write_comm(LCD_RETURNHOME);
__delay_ms(2); // <- QUELLO MISTERIOSO!
while (write_comm(LCD_BUSYCHECK) != 0);
// uint16_t a = 0b0000000001001000; // H
write_comm(LCD_WRITEDATA|'x');
while (write_comm(LCD_BUSYCHECK) != 0);
write_comm(LCD_WRITEDATA|'u');
while (write_comm(LCD_BUSYCHECK) != 0);
write_comm(LCD_WRITEDATA|'@');
while (write_comm(LCD_BUSYCHECK) != 0);
while (1) {
} // while
e la write_comm è descritta così, insieme alla generazione dell'impulso:
- Codice: Seleziona tutto
void pulse(){
PORTCbits.RC2 = 0;
__delay_us(1); // 1us enable cycle time
PORTCbits.RC2 = 1;
__delay_us(1);
PORTCbits.RC2 = 0;
__delay_us(100);
}
bool write_comm(uint16_t comando){
if (comando == LCD_BUSYCHECK)
{
bool flag = 1;
TRISD = 0xFF; //8 bit data
PORTCbits.RC0 = comando >> 9;
PORTCbits.RC1 = comando >> 8;
pulse();
flag = PORTD & (1 << 8);
TRISD = 0x00; //8 bit data
return flag; // for checking purposes, ready flag
}
PORTD = comando;
PORTCbits.RC0 = comando >> 9; //RS
PORTCbits.RC1 = comando >> 8; // R/W
pulse();
return 0; // scarta
}
I define:
- Codice: Seleziona tutto
#define LCD_CLEARDISPLAY 0x0001
#define LCD_RETURNHOME 0x0002
#define LCD_ENTRYMODESET 0x0004
#define LCD_DISPLAYCONTROL 0x0008
#define LCD_CURSORSHIFT 0x0010
#define LCD_FUNCTIONSET 0x0020
#define LCD_SETCGRAMADDR 0x0040
#define LCD_SETDDRAMADDR 0x0080
#define LCD_BUSYCHECK 0x0100
#define LCD_WRITEDATA 0x0200
Inserendo i 2ms dopo il RETURNHOME funziona, se non lo faccio quando resetto il micro "a caldo", a volte il display sceglie una delle 3 locazioni in cui scrivo il carattere "a caso", quando il programma riparte, invece di partire dalla prima posizione. Ripeto, a volte: dev'essere un tempo non rispettato, o quasi.
In questo articolo http://www.electroyou.it/tardofreak/wiki/pic18f47j53-un-modulo-in-c-per-pilotare-display-lcd ho letto due cose che non mi sono chiare:
- Codice: Seleziona tutto
void HD44780_writeCmd(unsigned char n)
{
// Per inviare un comando la linea RS deve essere posta a 0
HD44780_RS = 0;
// Invia il dato
writeByte(n);
// Ritarda per attendere la completa esecuzione del comando
// In questo caso dipende dal comando
// questi ritardi sono di 1600 e 43 us massimi
if (!(n & 0xFC)) delay1600us(); else delay43us();
}
//-----------------------------------------------------------------------------
void HD44780_writeData(unsigned char n)
{
// Per inviare un comando la linea RS deve essere posta a 0
HD44780_RS = 1;
// Invia il dato
writeByte(n);
// Ritarda per attendere la completa esecuzione del comando
// anche questo ritardo deve essere 43us
delay43us();
}
Perché viene fatta una sola lettura del flag e in base a quello impostare il ritardo? Non va bene una lettura in polling, come dice nel datasheet? Credo che a livello funzionale sia l'unica differenza... credo! Però deduco che quel programma li funziona.
Ma cosa sbaglio io, se non metto quei due millisecondi? Il flag dovrebbe rimanere a 1 fino a quando il display non riceve, e dopo il RETURN HOME pare che a volte sia "pronto" per ricevere anche quando non lo è, constringendomi a mettere una ritardo manuale. Cosa mi sfugge?

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)




