0

I'm trying to control an HD44780-based LCD in Proteus with 4-bit interface. The problem is that the simulation log gives me a series of messages, which I think means that I'm not sending the commands for initialization correctly.

The initialization code for the LCD is the following:

void Inicia_LCD4(unsigned short dato)       /* Función para inicializar la*/
                                            /* pantalla LCD.                  */
{    
    PORTD = 0;
    retardo_ms(16);

    E = 0;
    retardo_us(5);
    E = 1;
    PORTD = 0x60 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_ms(10);

    E = 1;
    PORTD = 0x60 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_us(100);

    E = 1;
    PORTD = 0x60 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_us(100);

    E = 1;
    PORTD = 0x60 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_us(100);

    E = 1;
    PORTD = 0x20 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_us(100);

    E = 1;
    PORTD = 0x0c | 0x04;
    retardo_us(5);
    E = 0;   

    retardo_us(100);

    E = 1;
    PORTD = 0x60 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_us(100);

    E = 1;
    PORTD = 0x08 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_us(100);

    E = 1;
    PORTD = 0x60 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_us(100);

    E = 1;
    PORTD = 0x40 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_us(100);

    E = 1;
    PORTD = 0x60 | 0x04;
    retardo_us(5);
    E = 0;

    retardo_us(100);

    E = 1;
    PORTD = 0x78 | 0x04;
    retardo_us(5);
    E = 0;
}

the simulation log result is the following:

        Initial delta set to 2.5e-05
[HD44780] Set Function: bits=8, lines=1, dots=7 [LCD1]
[HD44780] Set Function: bits=8, lines=1, dots=7 [LCD1]
[HD44780] Set Function: bits=8, lines=1, dots=7 [LCD1]
[HD44780] Set Function: bits=8, lines=1, dots=7 [LCD1]
[HD44780] Set Function: bits=4, lines=1, dots=7 [LCD1]
[HD44780] Set DDRAM ptr = 03 [LCD1]
[HD44780] Set DDRAM ptr = 03 [LCD1]
[HD44780] Cursor left [LCD1]

and the pin assignment on my simulation is the following:

schematic in Proteus

And of course I'm trying to copy this format:

HD44780 initialization command sequence

How can I solve this problem?

Mike
  • 2,146
  • 1
  • 14
  • 29
vram
  • 158
  • 12

2 Answers2

1

To reset or init the HD44780 I used several millisecond long reset commands in a row before writing any display characters. I had to create 10, 20 and 50 millisecond long delays. Yes this is an ancient IC that is very slow to init. It was created at a time when LCD displays were very slow to update.

EDIT: After some research there does not appear to be a more advanced version of the HD44780 LDC driver on the market, but aside from a slow init cycle normal character updates are fast enough to appear instantaneous. It is still in wide use in many countries.

  • Thanks @Sparky256 for the clarification, In the meantime I was able to initialize the display (in proteus) by doing some assumptions and reading another pdf around, but some things are still unclear to me because the manuals found doesn't explain the working mode to well. – vram Nov 23 '19 at 00:12
  • About the ancient of the device yes, it is very ancient but It still useful – vram Nov 23 '19 at 00:13
  • Almost forgot to tell what is obvious, I was sending the incorrect commands to the display but know it works. – vram Nov 23 '19 at 00:15
  • In my last comment I said "but know it works" when I must said "but now it works" – vram Nov 23 '19 at 13:15
0

Right now I could solve the problem, the code had bad timings and bad positioning of the bits.

Now the code looks like this:

void Inicia_LCD4(void)                      /* Función para inicializar la    */
{                                           /* pantalla LCD.                  */
    PORTD = 0;

    retardo_ms(16);

    Envia_Com(0x30);

    retardo_ms(10);

    Envia_Com(0x30);

    retardo_us(100);

    Envia_Com(0x30);

    retardo_us(100);

    Envia_Com(CF);

    Envia_Com4b(CF | 0x08);

    Envia_Com4b(CF | 0x08);

    Envia_Com4b(CME);

    Envia_Com4b(EAP | 0x06);

    Borra_Pant4b();
}

void Envia_Com(unsigned int comandoLCD)
{
    retardo_us(5);
    E = 1;
    PORTD = comandoLCD | 0x100;
    retardo_us(5);
    E = 0;
}

void Envia_Com_RAM(unsigned int comandoLCD)
{
    retardo_us(5);
    RS = 1;
    E = 1;
    PORTD = comandoLCD | 0x500;
    retardo_us(5);
    E = 0;
    retardo_us(5);
    RS = 0;
}

void Envia_Com4b(unsigned int comandoLCD4)/* Función para enviar comando con  */
{                                       /* la pantalla incializada en modo    */
    Envia_Com(comandoLCD4 & 0xf0);      /* de 4 bits.                         */
    Envia_Com((comandoLCD4 << 4) & 0xf0);
}

void Envia_Com_RAM4b(unsigned int comandoLCD4)/* Función para enviar comando  */
{                                       /* con la pantalla incializada en modo*/
    Envia_Com_RAM(comandoLCD4 & 0xf0);  /* de 4 bits.                         */
    Envia_Com_RAM((comandoLCD4 << 4) & 0xf0);
}

void Borra_Pant4b(void)                 /* Función para borrar pantalla en    */
{                                       /* modo de 4 bits.                    */
    Envia_Com4b(BP);
    retardo_ms(2);
}

void Retorno_Carro4b(void)              /* Función para realizar retorno de   */
{                                       /* en modo de 4 bits.                 */
    Envia_Com4b(RC);
    retardo_ms(2);
}

void Conf_Modo_Ent4b(unsigned int modo) /* Coloca la dirección de la DDRAM    */
{                                       /* se quiera incrementar o decrementar*/
    Envia_Com4b(CME | modo);            /* también especifica el salto del    */
    retardo_us(40);                     /* cursor durante una lectura o       */
}                                       /* escritura de datos.                */

void Enc_Apa4b(unsigned int interr)     /* Enciende y apaga la pantalla, el   */
{                                       /* el cursor, también sirve para      */
    Envia_Com4b(EAP | interr);          /* hacer parpadear el cursor en la    */
    retardo_us(40);                     /* posición actual.                   */
}

void Desp_Cur4b(unsigned int direc)     /* Mueve el cursor o desplaza la      */
{                                       /* pantalla sin cambiar el contenido  */
    Envia_Com4b(CDD | direc);           /* de la DDRAM.                       */
    retardo_us(40);
}

void Conf_Func4b(unsigned int funcion)  /* Configura la longitud del bus de   */
{                                       /* de datos, el número de líneas de la*/
    Envia_Com4b(CF | funcion);          /* pantalla y la fuente de los        */
    retardo_us(40);                     /* caracteres.                        */
}

void Conf_CGRAM4b(unsigned int dirC)    /* Establece la dirección de la CGRAM */     
{                                       /* para poder enviar o recibr datos a */
    Envia_Com4b(ECGR | dirC);           /* esa dirección.                     */
    retardo_us(40);                     
}

void Conf_DDRAM4b(unsigned int dirD)    /* Establece la dirección de la DDRAM */
{                                       /* para poder enviar o recibir datos a*/
    Envia_Com4b(EDDR | dirD);           /* esa dirección.                     */
    retardo_us(40);
}

void Lee_BF4b(unsigned int dirB)        /* Lee la bandera de ocupado y también*/
{                                       /* lee el valor del contador de       */
    Envia_Com_RAM4b(LBFD | dirB);           /* direcciones.                       */
    retardo_us(5);
}

void Esc_DCRAM4b(unsigned int car)      /* Escribe dato a la DDRAM o CGRAM e  */
{                                       /* incrementa o decrementa el contador*/
    Envia_Com_RAM4b(car);               /* de direcciones.                    */
    retardo_us(40);                    
}                                       

/* Debo seguir trabajando en las función Lee_DCRAM4b para retornar el dato    */

Lee_DCRAM4b(unsigned int dat)           /* Lee dato de la DDRAM o CGRAM e     */
{                                       /* incrementa o decrementa el contador*/
    Envia_Com4b(LDCD | dat)             /* de direcciones.                    */
    retardo_us(40);
}

and the pins was repositioned like this. Position of the pins right now

vram
  • 158
  • 12