/////////////////////////////////////////////////////////////////////////
// Conexiones de pines del GLCD GTK-281 de GEM-TECH //
// El Patillaje esta indicado abajo, del lado del GLCD //
// y del Lado del PIC 18F-4550 //
// Sirve para Controladores como el NT7534 y el SED1565 //
// (Tambien puede ocuparse con el GLCD 12864F3, //
// Pero el patillaje es distinto) //
// //
// ------------------------------------ //
// GLCD GTK-281 --- PIC 18F4550 //
// ------------------------------------ //
// 17: Reset <-> A4 :6 //
// 4: A0 <-> C2 :17 //
// 5: R/W <-> C1 :16 //
// 6: E <-> C0 :15 //
// 7..14: D0..D7 <-> B0..B7 :33..40 //
// ------------------------------------ //
// //
// Los valores pueden cambiarse con los DEFINE que están más abajo //
//---------------------------------------------------------------------//
// > GLCD_clear(color) //
// "Borra" la pantala, llenando la del color seleccionado. //
// color = 0 : puntos apagados //
// color = 1 : puntos encendidos //
// //
//---------------------------------------------------------------------//
// > GLCD_init(modo) //
// Inicializa el GLCD, y debe llamarse ANTES de cualquier otra. //
// modo = 0 : GLCD en ON //
// modo = 1 : GLCD en OFF //
// //
// EN LAS SIGUIENTES FUNCIONES, SIEMPRE SE RESPETA QUE: //
// color = 0 : puntos apagados //
// color = 1 : puntos encendidos //
// Tambien puede usarse directamente ON / OFF //
// //
// > GLCD_pixel(x,y,color) //
// Dibuja un punto en x,y. 0,0 es la esquina superior izquierda. //
// //
// > GLCD_line(x1,y1,x2,y2,color) //
// Dibuja una linea desde (x1,y1) a (x2,y2) //
// //
// >GLCD_rectangle (x1,y1,x2,y2,color) //
// Dibuja un rectangulo con esquinas en (x1,y1) y (x2,y2) //
// //
// >GLCD_box (x1,y1,x2,y2,color) //
// Dibuja un rectangulo pintado con esquinas en (x1,y1) y (x2,y2) //
// //
// >GLCD_circle (x1,y1,r,color) //
// Dibuja un circulo con centro en (x1,y1) y radio R //
// //
// >GLCD_text35(x,y,textptr,color) //
// Escribe un texto de pequeñas dimensiones //
// (x,y) - Coordenada superior izquierda del primer caracter //
// textptr - Puntero a una matriz de caracteres del texto a mostrar //
// //
/////////////////////////////////////////////////////////////////////////
#include <STDLIB.H>
//Pines a usar
#define GLCD_RESET PIN_C4
#define GLCD_A0 PIN_C2
#define GLCD_RW PIN_C1
#define GLCD_E PIN_C0
#define GLCD_TRIS set_tris_b
#define GLCD_SAL output_b
#define GLCD_ENT input_b
//Definiciones varias
#define GLCD_WIDTH 128
#define ON 1
#define OFF 0
// Declaracion de funciones
void GLCD_Data(BYTE dato);
void GLCD_Command(BYTE dato);
BYTE GLCD_readBYTE();
void GLCD_clear(int1 color);
void GLCD_init(int1 modo);
void GLCD_pixel(int8 x, int8 y, int1 color);
void GLCD_line(int x1, int y1, int x2, int y2, int1 color);
void GLCD_rectangle(int x1, int y1, int x2, int y2, int1 color);
void GLCD_box(int x1, int y1, int x2, int y2, int1 color);
void GLCD_circle(int x1, int y1, int radio, int1 color);
void glcd_text35(int8 x, int8 y, char* textptr, int1 color);
const int8 TEXT35[95][5]={
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, //SPACE
0b01000100, 0b01000100, 0b01000100, 0b00000000, 0b01000100, //!
0b10101010, 0b10101010, 0b00000000, 0b00000000, 0b00000000, //"
0b10101010, 0b11101110, 0b10101010, 0b11101110, 0b10101010, //#
0b01100110, 0b11001100, 0b11001100, 0b01100110, 0b11101110, //$
0b10101010, 0b00100010, 0b01000100, 0b10001000, 0b10101010, //%
0b01000100, 0b10101010, 0b01000100, 0b10101010, 0b01100110, //&
0b01000100, 0b01000100, 0b00000000, 0b00000000, 0b00000000, //'
0b01000100, 0b10001000, 0b10001000, 0b10001000, 0b01000100, //(
0b01000100, 0b00100010, 0b00100010, 0b00100010, 0b01000100, //)
0b00000000, 0b10101010, 0b01000100, 0b10101010, 0b00000000, //*
0b00000000, 0b01000100, 0b11101110, 0b01000100, 0b00000000, //+
0b00000000, 0b00000000, 0b00000000, 0b01000100, 0b10001000, //,
0b00000000, 0b00000000, 0b11101110, 0b00000000, 0b00000000, //-
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b01000100, //.
0b00100010, 0b00100010, 0b01000100, 0b10001000, 0b10001000, ///
0b11101110, 0b10101010, 0b10101010, 0b10101010, 0b11101110, //0
0b01000100, 0b11001100, 0b01000100, 0b01000100, 0b11101110, //1
0b11101110, 0b00100010, 0b11101110, 0b10001000, 0b11101110, //2
0b11101110, 0b00100010, 0b11101110, 0b00100010, 0b11101110, //3
0b10101010, 0b10101010, 0b11101110, 0b00100010, 0b00100010, //4
0b11101110, 0b10001000, 0b11101110, 0b00100010, 0b11101110, //5
0b11001100, 0b10001000, 0b11101110, 0b10101010, 0b11101110, //6
0b11101110, 0b00100010, 0b01000100, 0b10001000, 0b10001000, //7
0b11101110, 0b10101010, 0b11101110, 0b10101010, 0b11101110, //8
0b11101110, 0b10101010, 0b11101110, 0b00100010, 0b01100110, //9
0b00000000, 0b01000100, 0b00000000, 0b01000100, 0b00000000, //:
0b00000000, 0b01000100, 0b00000000, 0b01000100, 0b10001000, //;
0b00100010, 0b01000100, 0b10001000, 0b01000100, 0b00100010, //<
0b00000000, 0b11101110, 0b00000000, 0b11101110, 0b00000000, //=
0b10001000, 0b01000100, 0b00100010, 0b01000100, 0b10001000, //>
0b11001100, 0b00100010, 0b01100110, 0b00000000, 0b01000100, //?
0b01000100, 0b10101010, 0b11101110, 0b10001000, 0b01100110, //@
0b11101110, 0b10101010, 0b11101110, 0b10101010, 0b10101010, //A
0b11001100, 0b10101010, 0b11101110, 0b10101010, 0b11001100, //B
0b11101110, 0b10001000, 0b10001000, 0b10001000, 0b11101110, //C
0b11001100, 0b10101010, 0b10101010, 0b10101010, 0b11001100, //D
0b11101110, 0b10001000, 0b11101110, 0b10001000, 0b11101110, //E
0b11101110, 0b10001000, 0b11101110, 0b10001000, 0b10001000, //F
0b11101110, 0b10001000, 0b10001000, 0b10101010, 0b11101110, //G
0b10101010, 0b10101010, 0b11101110, 0b10101010, 0b10101010, //H
0b11101110, 0b01000100, 0b01000100, 0b01000100, 0b11101110, //I
0b00100010, 0b00100010, 0b00100010, 0b10101010, 0b11101110, //J
0b10001000, 0b10101010, 0b11001100, 0b11001100, 0b10101010, //K
0b10001000, 0b10001000, 0b10001000, 0b10001000, 0b11101110, //L
0b10101010, 0b11101110, 0b11101110, 0b10101010, 0b10101010, //M
0b00000000, 0b11001100, 0b10101010, 0b10101010, 0b10101010, //N
0b01000100, 0b10101010, 0b10101010, 0b10101010, 0b01000100, //O
0b11101110, 0b10101010, 0b11101110, 0b10001000, 0b10001000, //P
0b01000100, 0b10101010, 0b10101010, 0b11101110, 0b01100110, //Q
0b11101110, 0b10101010, 0b11001100, 0b11101110, 0b10101010, //R
0b11101110, 0b10001000, 0b11101110, 0b00100010, 0b11101110, //S
0b11101110, 0b01000100, 0b01000100, 0b01000100, 0b01000100, //T
0b10101010, 0b10101010, 0b10101010, 0b10101010, 0b11101110, //U
0b10101010, 0b10101010, 0b10101010, 0b10101010, 0b01000100, //V
0b10101010, 0b10101010, 0b11101110, 0b11101110, 0b10101010, //W
0b00000000, 0b10101010, 0b01000100, 0b01000100, 0b10101010, //X
0b10101010, 0b10101010, 0b01000100, 0b01000100, 0b01000100, //Y
0b11101110, 0b00100010, 0b01000100, 0b10001000, 0b11101110, //Z
0b11101110, 0b10001000, 0b10001000, 0b10001000, 0b11101110, //[
0b10001000, 0b10001000, 0b01000100, 0b00100010, 0b00100010, //\
0b11101110, 0b00100010, 0b00100010, 0b00100010, 0b11101110, //]
0b01000100, 0b10101010, 0b00000000, 0b00000000, 0b00000000, //^
0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11101110, //_
0b10001000, 0b01000100, 0b00000000, 0b00000000, 0b00000000, //`
0b00000000, 0b01000100, 0b10101010, 0b10101010, 0b01100110, //a
0b10001000, 0b11001100, 0b10101010, 0b10101010, 0b11001100, //b
0b00000000, 0b01100110, 0b10001000, 0b10001000, 0b01100110, //c
0b00100010, 0b01100110, 0b10101010, 0b10101010, 0b01100110, //d
0b00000000, 0b01000100, 0b10101010, 0b11001100, 0b01100110, //e
0b01100110, 0b01000100, 0b11101110, 0b01000100, 0b01000100, //f
0b00000000, 0b01000100, 0b10101010, 0b01100110, 0b11001100, //g
0b10001000, 0b11001100, 0b10101010, 0b10101010, 0b10101010, //h
0b01000100, 0b00000000, 0b01000100, 0b01000100, 0b01000100, //i
0b01000100, 0b00000000, 0b01000100, 0b01000100, 0b10001000, //j
0b10001000, 0b10001000, 0b10101010, 0b11001100, 0b10101010, //k
0b01000100, 0b01000100, 0b01000100, 0b01000100, 0b01000100, //l
0b00000000, 0b11101110, 0b11101110, 0b10101010, 0b10101010, //m
0b00000000, 0b11001100, 0b10101010, 0b10101010, 0b10101010, //n
0b00000000, 0b01000100, 0b10101010, 0b10101010, 0b01000100, //o
0b00000000, 0b11001100, 0b10101010, 0b11001100, 0b10001000, //p
0b00000000, 0b01100110, 0b10101010, 0b01100110, 0b00100010, //q
0b00000000, 0b10001000, 0b11101110, 0b10001000, 0b10001000, //r
0b00000000, 0b01100110, 0b11001100, 0b00100010, 0b11001100, //s
0b01000100, 0b11101110, 0b01000100, 0b01000100, 0b01000100, //t
0b00000000, 0b10101010, 0b10101010, 0b10101010, 0b01000100, //u
0b00000000, 0b10101010, 0b10101010, 0b01000100, 0b01000100, //v
0b00000000, 0b10101010, 0b10101010, 0b11101110, 0b10101010, //w
0b00000000, 0b10101010, 0b01000100, 0b01000100, 0b10101010, //x
0b00000000, 0b10101010, 0b10101010, 0b01100110, 0b11001100, //y
0b00000000, 0b11101110, 0b01100110, 0b11001100, 0b11101110, //z
0b00100010, 0b01000100, 0b11001100, 0b01000100, 0b00100010, //{
0b01000100, 0b01000100, 0b01000100, 0b01000100, 0b01000100, //|
0b10001000, 0b01000100, 0b01100110, 0b01000100, 0b10001000, //}
0b00000000, 0b11001100, 0b10101010, 0b00000000, 0b00000000 //~
};
//-----------------------------------------------------------------------
//Escribe un byte en la pantalla
//-----------------------------------------------------------------------
void GLCD_Data(BYTE dato)
{
output_low (GLCD_RW); // Modo escritura
output_high (GLCD_A0); // Modo escritura
GLCD_SAL (dato); // Coloco el dato a escribir
output_high (GLCD_E); // Aviso que hay un dato a escribir
delay_cycles( 2 ); // Espero
output_low (GLCD_E); // Termino la escritura del dato
delay_cycles( 2 ); // Espero
}
//-----------------------------------------------------------------------
//Envía un comando a GLCD
//-----------------------------------------------------------------------
void GLCD_Command(BYTE dato)
{
output_low (GLCD_RW); // Modo comando
output_low (GLCD_A0); // Modo comando
GLCD_SAL (dato); // Coloco el Comando a escribir
output_high (GLCD_E); // Aviso que estoy enviado un comando
delay_cycles( 2 ); // Espero
output_low (GLCD_E); // Termino el envío del comando
delay_cycles( 2 ); // Espero
}
//-----------------------------------------------------------------------
// Lee un byte de la pantalla
//-----------------------------------------------------------------------
BYTE GLCD_readBYTE()
{
BYTE dato;
GLCD_TRIS (0xFF); // Todo el Puerto como entrada de datos
output_high (GLCD_RW); // Modo lectura
output_high (GLCD_A0); // Modo lectura
output_high (GLCD_E); // Activo la lectura
delay_cycles( 2 ); // Espero
output_low (GLCD_E); // lectura tonta
delay_cycles( 2 ); // Espero
output_high (GLCD_E); // Activo la lectura
delay_cycles( 2 ); // Espero
dato = GLCD_ENT(); // Guardo en "dato" el valor devuelto
output_low (GLCD_E); // Termino la lectura
output_low (GLCD_RW); // Modo comando
output_low (GLCD_A0); // Modo comando
GLCD_SAL (0x00); // Limpio el Puerto de salida
GLCD_TRIS (0x00); // Todo el Puerto como salida de datos
return dato; // Retorno de la rutina con el dato
}
//-----------------------------------------------------------------------
// Limpia el GLCD (pinta toda la pantalla de un color)
//-----------------------------------------------------------------------
void GLCD_clear(int1 color)
{
int8 i, j;
for(i = 0; i < 7; ++i) // Recorre las 8 paginas (vertical)
{
for(j = 0; j < 127; ++j) // Recorre los 128 segmentos (horizontal)
{ GLCD_Data(0xFF * color); // Enciende/apaga pixeles
}
}
}
//-----------------------------------------------------------------------
//Esta funcion inicializa el LCD.
//-----------------------------------------------------------------------
void GLCD_init(int1 modo)
{
// Pone los pines de control en el estado correcto.
output_low(GLCD_RESET);
delay_ms(1);
output_high(GLCD_RESET);
GLCD_Command(0x40); // Linea Inicial = 0
GLCD_Command(0xA0); // ADC = normal
GLCD_Command(0xA3); // LCD-Bias = 1/7
GLCD_Command(0xC0); // output mode
GLCD_Command(0xAC); // static indicator = 0
GLCD_Command(0xA4); // Todos los pixeles apagados
GLCD_Command(0xA6); // Display no Invertido
GLCD_Command(0xE0); // read/modify/write
// Si modo = 1 inicializa encendido. Sino, apagado.
if(modo == 1)
{ GLCD_Command(0xAF); } // Enciendo el GLCD
else {
GLCD_Command(0xAE); } // Apago el GLCD
}
//-----------------------------------------------------------------------
// Dibuja un pixel
//-----------------------------------------------------------------------
void GLCD_pixel(int8 x, int8 y, int1 color)
{
BYTE dato;
int8 Posicion_Y;
int8 Posicion_X;
x = 127-x;
y = 63-y;
//Primero verificar que X e Y estan dentro de los límites
if ((x<=127)&(y<=63)){
Posicion_Y = y / 8; // Calculo La página a donde pertenece el bit
Posicion_Y = 0xB0 + Posicion_Y; // Genero el comando para ir a la página
GLCD_Command(Posicion_Y); // Ejecuto el comando
Posicion_X = x;
swap(Posicion_X);
Posicion_X &= 0x0F;
Posicion_X |= 0x10;
GLCD_Command(Posicion_X);
Posicion_X = x;
Posicion_X &= 0x0F;
GLCD_Command(Posicion_X);
dato = GLCD_ReadBYTE();
if(color == 1)
bit_set(dato, y%8); // Turn the pixel on
else // or
bit_clear(dato, y%8); // turn the pixel off
GLCD_Data(dato);
}
}
//-----------------------------------------------------------------------
// Dibuja una linea desde (x1,y1) a (x2,y2) de color (0 o 1)
//-----------------------------------------------------------------------
void GLCD_line(int x1, int y1, int x2, int y2, int1 color)
{
//Declaro variables-------------------
signed int x, y, incremento_x, incremento_y, distancia_x, distancia_y;
signed long P;
int i;
//Calculo las diferencias entre las coordenadas de origen y destino
distancia_x = abs((signed int)(x2 - x1));
distancia_y = abs((signed int)(y2 - y1));
//Inicializo x e y con las coordenadas de origen
x = x1;
y = y1;
//Calculo el sentido de los incrementos (positivos o negativos)
//en funcion de la posicion del origen y el destino
if(x1 > x2) incremento_x = -1; else incremento_x = 1;
if(y1 > y2) incremento_y = -1; else incremento_y = 1;
//Si la distancia horizontal es mayor a la vertical...
if(distancia_x >= distancia_y)
{ P = 2 * distancia_y - distancia_x;
for(i=0; i<=distancia_x; ++i)
{
GLCD_pixel(x, y, color);
if(P < 0)
{ P += 2 * distancia_y;
x += incremento_x; }
else
{ P += 2*distancia_y - 2*distancia_x;
x += incremento_x;
y += incremento_y;}
}
}
//Si la distancia vertical es mayor a la horizontal...
else
{ P = 2 * distancia_x - distancia_y;
for(i=0; i<=distancia_y; ++i)
{ GLCD_pixel(x, y, color);
if(P < 0)
{ P += 2 * distancia_x;
y += incremento_y; }
else
{ P += 2 * distancia_x - 2 * distancia_y;
x += incremento_x;
y += incremento_y; }
}
}
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// Dibuja un rectángulo desde (x1,y1) a (x2,y2) de color (0 o 1)
//-----------------------------------------------------------------------
void GLCD_rectangle(int x1, int y1, int x2, int y2, int1 color)
{
GLCD_line(x1,y1,x2,y1,color);
GLCD_line(x1,y1,x1,y2,color);
GLCD_line(x1,y2,x2,y2,color);
GLCD_line(x2,y1,x2,y2,color);
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// Dibuja un rectángulo PINTADO desde (x1,y1) a (x2,y2) de color (0 o 1)
//-----------------------------------------------------------------------
void GLCD_box(int x1, int y1, int x2, int y2, int1 color)
{
//Declaro variables-------------------
int i;
for(i=y1;i<=y2;i++) {
GLCD_line(x1,i,x2,i,color); }
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// Dibuja un circulo con centro en (x1,y1), radio y color (0 o 1)
//-----------------------------------------------------------------------
void GLCD_circle(int x1, int y1, int radio, int1 color)
{
signed int d, x, y;
//Inicializo las variables.
d = 1 - radio;
x = 0;
y = radio;
//Dibujo los cuatro pixeles que "caen" sobre los ejes cartesianos.
GLCD_pixel(x1, y1 + radio, color);
GLCD_pixel(x1, y1 - radio, color);
GLCD_pixel(x1 + radio, y1, color);
GLCD_pixel(x1 - radio, y1, color);
//Este es el bucle que pinta los octavos de la circunferencia.
while(x < y) {
if(d < 0) {d = d + 2 * x + 3;}
else {d = d + 2 * (x - y ) + 5;
y = y - 1 ;}
x = x + 1;
//Pone el punto en cada uno de los "octantes".
GLCD_pixel(x1 + x, y1 + y, color);
GLCD_pixel(x1 - x, y1 + y, color);
GLCD_pixel(x1 + x, y1 - y, color);
GLCD_pixel(x1 - x, y1 - y, color);
GLCD_pixel(x1 + y, y1 + x, color);
GLCD_pixel(x1 - y, y1 + x, color);
GLCD_pixel(x1 + y, y1 - x, color);
GLCD_pixel(x1 - y, y1 - x, color);
}
}
//char characterSet[] = " !#$%&'()*+,-./0123456789:;=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
void GLCD_text35(int8 x, int8 y, char* textptr, int1 color)
{
int i, j, k; // Loop counters
BYTE pixelData[5]; // Stores character data
for(i=0; textptr[i] != '\0'; ++i, ++x) // Loop through the passed string
{
if((textptr[i] >= ' ') && (textptr[i] <= '~'))
memcpy(pixelData, TEXT35[textptr[i]-' '], 5);
else
memcpy(pixelData, TEXT35[0], 5); // Default to space
if(x+3 >= GLCD_WIDTH) // Performs character wrapping
{
x = 0; // Set x at far left position
y += 5 + 1; // Set y at next position down
}
for(j=3; j>0; j--, x++) // Loop through character byte data
{
for(k=0; k<5; k++) // Loop through the vertical pixels
{
if(bit_test(pixelData[k], j)) // Check if the pixel should be set
{
glcd_pixel(x, y+k, color); // Draws the pixel
}
}
}
}
}