MSP432 Leer BF y contador de direcciones de HD77480 LCD

Antecedentes Funcionales

He escrito un pequeño proyecto de prueba de menú en MSP432401R usando una pantalla LCD HD77480 16x2 en modo de 4 bits (el modelo real es HiLetgo HD77480 16x2 1602A). La configuración de Puerto/Pin es la siguiente:

  P4.0 - RS
  P4.1 - R/W
  P4.2 - E
  ...
  P4.4 - DB4
  P4.5 - DB5
  P4.6 - DB6
  P4.7 - DB7

Después de mostrar una selección de 3 elementos y encender /apagar la función de control de pantalla configurando Display_On_Cursor_Blink para marcar el elemento con el cursor parpadeante, el usuario puede usar Switch1 (P1.1) para seleccionar cualquier elemento del menú moviendo el cursor usando el comando Establecer dirección DDRAM . Luego, el usuario usa Switch2 (P1.4) para hacer la selección.

Se utiliza un contador simple para realizar un seguimiento del índice del menú ( 0, 1, 2). Después de hacer la selección, el índice del menú se escribe en la pantalla LCD en la línea debajo de los elementos del menú. La posición de los caracteres de los elementos del menú (en la segunda línea de pantalla, celdas 16-31) son 16, 21y 26. Luego intento leer el indicador de ocupado y el contador de direcciones y escribir el contador de direcciones en la pantalla LCD una posición a la derecha del índice del menú). Toda la escritura funciona, solo obtengo valores incorrectos para el contador de direcciones.

Problema

Después de escribir el índice del menú en la pantalla, quiero leer el indicador de ocupado y el contador de direcciones. (Todos los comandos hasta este punto han sido emitidos y el retraso ha sido manejado por un bucle de retraso). La hoja de datos describe la configuración de los bits RS, R/W y E y los tiempos necesarios para la lectura, por ejemplo

ingrese la descripción de la imagen aquí

Donde estoy atascado es mientras todos los comandos de salida funcionan sin problemas, cuando leo desde la pantalla LCD, simplemente recibo el índice del menú ( 0, 1, 2para los 4 bits altos y bajos, lo que resulta en 0, 17, 34una salida como Contador de direcciones en la pantalla LCD) , o si configuro el registro DIR para P4.4-4.7 para ingresar ( 0) y luego leo desde P4IN, recibo 0xFFsin importar qué índice de menú se use.

El enfoque de lectura se realiza como se indica en los tiempos anteriores. Esencial terminar de escribir el índice del menú en la pantalla LCD para mostrarlo, configurar R/W, proporcionar un ligero retraso (borrado de E adicional) antes de la luz estroboscópica para leer los primeros 4 bits (incluidos BF y AC6, AC5, AC4) como los 4 altos -bits y luz estroboscópica de nuevo para leer los 4 bits inferiores (AC3, AC2, AC1, AC0) con un ligero retraso de E alto en la última luz estroboscópica.

Lo hago con el siguiente código:

/*
 *  see pg 21, 22 (timing), 31 data-sheet and pg 33 for 4-bit busy read (working)
 *  This is busy flag address counter read, must set RS-1 for DDRAM read.
 */
void lcd16x2_BFread (uint_fast8_t *char_lcd)
{
    RS_CLEAR;           /* set RS 0 for BF/AC read */
    RW_SET;             /* set R/W 1 for read */

    DIR_IN;             /* set P4DIR &= ~0xF0 */
    EN_CLEAR;           /* additional clear per pg. 21 for busy flag read after xfer */
    LCD_EN_STROBE;      /* strobe (EN_CLEAR; EN_SET; EN_CLEAR) */

    /* read high 4-bits, busy flag and AC6, AC5, AC4 */
    // *char_lcd = LCD_DATA_OUT  & (_LCD_4BIT_HIGH << _LCD_DATA_BASE); // read data pins high-nibble
    *char_lcd = LCD_DATA_IN  & (_LCD_4BIT_HIGH << _LCD_DATA_BASE); // read data pins high-nibble

    EN_SET;
    lcd16x2_Wait(6);    /* small delay per pg. 21 timings for 4-bit operations */
    EN_CLEAR;

    /* read low 4-bits, AC3, AC2, AC1, AC0 */
    // *char_lcd |= (LCD_DATA_OUT >> _LCD_DATA_BASE) & _LCD_4BIT_HIGH; // read data pins low-nibble
    *char_lcd |= (LCD_DATA_IN >> _LCD_DATA_BASE) & _LCD_4BIT_HIGH; // read data pins low-nibble

    DIR_OUT;            /* restor P4DIR |= 0xF0 */

    RW_CLEAR;           /* clear R/W */
}

( nota: el código comentado arriba es para leer P4OUT como una prueba, que simplemente devuelve el valor que acababa de escribir en la pantalla LCD como el índice del menú en ambos nibbles altos/bajos como se explicó anteriormente)

Todas las macros se expanden a las direcciones adecuadas con P4IN ( 0x40004c21), P4OUT ( 0x40004c23) y P4DIR ( 0x40004c25).

Entonces la pregunta es "¿Qué pieza obvia de este rompecabezas me estoy perdiendo?" No hay duda de que hay algo fundamental en el proceso que simplemente se me escapa debido a mi falta de experiencia en electrónica/EE. La lectura de los pines en la dirección de salida me devuelve lo que acabo de escribir en la pantalla.

Con el puerto configurado para la entrada, no obtengo nada más que 0xff. No 0xffes una indicación de que el indicador de ocupado esté configurado, puedo insertar el retraso máximo en un ciclo manual y nada cambia. Los bits RS, R/W y E se manejan según la hoja de datos, como se muestra en los tiempos y en las descripciones de las funciones, p.

ingrese la descripción de la imagen aquí

Entonces, desde mi perspectiva, no parece que configurar R/W y strobing con E_CLEAR, E_SET, E_CLEAR tenga ningún efecto sobre lo que hay en los pines P4.4-P4.7 para mi lectura. ¿Hay algo que he descrito aquí o que es evidente de la función en la forma en que estoy tratando de hacer la lectura del BF y el contador de direcciones que salta como simplemente incorrecto o algo que me he perdido?

Respuestas (2)

El mayor problema es que no está leyendo los pines de datos mientras la E está alta. Durante un ciclo de lectura, la pantalla LCD controlará los pines de datos solo cuando E sea alta. Esto es evidente en el diagrama de tiempo que publicaste. Usted lee los pines de datos cuando E ya está configurado bajo, por lo que la pantalla LCD ya no está impulsando el bus de datos.

Eso se ve exactamente como cuál es el problema. Ahora veo que me tropecé con el borde descendente de E pensando que no importaría ya que BF y los bits de CA todavía están en el mismo estado cuando E regresa bajo. Probaré e informaré de nuevo. Realice otra prueba con el RTC ejecutándose ahora mismo, por lo que tardará unas horas.
¡Exactamente! Dejar E alto da como resultado una lectura de 217o 89(ambos el mismo número 89con/sin BF establecido). También lo 89es la ubicación correcta de CA, que es 1 después de donde acabo de escribir el índice del menú en la segunda línea de la pantalla. (y sí, debe configurar los pines P4.4-4.7 como entrada antes de la lectura)
Eso se llama, hey, tonto AERO, lees los tiempos desde el principio del valor de bit completo que necesitas no solo arbitrariamente al principio o al final. Lección aprendida gracias de nuevo.

Todas las operaciones de bits son incorrectas.

Para copiar los cuatro bits superiores del registro del puerto en los cuatro bits superiores de su variable (y para borrar los cuatro bits inferiores de su variable), use:

*char_lcd = P4IN & 0xf0;

Para copiar los cuatro bits superiores del registro del puerto a los cuatro bits inferiores de su variable, utilice:

*char_lcd |= (P4IN >> 4) & 0x0f;
Disculpas, de hecho, eso es exactamente lo que está sucediendo (las macros son un poco inestables). Creo que @Justme probablemente tiene razón. Probaré e informaré de nuevo. El borde descendente del tiempo E me hizo tropezar.