Versión para GLCD con chip SED1565
El amigo
Ruben Arranz nos ha mandado una version de esta libreria para displays que integran el chipset
SED1565. Aquí está:
/////////////////////////////////////////////////////////////////////////
// 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
}
}
}
}
}
¡Gracias Ruben! 
Restricciones legales de CCS
Como deciamos en la introducción, dentro de las librerias incluidas en CCS se ha incluido una especie de licencia. Concretamente, en el código fuente de dichas librerias puede leerse algo como lo siguiente:
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996, 2004 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////
Esto, traducido al español significa más o menos lo siguiente:
"
Este código fuente sólo puede ser utilizado por usuarios con licencia del compilador C CCS. Este código fuente sólo puede ser distribuido a otros usuarios con licencia del compilador C CCS. No se permite ningún otro uso, reproducción o distribución sin el consentimiento escrito. Los programas derivados, creados utilizando este software, pueden distribuirse como código objeto sin limitantes."