Aqui va.
Es algo extenso, pero no complicado.
El programa "principal" es este: calculadora.c
//-------------------------------------------------------------------//
// CALCULADORA CIENTIFICA GRAFICA
// Programa principal
//-------------------------------------------------------------------//
//-------------------------------------------------------------------//
// Includes
//-------------------------------------------------------------------//
#include <16f877a.h>
// Fuses ------------------------------------------------------------//
// Configuracion del PIC
//-------------------------------------------------------------------//
// Aqui hay mucho por corregir todavia. No he mirado tooodos los fuses
// que tiene este PIC
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
//#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN
#use delay(clock=4000000)
//#use fast_io(b) //Optimizamos E/S del PORTB
//#use fast_io(c) //Optimizamos E/S del PORTC
//#use fast_io(d) //Optimizamos E/S del PORTD
//#use fast_io(e) //Optimizamos E/S del PORTE
// Bits & Bytes -----------------------------------------------------//
// Declaro la direccion de los puertos.
//-------------------------------------------------------------------//
#BYTE PORTA = 0x05
#BYTE PORTB = 0x06
#BYTE PORTC = 0x07
#BYTE PORTD = 0x08
#BYTE PORTE = 0x09
//Defines -----------------------------------------------------------//
// Declaro el uso de cada pin de E/S
//-------------------------------------------------------------------//
#define VERSION 1 //1=Pinout PCB Ariel - 2=Pinout Version Felixls
#if VERSION == 1 //Pinout PCB Ariel
#define COL1 PIN_E0 //Columna 1 del teclado.
#define COL2 PIN_A5 //Columna 2 del teclado.
#define COL3 PIN_A4 //Columna 3 del teclado.
#define COL4 PIN_A3 //Columna 4 del teclado.
#define COL5 PIN_A2 //Columna 5 del teclado.
#define COL6 PIN_A1 //Columna 6 del teclado.
#define COL7 PIN_A0 //Columna 7 del teclado.
#define FILA1 PIN_D2 //Fila 1 del teclado.
#define FILA2 PIN_D3 //Fila 2 del teclado.
#define FILA3 PIN_D0 //Fila 3 del teclado.
#define FILA4 PIN_D1 //Fila 4 del teclado.
#define FILA5 PIN_D7 //Fila 5 del teclado.
#define FILA6 PIN_D6 //Fila 6 del teclado.
#define FILA7 PIN_D5 //Fila 7 del teclado.
#define FILA8 PIN_D4 //Fila 8 del teclado.
#define GLCD_CS1 PIN_B2 //CS1 del GLCD
#define GLCD_CS2 PIN_B3 //CS2 del GLCD
#define GLCD_RESET PIN_B4 //RESET del GLCD
#define GLCD_E PIN_B5 //Enable del GLCD
#define GLCD_RW PIN_B6 //RW del GLCD
#define GLCD_DI PIN_B7 //DI del GLCD
#DEFINE EEPROM_SCL PIN_B1
#DEFINE EEPROM_SDA PIN_B0
#else //Pinout Version Felixls
//Felixls....a lo tuyo! :)
#endif
//Defines -----------------------------------------------------------//
// Declaro el uso del bus i2c
//-------------------------------------------------------------------//
//#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
//#define EEPROM_ADDRESS long int
#include <string.h>
//Incluyo la libreria gráfica---------------------------------------//
//Lados del GLCD
#define GLCD_lado_CS1 0
#define GLCD_lado_CS2 1
BYTE GLCD_leeBYTE(int1 lado);
//-----------------------------------------------------------------------
//Escribe un byte en una de las mitades de la pantalla (lado=0:izq Lado=1:der)
//-----------------------------------------------------------------------
void GLCD_enviaBYTE(int1 lado, BYTE dato)
{
if(lado) output_high(GLCD_CS2); // Selecciono la mitad correspondiente
else output_high(GLCD_CS1);
output_low(GLCD_RW); // Modo escritura
output_d(dato); // Coloco el dato en el puerto y...
delay_us(1); // ...espero.
output_high(GLCD_E); // Pongo el bit Enable en alto y...
delay_us(2); // ...espero.
output_low(GLCD_E); // Pongo el bit Enable en bajo.
output_low(GLCD_CS1); // Libero la linea CS1 y...
output_low(GLCD_CS2); // CS2.
}
//-----------------------------------------------------------------------
// Lee un byte de una de las dos mitades de la pantalla
//-----------------------------------------------------------------------
BYTE GLCD_leeBYTE(int1 lado)
{
BYTE dato;
set_tris_d(0xFF); // Puerto D como entrada
output_high(GLCD_RW); // GLCD en Modo lectura
// Selecciono la mitad del display a leer.
if(lado) output_high(GLCD_CS2);
else output_high(GLCD_CS1);
delay_us(1); // Espero...
output_high(GLCD_E); // Pongo en alto el pin enable y...
delay_us(2); // ...espero.
dato = input_d(); // Guardo en "dato" el valor devuelto y...
output_low(GLCD_E); // ...pongo en bajo el pin enable.
// Vuelvo a poner en bajo las lineas CS1 y CS2.
output_low(GLCD_CS1);
output_low(GLCD_CS2);
return dato;
}
//-----------------------------------------------------------------------
// Limpia el GLCD (pinta toda la pantalla de un color)
//-----------------------------------------------------------------------
void GLCD_limpiar(int1 color)
{
int8 i, j;
// Recorre las 8 paginas (vertical)
for(i = 0; i < 8; ++i)
{
output_low(GLCD_DI); // Modo instruccion
//Comienzo, en cada página, desde la dirección 0
GLCD_enviaBYTE(GLCD_lado_CS1, 0b01000000);
GLCD_enviaBYTE(GLCD_lado_CS2, 0b01000000);
//Selecciono la direccion dentro de la pagina
GLCD_enviaBYTE(GLCD_lado_CS1, i | 0b10111000);
GLCD_enviaBYTE(GLCD_lado_CS2, i | 0b10111000);
output_high(GLCD_DI); // Modo datos
// Recorre las dos mitades (horizontales)
for(j = 0; j < 64; ++j)
{ GLCD_enviaBYTE(GLCD_lado_CS1, 0xFF * color); // Enciende/apaga pixeles
GLCD_enviaBYTE(GLCD_lado_CS2, 0xFF * color); // Enciende/apaga pixeles
}
}
}
//-----------------------------------------------------------------------
//Esta funcion inicializa el LCD.
//-----------------------------------------------------------------------
void GLCD_inicializa(int1 modo)
{
// Pone los pines de control en el estado correcto.
output_high(GLCD_RESET);
output_low(GLCD_E);
output_low(GLCD_CS1);
output_low(GLCD_CS2);
output_low(GLCD_DI); // Modo instruccion
// Envio datos de inicialización -----------------------
GLCD_enviaBYTE(GLCD_lado_CS1, 0xC0);
GLCD_enviaBYTE(GLCD_lado_CS2, 0xC0);
GLCD_enviaBYTE(GLCD_lado_CS1, 0x40);
GLCD_enviaBYTE(GLCD_lado_CS2, 0x40);
GLCD_enviaBYTE(GLCD_lado_CS1, 0xB8);
GLCD_enviaBYTE(GLCD_lado_CS2, 0xB8);
// Si modo = 1 inicializa encendido. Sino, apagado.
if(modo == 1)
{ GLCD_enviaBYTE(GLCD_lado_CS1, 0x3F); // Enciendo el GLCD
GLCD_enviaBYTE(GLCD_lado_CS2, 0x3F); }
else {
GLCD_enviaBYTE(GLCD_lado_CS1, 0x3E); // Apago el GLCD
GLCD_enviaBYTE(GLCD_lado_CS2, 0x3E); }
// Borro la pantalla
GLCD_limpiar(0);
}
//-----------------------------------------------------------------------
// Dibuja un pixel
//-----------------------------------------------------------------------
void GLCD_punto(int8 x, int8 y, int1 color)
{
BYTE dato;
int1 lado = GLCD_lado_CS1; // Lado en que voy a dibujar.
if(x > 63) // Veo si cae del otro lado
{ x -= 64;
lado = GLCD_lado_CS2;}
output_low(GLCD_DI); // Modo instruccion
bit_clear(x,7); // Limpio bit MSB...
bit_set(x,6); // ...y pongo el bit 6 en 1
GLCD_enviaBYTE(lado, x); //Envio la dirección de la coordenada X
// Calculo en que pagina de las 8 cae...
GLCD_enviaBYTE(lado, (y/8 & 0xBF) | 0xB8);
output_high(GLCD_DI); // ...y paso a Modo datos
//Se necesitan dos lecturas para que devuelva el dato en la nueva direccion
GLCD_leeBYTE(lado);
dato = GLCD_leeBYTE(lado);
//De acuerdo al valor de color...
if(color == 1) bit_set(dato, y%8); // Enciendo el pixel
else bit_clear(dato, y%8); // apago el pixel
output_low(GLCD_DI); // Modo instruccion
GLCD_enviaBYTE(lado, x); // Fijo el lado a escribir,
output_high(GLCD_DI); // pongo en Modo Datos y....
GLCD_enviaBYTE(lado, dato); // dibujo el pixel
}
//-----------------------------------------------------------------------
// Dibuja una linea desde (x1,y1) a (x2,y2) de color (0 o 1)
//-----------------------------------------------------------------------
void GLCD_linea(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_punto(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_punto(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_rectangulo(int x1, int y1, int x2, int y2, int1 color)
{
GLCD_linea(x1,y1,x2,y1,color);
GLCD_linea(x1,y1,x1,y2,color);
GLCD_linea(x1,y2,x2,y2,color);
GLCD_linea(x2,y1,x2,y2,color);
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// Dibuja un rectángulo PINTADO desde (x1,y1) a (x2,y2) de color (0 o 1)
//-----------------------------------------------------------------------
void GLCD_caja(int x1, int y1, int x2, int y2, int1 color)
{
//Declaro variables-------------------
int i;
for(i=y1;i<=y2;i++) {
GLCD_linea(x1,i,x2,i,color); }
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// Dibuja un circulo con centro en (x1,y1), radio y color (0 o 1)
//-----------------------------------------------------------------------
void GLCD_circulo(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_punto(x1, y1 + radio, color);
GLCD_punto(x1, y1 - radio, color);
GLCD_punto(x1 + radio, y1, color);
GLCD_punto(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_punto(x1 + x, y1 + y, color);
GLCD_punto(x1 - x, y1 + y, color);
GLCD_punto(x1 + x, y1 - y, color);
GLCD_punto(x1 - x, y1 - y, color);
GLCD_punto(x1 + y, y1 + x, color);
GLCD_punto(x1 - y, y1 + x, color);
GLCD_punto(x1 + y, y1 - x, color);
GLCD_punto(x1 - y, y1 - x, color);
}
}
#include <fuentes.c> //Incluyo la libreria gráfica
//Comienza el programa principal-------------------------------------//
main() {
char *texto1;
GLCD_inicializa(1);
strcpy (texto1,'-0123.45678912');
glcd_texto_grande(0 ,17, texto1, 1);
texto1 = "ABCDEFABCDEFAB";
glcd_texto_grande(0 ,30, texto1, 1);
//char texto1[] = "-0123.45678912";
//char texto2[] = "ABCDEFABCDEFAB";
//char texto3[] = "ABCDEFGHIJKLMNOPQRSTU";
//char texto4[] = "VWXYZ01234567890abcde";
//char texto5[] = "ABCDEFGHIJKLMNOPQRSTU";
//char texto6[] = " www.ucontrol.com.ar ";
// glcd_texto_chico(0, 0, texto3, 1);
// glcd_texto_chico(0, 8, texto4, 1);
// glcd_texto_grande(0 ,17, texto2, 1);
// glcd_texto_grande(0 ,30, texto1, 1);
//glcd_texto_chico(0, 49, texto5, 1);
//glcd_texto_chico(0, 57, texto6, 1);
} //Fin del programa principal
En el post siguiente va el fuentes.c que es el encargado de dibujar las letras en el GLCS.