Electrónicos Embebidos

Bienvenido a mi sitio web

Controlando un GLCD GDM12864-5 con controlador ST7920 usando CCS C y PIC18F25K22

    Resumen del funcionamiento

    GLCD 128645K
    Este driver controla un GLCD 128×64 con controlador ST7920 en modo paralelo de 8 bits, usando PORTB para datos y las señales en PORTC: RS→C0, RW→C1, E→C2, RST→C3. La línea PSB del display debe ir a Vcc (modo paralelo).

    El render se hace en RAM de usuario (gdram) y se “vuelca” al LCD con glcd_update(). Esto evita parpadeos y permite dibujar múltiples píxeles/figuras antes de refrescar.

    Funcionamiento en físico

    Mapa de memoria lógico

    • Resolución: 128×64.
    • Se divide en 32 filas (YVAL=32) de 16 palabras de 16 bits (XVAL=16).
    • Cada palabra (16 bits) representa 16 píxeles horizontales.
    • glcd_DrawPixel(x,y,...) calcula v=y, h=x/16, b=15-(x%16).
    • Para y>31 se compensa x+=128 (metodología usada en este driver).

    Protocolo y temporizado

    • Lecturas y “busy flag” conmutan TRISB a entrada temporalmente.
    • Se aumentaron los delay_us() alrededor de E para robustez.
    • Comandos de inicialización siguen la secuencia del datasheet (doble 0x30, gráfico 0x34/0x36).

    API del Driver

    Inicialización

    • glcd_init_graph(): modo gráfico (recomendado para dibujar). Limpia y actualiza.
    • glcd_init_basic(): modo básico (texto interno del ST7920).

    Acceso de bajo nivel

    • glcd_instruction(uint8), glcd_data(uint8): envío al LCD.
    • glcd_readByte(address): lectura (respeta TRISB).
    • glcd_check_busy(): espera a que BF=0 (PIN_B7).

    Rasterizado en RAM y refresco

    • glcd_DrawPixel(int8 x,int8 y,int1 color): dibuja en gdram y marca refresh=TRUE.
    • glcd_fillScreen(ON|OFF): rellena GDRAM con 1 o 0; marca refresh=TRUE.
    • glcd_update(): vuelca toda la GDRAM al LCD (si refresh==TRUE).
    Importante: Las operaciones que dibujan sólo modifican la memoria del usuario. Nada se verá en el LCD hasta llamar a glcd_update(). Puedes dibujar muchas cosas y actualizar una sola vez.

    Ejemplo mínimo (inicio + píxel + pantalla llena)

    // <main.c> – CCS C (ejemplo mínimo)
    // Ajusta fuses/clock según tu proyecto
    #include <18F25K22.h>
    #device ADC=10
    #fuses NOWDT, INTRC_IO, NOMCLR, NOLVP, PUT, NOCPD
    #use delay(internal=64MHz)
    
    // Incluye tu driver tal cual lo compartiste
    #include "st7920_driver.c"   // renombra con el nombre real del archivo
    
    void main(void)
    {
       glcd_init_graph();        // Modo gráfico
       glcd_fillScreen(OFF);     // Limpia la GDRAM (apagado)
       glcd_update();            // Refresca LCD
    
       // Dibuja un píxel en (10,10)
       glcd_DrawPixel(10, 10, ON);
       glcd_update();            // ¡Ahora se ve!
    
       while(TRUE) { }
    }

    Ejemplo: dibujar una línea horizontal y un rectángulo hueco

    Como el driver expone sólo DrawPixel, aquí van helpers simples para figuras básicas:

    // Helpers sencillos basados en DrawPixel
    void glcd_hline(int x1, int x2, int y, int1 c){
       int x; if(x2<x1){int t=x1; x1=x2; x2=t;}
       for(x=x1;x<=x2;x++) glcd_DrawPixel(x,y,c);
    }
    void glcd_vline(int x, int y1, int y2, int1 c){
       int y; if(y2<y1){int t=y1; y1=y2; y2=t;}
       for(y=y1;y<=y2;y++) glcd_DrawPixel(x,y,c);
    }
    void glcd_rect_hollow(int x1,int y1,int x2,int y2,int1 c){
       glcd_hline(x1,x2,y1,c);
       glcd_hline(x1,x2,y2,c);
       glcd_vline(x1,y1,y2,c);
       glcd_vline(x2,y1,y2,c);
    }
    
    // Uso
    glcd_fillScreen(OFF);
    glcd_hline(5, 122, 10, ON);
    glcd_rect_hollow(20, 20, 100, 50, ON);
    glcd_update();

    Ejemplo: texto 5×7 escalable (si ya tienes font5x7[])

    Si tu proyecto incluye font5x7 y la rutina glcd_text57() (la que compartiste), úsala así:

    extern const unsigned int8 font5x7[][5];
    void glcd_text57(int x,int y,char* text,int size,int1 color); // tu implementación
    
    glcd_fillScreen(OFF);
    glcd_text57(2, 2, "HELLO", 1, ON);   // 5x7
    glcd_text57(2, 14, "WORLD", 2, ON);  // 10x14
    glcd_text57(2, 32, "GLCD", 3, ON);   // 15x21 (triplicado)
    glcd_update();

    Ejemplo: animación suave (sin parpadeo)

    Dibuja varias cosas y refresca una sola vez por fotograma:

    int x = 5, y = 24, dx = 1;
    
    while(TRUE){
       glcd_fillScreen(OFF);                 // limpia el backbuffer (GDRAM)
       glcd_rect_hollow(x, y, x+20, y+10, ON);
       // ... (dibuja más cosas si quieres)
       glcd_update();                        // 1 solo refresco
    
       x += dx;
       if(x<=0 || x+20>=127) dx = -dx;
       delay_ms(30);
    }

    Buenas prácticas y notas eléctricas

    • Alimentación estable: desacopla con 100 nF cerca del LCD y del PIC; añade 10 µF en la línea de 5 V.
    • RST (C3): el driver asertará reset al iniciar; puedes añadir un pull-up (~10 kΩ) si tu placa lo requiere.
    • Entradas flotantes: si usas teclas/entradas, usa resistencias de pull-up/pull-down para evitar ruido que cause cuelgues.
    • Temporizado: si subes el clock o cambias de PIC, conserva o incrementa ligeramente los delay_us() alrededor de E.
    • Refresh: llama a glcd_update() sólo cuando termines un “lote” de dibujo; reduce parpadeo y tráfico al LCD.
    • Compatibilidad: PSB a Vcc (paralelo); si usas serial del ST7920, este driver no aplica.

    Tabla rápida de pines y macros

    // Señales (PORTC)
    #define rs  PIN_C0   // Register Select
    #define rw  PIN_C1   // Read/Write
    #define e   PIN_C2   // Enable
    #define rst PIN_C3   // Reset
    
    // Datos (PORTB, D0..D7)
    output_b(value);     // Escribe 8 bits
    input_b();           // Lee 8 bits
    set_tris_b(mask);    // Dirección del puerto (1=input)
    
    /* Conexiones sugeridas:
       ST7920 D0..D7  <—> PIC PORTB RB0..RB7
       ST7920 RS      <—> PIC RC0
       ST7920 RW      <—> PIC RC1
       ST7920 E       <—> PIC RC2
       ST7920 RST     <—> PIC RC3
       ST7920 PSB     —>  Vcc (paralelo)
       Vdd/Vss/VO/LED según módulo
    */

    Solución de problemas

    • Se borra la pantalla al rato: revisa alimentación y ruido; agrega pull-ups donde proceda; mantén delays y no llames update() en bucles ultra-rápidos sin necesidad.
    • Pantalla en blanco: confirma PSB→Vcc, orden de init (doble 0x30), y conexiones de datos D0–D7 con PORTB.
    • Texto/bitmap invertido: verifica la función que genera el array (MSB-first) y la dirección de bits en glcd_DrawPixel() (b = 15 - (x%16)).

    Documento generado para el driver definitivo GDM12864-5 (ST7920) con PIC18F25K22 y CCS C.

Este driver probado físicamente permite un control completo del GLCD, integrando gráficos y texto en proyectos embebidos de forma eficiente.