LCD Creación de símbolos en CGRAM


Programa de prueba para cargar la memoria CGRAM del LCD con controlador HD44780, la misma se accede (mediante la librería disponible en el compilador CCS) con la instrucción lcd_send_byte(a,b) donde “a” es el valor binario que le dirá si es el origen del bloque de memoria [a=0] o si es dato a grabar en el mismo [a=1] y por otro lado “b” será el dato a grabar en hexadecimal.

Por ejemplo para grabar el siguiente símbolo:



En la tabla se ve el equivalente hexadecimal del binario representado con rojo y azul: 
01110 = 0x0E De esta misma forma se realizan el resto de los bits para formar el mapa de bits a guardar en la CGRAM.

La memoria CGRAM posee solo 8 caracteres posibles para crear, donde el origen de dicho vector de memoria será el 0x40, desde ahí comenzara a crearse cada carácter de 8 direcciones cada uno y palabra de 5bit.

Por ejemplo primer Vector 0x40, le sumamos las 8 direcciones de datos y nos quedara el próximo vector en 0x48, nuevamente le sumamos las 8 direcciones (la suma es siempre hexadecimal) y nos quedara 0x50, y así sucesivamente… 0x58, 0x60, 0x68, …. Etc.

Como se puede ver en el programa de ejemplo se cargan solo 6 caracteres los cuales el primero posee ceros que lo utiliza para generar un blanco, y los otros 5 son barras verticales que se van incrementando: |, ||, |||, ||||, |||||. Esto da la ilusión óptica de una barra de progreso.

Nótese que para cargar estos valores se indica el vector de origen con a=0 y seguido el origen 0x40 quedando asi  lcd_send_byte(0,0x40);, luego para ingresar los datos se debe llevar a nivel alto la variable a, y poner el dato en hexadecimal como mencionábamos,

lcd_send_byte(1,0x04); , lcd_send_byte(1,0x0E); , lcd_send_byte(1,0x1F); , lcd_send_byte(1,0x1F); , lcd_send_byte(1,0x04); , lcd_send_byte(1,0x04); , lcd_send_byte(1,0x14); , lcd_send_byte(1,0x08) ;.

Así creamos el dibujo de la tabla de arriba (un paragua).

Una vez cargada la CGRAM con nuestro carácter especial, debemos mostrarla en el LCD, para ello le decimos donde mediante la instrucción gotoxy(x,y);  seguida de la misma instrucción lcd_send_byte(1,0); Donde 1 será el valor que nos dice que es un dato y 0 será el carácter 0.

Como hemos creado solo un carácter (el paragua) solo tendremos 0, pero en el programa que se muestra a continuación se puede ver que ese 0, se va incrementando según la cantidad de caracteres creados en la CGRAM que como mencionaba antes solo son 8
 (por ende ira del 0 al 7).
En el programa que se muestra a continuacion se simula una barra de progreso que aumenta y disminuye cilcicamente, es solo a modo ejemplo.

#include<16f883.h>
#use delay(int=4000000)
#include<LCD.C> 
void main()
{
   lcd_init();                //Inicializa LCD

                              //Caracter 0 creado en CGRAM
   lcd_send_byte(0,0x68);     //Origen en 0x40
   lcd_send_byte(1,0x00);     //00000
   lcd_send_byte(1,0x00);     //00000
   lcd_send_byte(1,0x00);     //00000
   lcd_send_byte(1,0x00);     //00000
   lcd_send_byte(1,0x00);     //00000
   lcd_send_byte(1,0x00);     //00000
   lcd_send_byte(1,0x00);     //00000
   lcd_send_byte(1,0x00);     //00000

                              //Caracter 1 creado en CGRAM
   lcd_send_byte(0,0x40);     //Origen en 0x48
   lcd_send_byte(1,0x10);     //10000
   lcd_send_byte(1,0x10);     //10000
   lcd_send_byte(1,0x10);     //10000
   lcd_send_byte(1,0x10);     //10000
   lcd_send_byte(1,0x10);     //10000
   lcd_send_byte(1,0x10);     //10000
   lcd_send_byte(1,0x10);     //10000
   lcd_send_byte(1,0x10);     //10000

                              //Caracter 2 creado en CGRAM
   lcd_send_byte(0,0x48);     //Origen en 0x50
   lcd_send_byte(1,0x18);     //11000
   lcd_send_byte(1,0x18);     //11000
   lcd_send_byte(1,0x18);     //11000
   lcd_send_byte(1,0x18);     //11000
   lcd_send_byte(1,0x18);     //11000
   lcd_send_byte(1,0x18);     //11000
   lcd_send_byte(1,0x18);     //11000
   lcd_send_byte(1,0x18);     //11000

                              //Caracter 3 creado en CGRAM
   lcd_send_byte(0,0x50);     //Origen en 0x58
   lcd_send_byte(1,0x1C);     //11100
   lcd_send_byte(1,0x1C);     //11100
   lcd_send_byte(1,0x1C);     //11100
   lcd_send_byte(1,0x1C);     //11100
   lcd_send_byte(1,0x1C);     //11100
   lcd_send_byte(1,0x1C);     //11100
   lcd_send_byte(1,0x1C);     //11100
   lcd_send_byte(1,0x1C);     //11100

                              //Caracter 4 creado en CGRAM
   lcd_send_byte(0,0x58);     //Origen en 0x60
   lcd_send_byte(1,0x1E);     //11110
   lcd_send_byte(1,0x1E);     //11110
   lcd_send_byte(1,0x1E);     //11110
   lcd_send_byte(1,0x1E);     //11110
   lcd_send_byte(1,0x1E);     //11110
   lcd_send_byte(1,0x1E);     //11110
   lcd_send_byte(1,0x1E);     //11110
   lcd_send_byte(1,0x1E);     //11110

                              //Caracter 5 creado en CGRAM
   lcd_send_byte(0,0x60);     //Origen en 0x68
   lcd_send_byte(1,0x1F);     //11111
   lcd_send_byte(1,0x1F);     //11111
   lcd_send_byte(1,0x1F);     //11111
   lcd_send_byte(1,0x1F);     //11111
   lcd_send_byte(1,0x1F);     //11111
   lcd_send_byte(1,0x1F);     //11111
   lcd_send_byte(1,0x1F);     //11111
   lcd_send_byte(1,0x1F);     //11111

   int i;                     //Variable del contador de los lazos for

   while(true){               //Ciclo infinito

      for(i=1;i<17;i++){      //Incremento de los caracteres creados

         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,1);  //Caracter 1 creado en CGRAM (0x40)
         delay_ms(10);        //Demora de 10ms
         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,2);  //Caracter 2 creado en CGRAM (0x48)
         delay_ms(10);        //Demora de 10ms
         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,3);  //Caracter 3 creado en CGRAM (0x50)
         delay_ms(10);        //Demora de 10ms
         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,4);  //Caracter 4 creado en CGRAM (0x58)
         delay_ms(10);        //Demora de 10ms
         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,5);  //Caracter 5 creado en CGRAM (0x60)
         delay_ms(10);        //Demora de 10ms
      }
      
      for(i=17;i>1;i--){      //Decremento de los caracteres creados

         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,5);  //Caracter 5 creado en CGRAM (0x60)
         delay_ms(10);        //Demora de 10ms
         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,4);  //Caracter 4 creado en CGRAM (0x58)
         delay_ms(10);        //Demora de 10ms
         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,3);  //Caracter 3 creado en CGRAM (0x50)
         delay_ms(10);        //Demora de 10ms
         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,2);  //Caracter 2 creado en CGRAM (0x48)
         delay_ms(10);        //Demora de 10ms
         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,1);  //Caracter 1 creado en CGRAM (0x40)
         delay_ms(10);        //Demora de 10ms
         lcd_gotoxy(i,2);     //Posición del cursor en el LCD x=i,y=2
         lcd_send_byte(1,0);  //Caracter 0 creado en CGRAM (0x68)
         delay_ms(10);        //Demora de 10ms
      }
   }
}