Inicialización de depuración de LCD con controlador NT7605

He estado tratando de inicializar mi LCD durante aproximadamente una semana, y me avergüenza decir que hasta ahora no he tenido éxito. He hecho esto en el pasado, y recuerdo que fue un poco complicado obtener la secuencia de inicialización correcta, pero en este punto creo que he examinado completamente la implementación y simplemente no funciona.

Configuración:

  1. NHT-C0220AZ-FSW-FTW LCD con controlador NT7605
  2. Plataforma de lanzamiento TI con MSP430G2231
  3. potenciómetro de 10k de una sola vuelta para control de contraste
  4. LCD alimentado con 3.3V
  5. Launchpad alimentado con USB
  6. Tierras para cada componente unido
  7. utilizando la interfaz de 4 bits de la pantalla LCD
  8. Luz de fondo LCD conectada a Vcc (3.3V) desde Launchpad

ingrese la descripción de la imagen aquí

Aquí hay cosas que he hecho hasta ahora para probar:

  1. Conexiones comprobadas dos veces
    1. Pines LCD D4-D7, RS, R/W y E
    2. Potenciómetro conectado al pin de control de contraste, y he verificado que el voltaje va de 0 - Vdd.
    3. LCD Vdd conectado a 3,4 V, que es aproximadamente la especificación de voltaje mínimo
  2. Rutinas de E/S comprobadas dos veces en MSP430
    1. Los pines LCD se restablecen/configuran como se esperaba a medida que repaso mi código
    2. forLas rutinas de temporización son bucles semi "calibrados".
  3. Cotejé la documentación de las rutinas de inicialización con las rutinas de otros que encontré en línea
      1.

Sin embargo, después de todo esto, ¡no puedo mostrar nada en la pantalla LCD! Asi que aqui están mis preguntas:

  1. El fabricante ha verificado que hay un error en el NT7605 donde el bit ocupado no se afirma correctamente. Así que he estado usando demoras fijas (bien por mí), pero quería usar el indicador de ocupado para ver si el conductor está respondiendo a los comandos. ¿Hay otra forma de hacer un diagnóstico de bajo nivel para ver lo que piensa la pantalla LCD cuando envío los comandos de inicialización?
  2. ¿Alguien más aquí ha usado la misma pantalla LCD? Todas las demás pantallas LCD estándar que he usado (tipos de caracteres 2x20) se oscurecen notablemente cuando giro el ajuste de contraste, y IIRC lo hacen incluso cuando no se inicializan correctamente. Sin embargo, cuando enciendo la olla en la mía, la pantalla LCD no se oscurece en absoluto. Quizás esto se deba a que no está inicializado, pero no estoy seguro.
  3. ¿Alguien puede encontrar algo raro con esta rutina de inicialización?
    1. retraso > 30ms
    2. enviar 0x20, solo nibble superior
    3. enviar 0x28 (establecer interfaz de 4 bits)
    4. espera 10ms
    5. enviar 0x0C (pantalla encendida, cursor apagado, parpadeo apagado)
    6. espera 10ms
    7. enviar 0x01 (pantalla clara)
    8. espera 10ms
    9. enviar 0x02 (cursor de incremento, sin cambio de visualización)
    10. espera 10ms
    11. configure RS alto para comenzar a enviar datos de caracteres
    12. enviar 0x48 (mostrar 'H')

Rutina de inicialización del fabricante

Mi código se ve así:

void InitializeLcd()
{
    DelayTicks( 10000);
    // 4 bit interface, 2 lines, 5x8 characters
    // the spec sheet shows the 0x20 part of 0x28 getting sent an extra time
    // so I used a special function to deal with this case.  This just sends
    // the 0x20 part and ignores the 0x08 part.
    SendLcdUpperNibble( COMMAND, 0x28);
    SendLcdByte( COMMAND, 0x28);
    DelayTicks( 1000);
    // Display on, cursor off, blink off
    SendLcdByte( COMMAND, 0x0C);
    DelayTicks( 1000);
    // clear display
    ClearLcd();
    // Entry mode set - increment cursor, no display shift
    SendLcdByte( COMMAND, 0x02);
    DelayTicks( 1000);
    // Set write to DDRAM mode since we'll just be sending data from now on
    SendLcdByte( DATA, 0x48);
    SendLcdByte( DATA, 0x65);
    SendLcdByte( DATA, 0x6C);
    SendLcdByte( DATA, 0x6C);
    SendLcdByte( DATA, 0x6F);
}

void ClearLcd()
{
    // Clear display
    SendLcdByte( COMMAND, 0x01);
    DelayTicks( 1000);  
}

void SetRS( int value)
{
    if( value == 0)
        P2OUT &= ~RS;
    else
        P2OUT |= RS;
}

void SetRW( int value)
{
    if( value == 0)
        P2OUT &= ~RW;
    else
        P2OUT |= RW;    
}

void SetE( int value)
{
    if( value == 0)
        P1OUT &= ~E;
    else
        P1OUT |= E;
}

void DelayMs( int delay)
{
    int ctr;
    int ms = delay * 100;
    for( ctr=0; ctr<ms; ctr++);
}

void DelayTicks( int ticks)
{
    int ctr;
    for( ctr=0; ctr<ticks; ctr++);
}

void SendLcdByte( unsigned char command_0_or_data_1, unsigned char command)
{
    SendLcdUpperNibble( command_0_or_data_1, command);
    // send the lower nibble next
    // special thank you to ToyBuilder for catching my missed bit-shift in the following line
    // I also had the mask on P1OUT incorrect, presumably because I messed up the command mask and just made it match that.
    P1OUT = ((command & 0x0F) << 4) | (P1OUT & 0x0F);
    Strobe( command_0_or_data_1);
}

void SendLcdUpperNibble( unsigned char command_0_or_data_1, unsigned char upper_nibble)
{
    P1OUT = (upper_nibble & 0xF0) | (P1OUT & 0x0F);
    Strobe( command_0_or_data_1);
}

void Strobe( unsigned char command_0_or_data_1)
{
    SetRS( command_0_or_data_1);
    SetRW( 0);
    DelayTicks( 1000);
    SetE( 1);
    DelayTicks( 1000);
    SetE( 0);       
}

Lo único que puedo decir es que parece que la pantalla LCD parpadea cuando paso por encima de SendLcdByte y le envío datos de caracteres. Cuando analizo todo, parece que estoy volteando los bits correctamente...

EDITAR: soldé una nueva pantalla LCD, y esta vez intenté dejar los pines de datos no utilizados (D0-D3) desconectados (es decir, flotando). No hubo diferencia. La pantalla LCD todavía parpadea cuando inicializo. Ahora estoy esperando 100 ms para todas las demoras, incluida una demora cuando se enciende la luz estroboscópica E. También desconecté el Vcc proveniente de la sección FET del Launchpad y ahora solo estoy alimentando el MSP430 y la pantalla LCD desde la fuente de alimentación de mi laboratorio.

EDICIÓN n. ° 2: fui a una pantalla LCD de 3.3 V y todo comenzó a funcionar mágicamente. Gracias a ToyBuilder por detectar un estúpido error de código cuando estaba depurando con la pantalla LCD de 5V. Después del intercambio, la pantalla LCD se inicializó correctamente. Actualmente estoy mostrando basura en lugar de "Hola", pero eso no está relacionado con esta pregunta.

EDICIÓN n. ° 3: encontré mi error de visualización: estaba enviando 0x06 para el modo de entrada en lugar de 0x02. No estoy seguro de por qué hice eso, debe haber sido un error tipográfico.

Una pequeña nota al margen: si hubiera sabido que iba a usar el MSP430 para este proyecto, habría elegido una pantalla LCD más adecuada, como la NHD-C0220AU-FSW-FTS, que es una pieza de 3,3 V. No estoy seguro de si parte de mi problema se debe al uso de señales lógicas de 3,3 V para hacer bitbang en el bus de datos. Podría pedir una de estas pantallas LCD ahora porque estoy perdiendo demasiado tiempo en esto.

Respuestas (5)

Oh, duh, no leí tu código cuidadosamente, tu envío SendLcdByte es incorrecto:

    void SendLcdByte( unsigned char command_0_or_data_1, unsigned char command)
{
    SendLcdUpperNibble( command_0_or_data_1, command);
    // send the lower nibble next
 // AS WRITTEN:
    P1OUT = (command & 0x0F) | (P1OUT & 0xF0);
 // SHOULD BE:
    P1OUT = ((command & 0x0F) << 4) | (P1OUT & 0xF0);
    Strobe( command_0_or_data_1);
}
¡Gran captura! Gracias por encontrar eso. Pensé totalmente que las cosas estaban funcionando con mi bit twiddling, pero pasé por alto el byte inferior durante la prueba. Estoy bastante seguro de que esta es la causa del problema y lo probaré pronto.
Cuando encuentre tiempo extra, tendré que usar el alcance en el mordisco inferior. Estaba seguro de que esta solución habría hecho que todo funcionara, pero la pantalla LCD aún no se está inicializando. ¡Gracias de nuevo por detectar mi error! Lo perdí por completo cada vez que miraba el código... realmente vergonzoso. :)
ok, en realidad debería ser P1OUT = ((command & 0x0F) << 4) | (P1OUT & 0x0F);Desearía poder poner una excusa, como "soy disléxico", pero no puedo. Verifiqué los bits del bus de datos en el osciloscopio, pero necesito volver a verificar los bits que se activan porque todavía no funciona. Ahora estoy probando en la propia pantalla LCD, en lugar de pinchar la placa de prueba.
@ToyBuilder: FYI, después de cambiar las pantallas LCD, mi código funciona, pero su respuesta fue sin duda un ingrediente clave para llegar allí. No sé por qué esto no funcionó con la pantalla LCD de 5 V, porque mis niveles lógicos estaban dentro de las especificaciones. De todos modos, decidí reiniciar la recompensa y mañana te la otorgaré por esta respuesta. ¡Gracias de nuevo!
Puede tener que ver con la capacidad del controlador LCD para generar el voltaje de accionamiento adecuado para el cristal líquido en el dispositivo; puede ser que a 3,3 V, el LC no esté lo suficientemente sesgado como para marcar una diferencia visible...
Sin embargo, 3.3V está dentro de las especificaciones y lo confirmé con su soporte técnico. Tal vez vuelva a cambiar a la pantalla de 5V mañana solo por diversión, ahora que he confirmado que el código funciona correctamente.

Vuelva a verificar los voltajes de salida alto/bajo de la señal del MSP430 y los mínimos para las entradas en la pantalla LCD.

Otra cosa es si está golpeando un poco demasiado rápido: su lista de fuentes no muestra cómo está jugando con los datos y las señales E. Si gira E demasiado pronto después de cargar los bits de datos, no funcionará. Si no mantiene presionado E el tiempo suficiente para que la pantalla LCD enganche los datos entrantes, no funcionará. Intente agregar un retraso de tiempo entre escribir D0-D7, y luego entre afirmar y luego anular la afirmación de la línea E.

Supongo que las líneas se usan estrictamente para las pantallas LCD, por lo que no hay problemas de tiempo de espera. Si también usa las líneas como un bus para otros dispositivos, deberá asegurarse de que sus datos se retengan el tiempo suficiente antes de que el bus se use para otras cosas.

gracias por el punto sobre los retrasos después de configurar los bits de datos. Mi código muestra el retraso que estoy usando, que es ninguno. :) Solo tengo un retraso de 1000 tics entre E alto y E bajo, lo que equivale a unos 10 ms según mi osciloscopio. Probaré el retraso antes de la E estroboscópica ahora.
El nivel de salida del MSP430 es Vcc-0.3V, por lo que son 3V. La pantalla LCD tiene una entrada mínima alta de 2,4 V, por lo que debería estar listo para comenzar. Configuré los retrasos en 100 ms para todo , y la pantalla LCD todavía parpadea durante el inicio y no me muestra nada.
Necesito entender mejor esta parte. Por lo que puedo decir, las salidas del MSP430 están dentro de las especificaciones para los niveles altos de lógica de entrada de LCD, pero el soporte técnico cree que el problema es el contraste.

También una cosa que me engañó una vez fue que la luz de fondo era tan baja que no podía ver que estaba funcionando.

¡Sí, definitivamente tengo la luz de fondo funcionando! es brillante Lo único que me preocupa es que cuando giro la perilla de contraste, no veo ninguna indicación visual de que esté funcionando, y el soporte técnico me dijo que debería ver bloques aparecer en la primera línea.
Y parece que ha probado que su potenciómetro de contraste no está roto... raro.
Sí, he visto oscilar el voltaje cuando lo enciendo.

El soporte técnico de Newhaven Display me recomendó reemplazar la pantalla LCD y volver a intentarlo. Es posible que lo haya dañado durante la configuración inicial, así que veremos cómo va. Publicaré los resultados aquí.

El primer módulo LCD que obtuve, alrededor de 1989, fue DOA; la línea de habilitación actuó como una resistencia a tierra de aproximadamente 100 ohmios. Digi-Key lo reemplazó sin cargo más que el envío (agradable de ellos) y el reemplazo funcionó al primer intento.
No creo que las pantallas LCD estén dañadas. El soporte técnico se corrigió y me hizo saber que los bloques no aparecerán cuando se ajuste el potenciómetro de contraste sin inicializar primero. ¡Todavía estoy trabajando en esto!

¿Será posible que tengas los pines conectados al revés?

De vez en cuando, me encontraba con pantallas LCD con los números de pin invertidos en la pieza misma o en la hoja de datos o en ambos.

Sé que esto puede parecer un "¿Está enchufado?" pregunta - pero personalmente me ha pillado por sorpresa con esto.

* EDITAR *

Uf, en mi comentario anterior, dije que escribiera 0x80; lo que pretendía era que tratara de mantener el valor 0x40 o 0x60 en las líneas de datos.

Si resulta que los pines están invertidos, escribir 0x40 aplicaría energía y tierra a través de los pines de datos a la pantalla LCD, lo que le daría la oportunidad de reiniciarse automáticamente. Esto es posible porque un módulo LCD de caracteres típico solo consume de 1 a 5 mA de corriente, dentro de la capacidad de conducción de la mayoría de las salidas.

Lo que sospecho que puede estar sucediendo es que está escribiendo algunos valores 0x6X y 0x4X en su pantalla LCD durante un breve período de tiempo mientras inicializa la pantalla LCD, y que la pantalla LCD se está encendiendo durante ese breve período; pero cuando comienza a escribir otros valores, efectivamente lo está desactivando.

* EDITAR 2 *

Mientras buscaba la hoja de datos de otra pantalla LCD para verificar los requisitos actuales, noté que es posible que haya intercambiado sus pines Vcc y Vcontrast. ¡Asegúrate de comprobar eso también!

Acabo de mirar y vi en la hoja de datos NHT-C0220AZ-FWS-FTW (donde obtuvo su dibujo esquemático arriba) que el contraste es el pin 2 y el voltaje de suministro es el pin 3. Que es el reverso de las partes de Vishay y Optrex donde el contraste es el pin 3 y el voltaje de suministro es el pin 2.

Bueno, diablos, incluso el NHD-0420DZ-FSW-FBW de NewHaven tiene contraste en el pin 3 y suministro en el pin 2.

Bueno, salí directamente de su hoja de datos, en lugar de basarme en experiencias pasadas, por lo que estoy conectado correctamente. Pero lo que parece, el soporte técnico cree que simplemente no debería usar esta pantalla LCD con el MSP430 debido a los niveles de voltaje incompatibles. Tengo una pieza de 3.3V ordenada y eso podría resolver todos mis problemas. Pero, sinceramente, todavía no entiendo por qué una MCU de 3,3 V no funcionaría con esta pantalla LCD.
En referencia a su primera edición, no creo que este sea el caso. Tengo la pantalla LCD encendida mucho antes de pasar por mi rutina de inicialización.
Mirando la hoja de datos de su parte específica, estoy de acuerdo en que parece que podría operar (aunque en los márgenes) a 3.3V.