Problemas con un LCD 16x2 controlado con un microcontrolador LPC2114

Hola a todos! Tengo un problema con un display LCD (wh1602a) que no me anda ni para atrás ni para adelante :/

Yo utilizo un microcontrolador LPC2114, programando en C (no creo que todos lo conozcan, pero los que saben programar con PIC en C, pueden entender más o menos el código)

Acá les paso el código, con muchos comentarios, para tratar de ser lo más claro posible, cualquier cosa me preguntan, yo voy a estar conectado.

Saludos!


Código:
#include "lpc2114.h"
#include <stdio.h>

#define LCD_D0 0x00000010            /* P0.4 */
#define LCD_D1 0x00000020            /* P0.5 */
#define LCD_D2 0x00000040            /* P0.6 */
#define LCD_D3 0x00000080            /* P0.7 */
#define LCD_D4 0x00000100            /* P0.8 */
#define LCD_D5 0x00000200            /* P0.9 */
#define LCD_D6 0x00000400            /* P0.10 */
#define LCD_D7 0x00000800            /* P0.11 */
#define LCD_RS 0x00008000            /* P0.15 (DATO - INSTRUCCION)*/
#define LCD_EN 0x00002000            /* P0.13 (ENABLE)*/
#define LCD_DATO 0x00000FF0            /* Agrupa los 8 bits de dato */

void InicializarLCD (void);
void MostrarLCD (unsigned char []);
void delay_ms (int);
void delay_us (int);

int main(void) {

    IODIR0 = (LCD_DATO|LCD_EN|LCD_RS);    /* Declara los pines del grupo P0 que van a ser utilizados como salida */
    IOCLR0 = (LCD_DATO|LCD_EN|LCD_RS);    /* Todos los pines de salida se ponen en estado 0 */
    unsigned char LCD [] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPp";    /* 32 caracteres a ser mostrados */

    InicializarLCD ();    /* Se inicializa el display */

while (1) {            /* En este bucle infinito se muestran los caracteres */
    MostrarLCD (LCD);
}

return 0;

}


void InicializarLCD (void) {            /* IOSET0 pone en estado 1, e IOCLR0 pone en estado 0 */
                          /* EN - RS - DATO (RW va a estar conectado siempre a masa) */
    delay_ms (100);
    IOCLR0 = (LCD_DATO|LCD_EN|LCD_RS);       /* 0 0 00000001 Borra todo el display y coloca el cursor */
    IOSET0 = LCD_D0;                          /* en la posición 0 del address counter (a la izquierda de la primera línea) */
    delay_us (100);
    IOSET0 = LCD_D1;              /* 0 0 00000011 El cursor vuelve a la pocición inicial */
    delay_us (100);
    IOSET0 = (LCD_D2|LCD_D1);          /* 0 0 00000110 El cursor se mueve a la derecha, incrementando en 1 el address counter */
    IOCLR0 = LCD_D0;              /* El mensaje permanece fijo, no se desplaza hacia ningún lado */
    delay_us (100);
    IOSET0 = (LCD_D3|LCD_D2);          /* 0 0 00001100 El mensaje permanece visible */
    IOCLR0 = (LCD_D1|LCD_D0);          /* El cursor es invisible */
    delay_us (100);
    IOSET0 = (LCD_D4|LCD_D2);          /* 0 0 00010100 Desplaza el cursor a la derecha */
    IOCLR0 = LCD_D3;              /* sin arrastrar el mensaje */
    delay_us (100);
    IOSET0 = (LCD_D5|LCD_D4|LCD_D3);      /* 0 0 00111000 Los datos son transportados en 8 bits, se utilizan las 2 líneas del                                 display */
    IOCLR0 = LCD_D2;              /* y cada caracter se muestra en el display en matrices de 5x8 puntos */
    delay_us (100);

}


void MostrarLCD (unsigned char a[]) {
    int i;
    unsigned char caracter;
    
    IOCLR0 = (LCD_DATO|LCD_EN|LCD_RS);        /* 0 0 00000000 Vuelve el cursor */
    IOSET0 = LCD_D1;                /* 0 0 00000010 a la posición inicial */
    delay_us (100);

    for (i=0; i<32; i++) {
        caracter = a[i];
        IOCLR0 = LCD_DATO;                 /* 0 0 00000000 Lee la palabra de 8 bits y la guarda en la RAM */
        IOSET0 = (((caracter << 4) & LCD_DATO)|LCD_RS); /* 0 1 XXXXXXXX además de incrementar en 1 el address counter*/        
        delay_us (10);
        IOSET0 = LCD_EN;                 /* 1 1 XXXXXXXX Habilita módulo del display */
        delay_us (10);
        IOCLR0 = LCD_EN;                 /* 0 1 XXXXXXXX Deshabilita módulo del display */
        delay_us (10);

    }
}


/* Delay en milisegundos (no exactamente, hay que multiplicar la cantidad de instrucciones en assembler que demanda el for por el número que representa el tiempo), para una frecuencia de 60 MHz */

void delay_ms (int tiempo) {
    int i, j;
    for (i=0; i<tiempo; i++) {
        for (j=0; j<60000; j++); /* (1/60MHz)*60000 = 1ms */
    }
}


/* Delay en microsegundos, para una frecuencia de 60 MHz */

void delay_us (int tiempo) {
    int i, j;
    for (i=0; i<tiempo; i++) {
        for (j=0; j<60; j++); /* (1/60MHz)*60 = 1us */
    }
}



Escrito un par de horas después:

Recién encontré un simulador de display LCD y me estoy dando cuenta que no ponía en enable en 1 y después en 0 para ejecutar cada instrucción de inicialización.

http://www.geocities.com/dinceraydin/djlcdsim/djlcdsim.html
 
Última edición:
Atrás
Arriba