# Pantalla LCD grafica 320x240



## tanke (Oct 14, 2008)

Buenas, queria consultar si alguien alguna vez controlo una pantalla (LCD) grafica de 320 x 240 puntos, porque hasta el momento ella me viene controlando a mi. Mi principal problema es que no encuentro nada acerca de la pantalla que tengo, es una Winstar, en la etiqueta de la placa dice esto: "Winstar ELWG320240G0 - FFK". Lo unico que encontre es el pdf uqe dejo a continuacion. Lo que busco es conocer los comandos para inicializarla, la distribucion de pines ya la tengo, ya trabaje con los displays alfanumericos de 2 x 16 y me las arreglo bastante bien, supongo que la secuencia de inicializacion de esta pantalla ha de ser un poco mas compleja pero no debe salir del standard general.-

Desde ya muchas gracias por el tiempo prestado en leer mis inquietudes.-

Saludos.-

Tanke.-


----------



## Meta (Oct 14, 2008)

¿Lo programas con C o ASM?

Descargar ejemplo en C y ASM

Fuente


----------



## asherar (Oct 14, 2008)

tanke dijo:
			
		

> "Winstar ELWG320240G0 - FFK".
> Tanke.-


Eso es la denominación de la placa completa. Lo que necesitas es identificar el micro que maneja los comandos. 
Es ese código "SED 1335".  Acá tenés todo para manejarlo: 
http://www.lcd-module.de/eng/pdf/zubehoer/sed1335.pdf

Igual es difícil conseguir datos de esos bichos. 
Acá en el foro ya se ha hablado de los GLCD, así que aca, tal vez encontrés algo. 
Yo he trabajado con el T6963C. Si te sirve te puedo pasar algunas cosas.
Si manejás C te puede servir la biblioteca que yo subí para mikroC, pero es para el T6963C. 
No se si será compatible.

Esta es una biblioteca para C/C++:
http://www.ramtex.dk/glcd/glcd_faq.htm


----------



## Meta (Oct 14, 2008)

Esto si que es un buen entrenador.


----------



## asherar (Oct 14, 2008)

Me gusta más el mío ! 




y  su controlador 





 .


----------



## Meta (Oct 14, 2008)

*Pedazo pantallón*. ¿Sabes manejarlo bien en ASM o utilizas el C o ninguno de los dos?

Si puedes, pon en youtube un vídeo a ver si es rápida o lenta, porque lo que he visto por ahí, al generar gráfico son lentas.

Pedazo de controlador.





Me gustaría saber si esa pantalla y controlador es antiguo, aún así sorprende.

Saludos.


----------



## asherar (Oct 14, 2008)

Es de 128x128 y tengo bibliotecas para C y ASM, pero por tamaño de la aplicación y el problema del salto de página, decidí finalmente hacerlo andar en C. 
También lo manejo desde el LPT1 de la PC.






Probé la carga de la pantalla completa en modo gráfico y es bastante rápida. Más de lo que esperaba.
Si no haces el "check" antes de mandar los datos vuela!, pero no tengo confianza que sea estable. 
Tengo miedo que se cuelge, por eso hago el "check" como corresponde. 

Voy a ver si subo un video. Hasta ahora me salen de más de 30 MB y me parecen demasiado gordos para 
lo poco que muestran.

EDITADO: 
Antiguo ? 
El display lo compré en el 2005. 
La placa la hice en el año 2006 y tiene muchas cosas porque incuye la parte de adaptadores de varios sensores (la parte izquierda) y el MAX232. El display se conecta en el peine negro de la dercha. 
Tiene entradas para una celda de carga (puente), contador de pulsos, termocupla, y sonda lamda (medidor de oxigeno de escape de autos).  
Lo manejo todo con un *PIC 16F876A *(antes 16F873). 

Reduje un poco las fotos para no asustar tanto !


----------



## tanke (Oct 14, 2008)

Gracias muchachos! La verdad es que no esperaba tantas respuestas juntas y tan prontas! ya me pongo a mirar todos los enlaces que me dejaron!
El codigo que estoy manejado es ASM, tengo intensiónes de ponerme a ver un poco de C con Code Warrior, me estoy deicando a los micros de Freescale, en este caso le voy a meter un QY4, como para ver si la puedo dominar un poco y despues de lleno al AP32.-

Compañero Alejandro Sherar, el SED que mencionas no lo encontre, creo que el micro al que te referis (Es el unico integrado raro a parte de los integrados de frame) es un RAIO RA8835AP3N, puede ser que este ese en lugar del SED13...?

Mil Gracias de nuevo a todos, cuando tenga algo les cuento!

Saludos colegas!

Tanke.-


----------



## asherar (Oct 14, 2008)

tanke dijo:
			
		

> Compañero Alejandro Sherar, el SED que mencionas no lo encontre, creo que el micro al que te referis (Es el unico integrado raro a parte de los integrados de frame) es un RAIO RA8835AP3N, puede ser que este ese en lugar del SED13...?



EL codigo SED 1335 figura en la hoja de datos que subiste. 
Si en la plaqueta no está puede ser que el micro que usa sea compatible con el SED 1335.

Efectivamente mira ACÁ


----------



## Meta (Oct 14, 2008)

Alejandro Sherar dijo:
			
		

> Es de 128x128 y tengo bibliotecas para C y ASM, pero por tamaño de la aplicación y el problema del salto de página, decidí finalmente hacerlo andar en C.
> También lo manejo desde el LPT1 de la PC.
> 
> 
> ...



La pantalla si es del 2005 no es antigua, pensaba que era del 1999 por ahí. Veo que está muy currado. En la pantalla que te mensioné antes tiene estos controles que vete a saber sus referencias que las tiene ocultas.






Más información


----------



## tanke (Oct 14, 2008)

La verdad Alejandro que no tengo palabras para agradecerte, posta, sin palabras, simplemente Muchas Gracias, tu aporte me fue de mucha ayuda, gracias che!

Meta: Estuve leyendo el articulo que mencionaste y la verdad es que esta muy bueno, te consulto, el software que menciona ahi (BMPtoLCD) es se puede descargar de ahi? hay algun otro programa que convierta los BMP en lista de bytes?


----------



## asherar (Oct 14, 2008)

Meta dijo:
			
		

> Más información


Esos dos tienen toda la pinta de ser pics 16F84 programados (18 pines). 

*Edito:* Nobleza obliga. Abrí el PDF y el patillaje no coincide. 
Esta vez me equivoqué, pero ... mmm, ... pegó en el palo ...!


----------



## Meta (Oct 14, 2008)

Hola:

Lo del *BMPtoLCD* no tengo idea, me gustaría conseguirlo. Seguro que te viene en el CD-ROM si compras eso, también en Internet puedes comprarlo.

En cuanto a los controladores para el GLCD. Estas personas son muy listas y quizás usen PIC o otro marca de microcontrolador para recurrir a ellos mientras hace negocio.

Un cordial saludo.


----------



## asherar (Oct 14, 2008)

Acá está la biblioteca para GLCD desde la PC:
https://www.forosdeelectronica.com/download.php?id=13979


----------



## Meta (Oct 14, 2008)

```
/* ----------------------------------------------------------
 * Program to control a T6963C-based 240x64 pixel LCD display
 * using the PC's Parallel Port (LPT1:) in bidirectional mode
 * written in Microsoft Quick C
 *
 * Written by John P. Beale May 3-4, 1997  bealeAbest.com
 *
 *  Based on informaciónrmation from Steve Lawther,
 *  "Writing Software for T6963C based Graphic LCDs", 1997 which is at
 *  [url]http://ourworld.compuserve.com/homepages/steve_lawther/t6963c.pdf[/url]
 *
 *  and the Toshiba T6963C data sheet, also on Steve's WWW page
 *
 *  and información at: [url]http://www.citilink.com/~jsampson/lcdindex.htm[/url]
 *               [url]http://www.cs.colostate.edu/~hirsch/LCD.html[/url]
 *               [url]http://www.hantronix.com/[/url]
 * ----------------------------------------------------------
 */

//#include <stdio.h>
#include <stdlib.h>     // rand()
#include <conio.h>      // inp() outp() kbhit()
#include <string.h>     // strlen()
#include <math.h>       // cos(),sin()
#include <time.h>
#include <dos.h>
#include "teclas.h"

/* --------------------------------------------------------------
 * Ambas placas probadas usan el controlador T6963C
 *
 * Pin numbers refer to pins on PC's DB25 parallel port connector.
 * Recall that SEL (pin 17), LF (14), and STROBE (1) control ouputs
 * are inverted, but Init (16) is true.
 *
 * --------------------------------------------------------------
 *
 *  FG    (1)  frame ground
 *  GND   (2) <--> (25) GND
 *  +5V   (3)  LCD logic supply
 *  -7.8V (4)  LCD contrast
 *
 * --------------------------------------------------------------
 *
 *  LCD Pin ----- PC Port Pin  Status Reg. bit
 *  /WR  (5) <--> (16) Init      2
 *  /RD  (6) <--> (14) /LF       1
 *  /CE  (7) <--> (1)  /Strobe   0
 *  C/D  (8) <--> (17) /SEL      3
 *
 * --------------------------------------------------------------
 *
 * LCD pines para TOSHIBA TLX-711A-E0 - 240x64 pixels
 *
 * _RST (10) 0:reset 1:normal op.
 *  FS  (19) font select
 *
 *  LCD Pin ----- PC Port Pin
 *
 *  D0  (11) <--> (2)  D0
 *  D1  (12) <--> (3)  D1
 *  D2  (13) <--> (4)  D2
 *  D3  (14) <--> (5)  D3
 *  D4  (15) <--> (6)  D4
 *  D5  (16) <--> (7)  D5
 *  D6  (17) <--> (8)  D6
 *  D7  (18) <--> (9)  D7
 *
 * --------------------------------------------------------------
 * LCD pines para WM-G1212A - 128x128 pixels
 *
 * _RST  (9) 0:reset 1:normal op.
 *  FS  (18) font select
 *
 *  LCD Pin ----- PC Port Pin
 *
 *  D0  (10) <--> (2)  D0
 *  D1  (11) <--> (3)  D1
 *  D2  (12) <--> (4)  D2
 *  D3  (13) <--> (5)  D3
 *  D4  (14) <--> (6)  D4
 *  D5  (15) <--> (7)  D5
 *  D6  (16) <--> (8)  D6
 *  D7  (17) <--> (9)  D7
 *
 * --------------------------------------------------------------
 */
// Funciones Originales

#define CEHI outp(pcont, (inp(pcont) & 0xfe) ) // take PC 1 HI  // Baja el bit 0 de registro CONTROL
#define CELO outp(pcont, (inp(pcont) | 0x01) ) // take PC 1 LO // Sube el bit 0 de registro CONTROL

#define RDHI outp(pcont, (inp(pcont) & 0xfd) ) // take PC 14 HI // Baja el bit 1 de registro CONTROL

#define RDLO outp(pcont, (inp(pcont) | 0x02) ) // take PC 14 LO // Sube el bit 1 de registro CONTROL

#define WRHI outp(pcont, (inp(pcont) | 0x04) ) // take PC 16 HI // Sube el bit 2 de registro CONTROL (L�gica negativa)

#define WRLO outp(pcont, (inp(pcont) & 0xfb) ) // take PC 16 LO // Baja el bit 2 de registro CONTROL (L�gica negativa)

#define CDHI outp(pcont, (inp(pcont) & 0xf7) ) // take PC 17 HI // Baja el bit 3 de registro CONTROL

#define CDLO outp(pcont, (inp(pcont) | 0x08) ) // take PC 17 LO // Sube el bit 3 de registro CONTROL

#define DATAIN  outp(pcont, (inp(pcont) | 0x20) ) // 8bit Data input
// Sube el bit 5 de registro CONTROL

#define DATAOUT outp(pcont, (inp(pcont) & 0xdf) ) // 8bit Data output
// Baja el bit 5 de registro CONTROL

/* ----- Definitions concerning LCD internal memory  ------ */

#define G_BASE 0x0200            // base address of graphics memory
#define T_BASE 0x0000            // base address of text memory

/*
	Seleccionando el font mediante el pin FS del m�dulo LCD,
	se obtiene, tanto para modo Texto como para modo Grafico:

		Con FS=0: 8x8		Con FS=1: 8x6

	Esto es, para 240x64 pixels:

	FS=0 8x8: BYTES_PER_ROW=30 (64/8 x 240/8 = 8 filas x 30 caracteres)
	FS=1 8x6: BYTES_PER_ROW=40 (64/8 x 240/6 = 8 filas x 40 caracteres)

	y para 128x128 pixels:

	FS=0 8x8: BYTES_PER_ROW=16 (128/8 x 128/8 = 16 filas x 16 caracteres)
	FS=1 8x6: BYTES_PER_ROW=21 (128/8 x 128/6 = 16 filas x 21 caracteres)

*/
#define BYTES_PER_ROW_FS_0 16    // 16 lineas de 16 caracteres 8x8
#define BYTES_PER_ROW_FS_1 20    // 16 lineas de 20 caracteres 6x8

/* ----------------------------------------------------------- */

#define sgn(x) ((x)>0?1:-1)
#define frand() ((float)rand()/RAND_MAX)

#define UI unsigned int
#define UL unsigned long

void delayed(UL d);  		// delay proportional to "d" value
void putcur(int x, int y);
void scr_saver();

void lcd_putchar(char *letra);  // send char to LCD
void lcd_print(char *string);  // send string of characters to LCD
void lcd_read(char *string);  // read string of characters from LCD

void dput(int byte); 	// write data byte to LCD module
int  dget(void);      	// get data byte from LCD module
int  sget(void);      	// check LCD display status pbrt
void cput(int byte); 	// write command byte to LCD module
void lcd_setup();    	// make sure control lines are at correct levels
void lcd_init();     	// initialize LCD memory and display modes
void lcd_clear_graph(); // clear graphics memory of LCD
void lcd_clear_text();  // clear text memory of LCD
void lcd_xy(int x,int y); // set memory pointer to (x,y) position (text)
void lcd_setpixel(int column, int row);  // set single pixel in array

void setup_port();		// Encuentra el puerto LPT
void lcd_paint_graph();
void lcd_clrpixel(int column, int row);  // clr single pixel in array
void lcd_line( 		int x0,int y0,int xf,int yf,int color);
void lcd_rectangle( int x0,int y0,int xf,int yf,int color);


#define BASE 0x378   	// base address for parallel port LPT1:
UI LPT1  = 0;
UI LPT2  = 0;
UI LPT3  = 0;
UI pdata = BASE;     	// par.port data register
UI pstat = BASE+1;   	// par.port status register
UI pcont = BASE+2;   	// par.port control register

//#define home() dput(T_BASE%256);dput(T_BASE>>8);cput(0x24); // upper-left

#define XMIN 0 // limits of (x,y) LCD graphics drawing
#define XMAX 127
#define YMIN 0
#define YMAX 127

#define PI 3.1415926536

int BYTES_PER_ROW;
int NRO_DE_LINEAS;
int x0,y0;
int xcur,ycur;
int xcur0,ycur0;
int tecla;
int altocur=2;
int d1;                 // data from port
int s1;                 // status register value
int i,j;
int c1;                 // control register value
int ch;                  // character to write to display
float x,y;              // coordinates on graphics screen
float xinc,yinc;
float rad,theta;          // polar coords. for point dV
float theta_inc;
unsigned int cc;
int MG=1,MT=1,QR=1,BK=1;

int f0[100],f1[100],f01[100];

char string[320];       // string to print to display
char tmpbuf[128];  		// time buffer

int n,np,byteold;

// ----------------------------------------------------------------

void dly()
{
//delayed(100);
}

// ----------------------------------------------------------------

void showchar()
{
unsigned cc;

//lcd_clear_text();
//lcd_clear_graph();

// Text ON, Cursor Blinking

if (MG==0)
	{cput(0x97); MT=1;QR=1;BK=1;}
else
	{cput(0x9F); MT=1;QR=1;BK=1;}

putcur(xcur0,ycur0);
lcd_xy(xcur,ycur);        // write text from upper left corner

for (i=0;i<16;i++)	// display all characters
	{
	for (j=0;j<BYTES_PER_ROW-1;j++)
		{
		putcur(xcur+1,ycur);// aumenta x - retiene y

		if(j+i*BYTES_PER_ROW+1<128)
			{
			cc = (unsigned int) (10+j+i*BYTES_PER_ROW)%0x7f;
			dput(cc);
			cput(0xc0);		// write char, inc ptr.
			}
		}
	putcur(xcur0,ycur+1);	// resetea x - aumenta y
	lcd_xy(xcur,ycur);
	}
putcur(xcur0,ycur0);
}

// ----------------------------------------------------------------

void plot0() //Np, int X, int Y)
{
double k,cd,x0,y0;
int nx=55,ny=0,cmax,cx;

cput(0x9E); //MG=1;MT=1; QR=1;BK=0; // Graphics ON, Text ON
	{
	x0= XMIN+16;
	y0= (YMAX-YMIN) /2.;
	k = 2*PI/(XMAX-XMIN);
	rad = y0/2.;
	x = x0;
	cmax = 150.*(XMAX-16-x0);
	for (cx=0;cx<cmax;cx++)
		{
		if ( x>XMAX )	x = XMAX - 16.;
		y = y0 - rad * exp(-.5*k*(x-x0))* cos(4*k*(x-x0));
		lcd_setpixel((int)x,(int)y);
		cd=cx;
		x = x0+cx/150.;
		}
	}
}

// ----------------------------------------------------------------

void plot1() //Np, int X, int Y)
{
double k,cd,x0,y0, x,y,cmax;
int cx;

cput(0x9E); //MG=1;MT=1; QR=1;BK=0;// Graphics ON, Text ON
	{
	x0= XMIN+16+20;
	y0= (YMAX-YMIN) /2.;
	rad = y0/2.;
	x = x0;
	for (cx=0;cx<100;cx++)
		{
		x = x0;
		cd=cx;
		y = y0 - rad *cd/100;
		lcd_setpixel(x,y);
		}
	cmax = (XMAX-16-x0);
	for (cx=0;cx<15;cx++)
		{
		x = x0 + cx;
		y = y0 - r;
		lcd_setpixel(x,y);
		}
	x0= x;

	k = 2*PI/(XMAX-XMIN);
	cmax = (XMAX-16-x0);
	for (cx=0;cx<10*cmax;cx++)
		{
		if (x>XMAX)	x=XMAX-16;
		y = y0 - rad * exp(-.5*k*(x-x0))* cos(6*k*(x-x0));
		lcd_setpixel((int)x,(int)y);
		x = x0+cx/10.;
		}
	}
}

// ----------------------------------------------------------------

void plot(int Np, int X[], int Y[], int color)
{
double k,x0,y0;
int n,nx=55,ny=0, x,y;

cput(0x9E); //MG=1;MT=1; QR=1;BK=0;// Graphics ON, Text ON

	x0= XMIN+16;
	y0= 20;
	for (n=0;n<=Np;n++)
		{
		if (x0+X[n] > XMAX)
			{
			n=Np;
			}
		else
			{
			if (color==1)
				lcd_setpixel(x0+X[n], y0+Y[n]);
			else
				lcd_clrpixel(x0+X[n], y0+Y[n]);
			}
		}
}

// ----------------------------------------------------------------

void lcd_line(int x0,int y0,int xf,int yf,int color)
{
int n,N,x,y;

N = sqrt((double)(xf-x0)*(xf-x0)+(double)(yf-y0)*(yf-y0));
for(n=0;n<N;n++)
	{
	x = x0+n*(xf-x0)/N;
	y = y0+n*(yf-y0)/N;
	lcd_setpixel(x,y);
	}
}

// ----------------------------------------------------------------

void lcd_ellipse(int x0,int y0,int rx,int ry,int color)
{
int n,N, x,y;
double ang,ang_inc;

N = 6*sqrt(rx*rx+ry*ry);

ang = 0;
ang_inc = 2. * PI / N;
for(n=0;n<N;n++)
	{
	x = x0 + rx * cos(ang);
	y = y0 + ry * sin(ang);
	lcd_setpixel(x,y);
	ang += ang_inc;
	}
}

// ----------------------------------------------------------------

void lcd_rectangle( int x0,int y0,int xf,int yf,int color)
{
lcd_line(x0,y0,x0,yf,color);
lcd_line(x0,yf,xf,yf,color);
lcd_line(xf,yf,xf,y0,color);
lcd_line(xf,y0,x0,y0,color);
}

// ----------------------------------------------------------------

void scr_saver()
{
	lcd_clear_graph();        // fill graphics memory with 0x00

	cput(0x9A);
	//MG=1;MT=0;QR=1;BK=0;// Graphics ON, Text OFF

	x=(XMAX-XMIN)/2;
	y=(YMAX-YMIN)/2;
	r=0.3;
	theta = 2*PI*frand();
	theta_inc = (0.001 * frand()) - 0.005;
	c=0;
	while(!kbhit())
		{
		lcd_setpixel((int)x,(int)y);       // draw pixel on LCD screen
		xinc = r*cos(theta);
		yinc = r*sin(theta);
		theta += theta_inc;
		x += xinc;
		y += yinc;
		if (x>XMAX) {x=XMAX; theta = PI-theta;	}
		if (y>YMAX) {y=YMAX; theta = -theta;	}
		if (x<XMIN) {x=XMIN; theta = PI-theta;	}
		if (y<YMIN) {y=YMIN; theta = -theta;	}
		if (kbhit()) break;
		if(c<10000)
			c++;
		else
			{
			c=0;
			theta = 2*PI*frand();
			}
		} // end while(c)

	lcd_clear_graph();

	cput(0x9F); //MG=1;MT=1; QR=1;BK=1;// Graphics ON, Cursor ON, Text ON
}

// ----------------------------------------------------------------

void putcur(int x, int y)
	{
	xcur=x;		ycur=y;
	dput(x);	dput(y);	cput(0x21);
	}

// ----------------------------------------------------------------

void lcd_paint_graph()    	// pinta de negro toda la pantalla
{
int i,j,k;

cput(0x98);  // Graphics ON, Text OFF //MG=1;MT=0;QR=0;BK=0;

dput(G_BASE%256);
dput(G_BASE>>8);
cput(0x24);		// addrptr at address G_BASE

for (i=0;i<20;i++)
	{
	for (j=0;j<127;j++)
		{
		dput(0xFF);cput(0xc0); // write data, inc ptr.
		} // end for(j)
	putchar('.');
	}// end for(i)
for (j=0;j<22;j++)
	{
	dput(0xFF);cput(0xc0); // write data, inc ptr.
	} // end for(j)
} // end lcd_paint_graph()
// ----------------------------------------------------------------

/* Block writes would, I think, run faster if you used the DATA AUTO
   mode, eg command 0xB0. I didn't bother.
 */
void lcd_clear_graph()    	// clear graphics memory of LCD
{
int i,j,k;

//cput(0x9F);MG=1;MT=1;QR=1;BK=1;// Graphics ON, Text ON

dput(G_BASE%256);
dput(G_BASE>>8);
cput(0x24);		// addrptr at address G_BASE

for (i=0;i<20;i++)
	{
	putcur(i,ycur0);
	for (j=0;j<128;j++)
		{
		dput(0);cput(0xc0); // write data, inc ptr.
		} // end for(j)
	putchar('.');
	}// end for(i)
dput(0);cput(0xc0); // write data, inc ptr.
dput(0);cput(0xc0); // write data, inc ptr.
putcur(xcur0,ycur0);
} // end lcd_clear_graph()

// ----------------------------------------------------------------

void lcd_clear_text()
{
int i,j;

dput(T_BASE%256);
dput(T_BASE>>8);
cput(0x24);      // addrptr at address T_BASE

for (i=0;i<BYTES_PER_ROW+1;i++)
	{
	putchar('.');
	for (j=0;j<NRO_DE_LINEAS+1;j++)
		{
		dput(0);
		cput(0xc0); // write data, inc ptr.
		if(kbhit())
			{
			j=NRO_DE_LINEAS+1;	i=BYTES_PER_ROW+1;
			}
		} // end for(j)
	} // end for(i)

putcur(xcur0,ycur0);

} // lcd_clear_text()

// ----------------------------------------------------------------

void lcd_read(char *string)  // read string of characters from LCD
{
int i;
int c;

for (i=0;i<strlen(string);i++)
	{
	cput(0xc5);	   // Configura lectura, mantiene puntero
	c=dget()+0x20;	   // lee el dato recien recuperado
	putch(c);
	} // end for

} // end lcd_read

// ----------------------------------------------------------------

void lcd_setpixel(int column, int row)  // set single pixel in 240x64 array
{
int addr;       // memory address of byte containing pixel to write

addr =  G_BASE + (row*BYTES_PER_ROW)  + (column/6);
dput(addr%256);
dput(addr>>8);
cput(0x24);			// set LCD addr. pointer
cput(0xf8 | (5-(column%6)) );	// set bit-within-byte command

} // end lcd_setpixel()

// ----------------------------------------------------------------

void lcd_clrpixel(int column, int row)  // clr single pixel in array
{
int addr;       // memory address of byte containing pixel to write

addr =  G_BASE + (row*BYTES_PER_ROW)  + (column/6);
dput(addr%256);
dput(addr>>8);
cput(0x24);  					// set LCD addr. pointer
cput(0xf8);// | (5-(column%6)) );	// clr bit-within-byte command

} // end lcd_setpixel()

// ----------------------------------------------------------------

void lcd_xy(int x, int y)  // set memory pointer to (x,y) position (text)
{
int addr;

addr = T_BASE + (y * BYTES_PER_ROW) + x;
dput(addr%256); dput(addr>>8); cput(0x24);  // set LCD addr. pointer

dput(x); dput(y); cput(0x21);  // set LCD curs. pointer

} // lcd_xy()

// ----------------------------------------------------------------

void delayed(UL d)  // delay proportional to "d" value
{
UL i;
double a;

if(d>10000)
   d=10000;

a = 1.000;
for (i=0;i<d;i++)
	{
	a = a / 1.001;
	}
return;
} // end delay()

/* ==============================================================
 * Low-level I/O routines to interface to LCD display
 * based on four routines:
 *
 *          dput(): write data byte
 *          cput(): write control byte
 *          dget(): read data byte         (UNTESTED)
 *          sget(): read status
 *
 * ==============================================================
 */

void lcd_setup()  // make sure control lines are at correct levels
{
	CEHI; // disable chip
	RDHI; // disable reading from LCD
	WRHI; // disable writing to LCD
	CDHI; // set data mode
//	DATAOUT;    // make 8-bit parallel port an output port

} // end lcd_setup()

// ----------------------------------------------------------------

void lcd_init()  // initialize LCD memory and display modes
{

	NRO_DE_LINEAS = 16;

	dput(G_BASE%256);	// Pone Byte bajo
	dput(G_BASE>>8);	// Pone Byte alto
	cput(0x42);     	// set graphics memory to address G_BASE

	dput(BYTES_PER_ROW%256);// Pone Byte bajo
	dput(BYTES_PER_ROW>>8); // Pone Byte alto
	cput(0x43);  	 	// n bytes per graphics line

	dput(T_BASE%256);	// Pone Byte bajo
	dput(T_BASE>>8); 	// Pone Byte alto
	cput(0x40);     	// text memory at address T_BASE

	dput(BYTES_PER_ROW%256);	// Pone Byte bajo
	dput(BYTES_PER_ROW>>8); 	// Pone Byte alto
	cput(0x41);     	// n bytes per text line

	cput(0x80);     	// mode set: Graphics OR Text, ROM CGen

	cput(0x9F);MG=1;MT=1;// Graphics & Text ON, cursor ON & blinking

	xcur0=1;ycur0=0;
	putcur(xcur0,ycur0);   // put cursor at (1,0)

	cput(0xa0+altocur);	// cursor is altocur lines high

} // end lcd_init()

// ----------------------------------------------------------------

int sget(void)  // get LCD display status byte
{
int lcd_status;

//  DATAIN;           // make 8-bit parallel port an input
  CDHI;				// bring LCD C/D line high (read status byte)
  RDLO;				// bring LCD /RD line low (read active)

  CELO;//dly();		// bring LCD /CE line low (chip-enable active)

/*  dly();  dly();  dly();  dly();  dly();
  dly();
  dly();        	// > 150 ns antes de leer
  dly();
  dly();  dly();  dly();  dly();
*/
  lcd_status = inp(pdata);      // read LCD status byte

  CEHI;//dly();		// bring LCD /CE line high, disabling it

  RDHI;//dly();		// deactivate LCD read mode
//  DATAOUT; 		    // make 8-bit parallel port an output port

  return(lcd_status);
} // sget()

// ----------------------------------------------------------------

void dput(int byte) // write data byte to LCD module over par. port
			// assume PC port in data OUTPUT mode
{
//  wait_msj();

  // wait until display ready
  //
  do {;} while (!kbhit() && ((0x03 & sget()) != 0x03));

  // wait until MSB=1
  //
  do {;} while (!kbhit() && ((0x80 & sget()) != 0x80));

//  cls_msj();

  //if(kbhit()) getch();

  CDLO;//dly();
  WRLO;//dly();		// activate LCD's write mode

  outp(pdata,byte); // write value to data port
  //dly();

  CELO;//dly();		// pulse enable LOW > 80 ns (hah!)

//  dly(); dly(); dly(); dly(); dly();

  CEHI;//dly();		// return enable HIGH

  WRHI;//dly();		// restore Write mode to inactive

} // end dput()

// ----------------------------------------------------------------

int dget(void)      // get data byte from LCD module
{
int lcd_byte;

  // wait until display ready
  //
  do {;} while (!kbhit() && ((0x03 & sget()) != 0x03));

  // wait until MSB=1
  //
  do {;} while (!kbhit() && ((0x80 & sget()) != 0x80));

//  cls_msj();

//  DATAIN;       	// make 8-bit parallel port an input
  WRHI;//dly();   	// make sure WRITE mode is inactive
  CDLO;//dly();   	// data mode
  RDLO;//dly();   	// activate READ mode

  CELO;//dly();   	// enable chip, which outputs data

//  dly(); dly();
//  dly();        	// > 150 ns antes de leer
//  dly(); dly();

  lcd_byte=inp(pdata);// read data from LCD

  CEHI;//dly();   	// disable chip

  RDHI;//dly();   	// turn off READ mode
//  DATAOUT;			// make 8-bit parallel port an output port

  return(lcd_byte);
} // dget()

// ----------------------------------------------------------------

void cput(int byte) // write command byte to LCD module
					// assumes port is in data OUTPUT mode
{

  // wait until display ready
  //
  do {;} while (!kbhit() && ((0x03 & sget()) != 0x03));

  // wait until MSB=1
  //
  do {;} while (!kbhit() && ((0x80 & sget()) != 0x80));

  outp(pdata,byte);  // present data to LCD on PC's port pins
  //dly();
  CDHI;//dly();		 // control/status mode
  RDHI;//dly();		 // make sure LCD read mode is off
  WRLO;//dly();		 // activate LCD write mode

  CELO;//dly();		 // pulse ChipEnable LOW, > 80 ns, enables LCD I/O

//  dly();  dly();  dly();  dly();  dly();

  CEHI;//dly();		 // disable LCD I/O
  WRHI;//dly();		 // deactivate write mode

} // cput()

// ----------------------------------------------------------------

void titulo()
{
char TXT[100];

sprintf(TXT,"%s","A. Sherar"); 
lcd_xy(6,1);lcd_print(TXT);

sprintf(TXT,"%s","    Desarrollo de    ");
lcd_xy(0,13);lcd_print(TXT);

sprintf(TXT,"%s","  Sistemas Digitales ");
lcd_xy(0,14);lcd_print(TXT);

lcd_xy(xcur,ycur);
}

// ----------------------------------------------------------------

void logo()
{
lcd_clear_graph();
lcd_ellipse(64,62,50,40,1);
plot1();
lcd_clear_text();
titulo();
}

// ----------------------------------------------------------------

void main()
{
int salir,tecla, X0,X1,Y0,Y1;
unsigned char caracter, CAR[3];

lcd_setup();  // make sure control lines are at correct levels

BYTES_PER_ROW = BYTES_PER_ROW_FS_1;

lcd_init();   // initialize LCD memory and display modes

lcd_clear_text();
lcd_clear_graph();
cput(0x9F);  // Graphics & Text ON, cursor blinking
//MG=1;MT=1;QR=1;BK=1;

for(n=0;n<100;n++)
	{
	f0[n] = 0;
	f1[n] = 80;
	f01[n]= n;
	}

menutxt();

logo();

salir=0;
while(!salir)
	{

	gotoxy(10,1);
	printf("STATUS: MTEXT=%d MGRAF=%d CUR=%d BLINK=%d xc=%2d yc=%2d",
			MT,MG,QR,BK,xcur,ycur);clreol();
	gotoxy(10,24);printf("Comando: ");clreol();

	tecla=getch();
	gotoxy(10,1);clreol();
	if (tecla==0)
		{
		tecla=getch();gotoxy(19,24);putchar(tecla);clreol();
		switch (tecla)
			{
			case F1:  lcd_init();
					  lcd_clear_text();
					  lcd_clear_graph();
					  cput(0x9F);  MG=1;MT=1;QR=1;BK=1;

					  menutxt();
					  logo();
					  break;

			case F2:  cput(0x9F);  MG=1;MT=1;QR=1;BK=1;	putcur(0,0); break;

			case F3:  if (altocur<7)
							{
							altocur++;	cput(0xa0+altocur);
							}
					  break;

			case F4:  if (0<altocur)
							{
							altocur--;	cput(0xa0+altocur);
							}
					  break;

			case F5:  if(MG==1)
						{
						if(MT==1)
							{cput(0x9B);MT=0;QR=1;BK=1;}
						else
							{cput(0x9F);MT=1;QR=1;BK=1;}
						}
					  else
						{
						if(MT==1)
							{cput(0x93);MT=0;QR=1;BK=1;}
						else
							{cput(0x97);MT=1;QR=1;BK=1;}
						}
					  break;

			case F6:  lcd_clear_text();		break;

			case F7:  showchar(); 			break;

			case F8:
			case F11: lcd_paint_graph();	break;

			case F9:
			case F12: if(MT==1)
						{
						if(MG==1)
							{cput(0x97);MG=0;QR=1;BK=1;}
						else
							{cput(0x9F);MG=1;QR=1;BK=1;}
						}
					  else
						{
						if(MG==1)
							{cput(0x93);MG=0;QR=1;BK=1;}
						else
							{cput(0x9B);MG=1;QR=1;BK=1;}
						}
					  break;

			case F10:  lcd_clear_graph();		break;

			case DER: if(xcur<BYTES_PER_ROW-1)	putcur(xcur+1, ycur);	break;

			case IZQ: if(xcur>1) 				putcur(xcur-1, ycur);	break;

			case ABA: if(ycur<15)				putcur(xcur, ycur+1);	break;

			case ARR: if(ycur>0) 				putcur(xcur, ycur-1);	break;

			case HOM: putcur(xcur0, 0);				break;

			case END: putcur(BYTES_PER_ROW-1, 15);	break;

			case PDN: putcur(xcur, 15);	break;

			case PUP: putcur(xcur, 0);	break;

			case DEL:	clrscr();				break;

			case INS:	clrscr();  menutxt();	break;

			default: break;
			}
		}
	else
		{
		gotoxy(19,24);putchar(tecla);clreol();
		switch (tecla)
			{
			case ESP: scr_saver();				break;

			case ENT: lcd_clear_text();
					  lcd_clear_graph();
					  cput(0x9F);
					  MG=1;MT=1;QR=1;BK=1;		break;

			case 'A':
				{
				plot(80,f0, f01,1);		// 0,0 - 0,1
				plot(80,f01,f0 ,1);		// 0,0 - 1,0
				plot(80,f01,f1 ,1); 	// 0,1 - 1,1
				plot(80,f1, f01,1); 	// 1,0 - 1,1
				}
				break;

			case 'B':
				{
				//plot(80,f0, f01,0);		// 0,0 - 0,1
				//plot(80,f01,f0 ,0);		// 0,0 - 1,0
				//plot(80,f01,f1 ,0); 	// 0,1 - 1,1
				//plot(80,f1, f01,0); 	// 1,0 - 1,1
				}
				break;

			case 'P':
				{
				plot1();
				}
				break;

			case 'Q':
				{
				plot0();
				}
				break;

			case 'R':
				{
				lcd_rectangle(XMIN+16,20,XMAX-16,100,1);
				}
				break;

			case 'E':
				{
				X0 = (XMAX+XMIN)/2;
				Y0 = (YMAX+YMIN)/2;
				lcd_ellipse(X0,Y0,(int)X0*3/4,(int)Y0*3/4,1);
				}
				break;

			case 'L':
				{
				X0 = XMIN+16;         X1 = XMAX-16;
				Y0 = (YMAX-YMIN)/4;   Y1 = Y0*3;
				lcd_line(X0,Y0,X0,Y1,1);
				lcd_line(X0,Y1,X1,Y1,1);
				lcd_line(X1,Y0,X1,Y1,1);
				lcd_line(X0,Y0,X1,Y0,1);
				}
				break;

			case 'T':	titulo();				break;

			case ESC:   salir=1;				break;

			default:
				caracter = (char)tecla;

				if('a'<=tecla && tecla<='z') sprintf(CAR,"%s",&caracter);
				if('0'<=tecla && tecla<='9') sprintf(CAR,"%s",&caracter);
				CAR[1]='\0';
				//gotoxy(19,24);putchar(CAR[0]);clreol();
				lcd_xy(xcur,ycur);
				putcur(xcur+1,ycur);
				lcd_putchar(CAR);
				lcd_xy(xcur,ycur);

				break;
			}
		}
	}

lcd_clear_text();

lcd_clear_graph();

return;
}

// ----------------------------------------------------------------

void lcd_putchar(char *letra)  // send char to LCD
{
int c,cg;

	c = *letra-0x20;          	// convert ASCII to LCD char address
	if (c<0) c=0;
	dput(c);
	cput(0xc0);					// Env�a el caracter, mantiene puntero

	//putcur(xcur+1,ycur);	   	// mueve el cursor
	//cput(0xc5); 		   // Configura lectura, mantiene puntero
	//cg=dget()+0x20; 	   // lee el dato recien recuperado
	//dput(c);
	//cput(0xc0); 		   // write character, increment memory ptr.
	//putch(cg);

}

// ----------------------------------------------------------------

void lcd_print(char *string)  // send string of characters to LCD
{
int i,largo;

largo = strlen(string);
if (largo > BYTES_PER_ROW)
	largo = BYTES_PER_ROW;

for (i=0;i<largo;i++)
	{
	   lcd_putchar(&string[i]);
	   putch(string[i]);	   

	} // end for
} // end lcd_print

// ----------------------------------------------------------------
```


----------



## asherar (Oct 15, 2008)

Aquí algunos enlaces con información sobre LCD Graficos como para tirar para arriba ... 

http://www.geocities.com/dinceraydin/lcd/index.html
con http://www.geocities.com/dinceraydin/lcd/gfxfin.htm
http://www.skippari.net/lcd/index.html

... y verán que no exagero !

Y para jugar un rato, este simulador de Grafic LCD: 
http://www.geocities.com/dinceraydin/djgfxlcdsim/djgfxlcdsim.html

Fíjense si pueden hacer andar este programita en windows

Editado: Ojo! Funciona con BMPs monocromo del tamaño adecuado a la pantalla que quieren usar. 
Eso lo hacen con otro programa de edición de imágenes (p. ej. paint-brush).


----------



## Meta (Oct 15, 2008)

Muy buenas la Web, ahora mismo no puedo bajar esos archivos ya que estoy con openSUSE 11.0.


----------



## Meta (Oct 15, 2008)

Los he probado y al cargar el bmp me da error.


----------



## asherar (Oct 15, 2008)

El primer video lo subí acá:
YouTube - ProgramaciÃ³n de un LCD GrÃ¡fico
Está muy simple pero en la primera parte se puede ver la velocidad de carga de la pantalla completa, 
entre las cargas de los bmp distintos: logo y cara.
La secuencia completa es: 
Encendido - 5 pulsaciones del led rojo (una por segundo) - borrado textos - borrado graficos - textos - logo - cara - borrado graficos - cara - borrado graficos - textos - logo - textos - cara - ... (lazo infinito).
Cada vez que cambia de texto a un gráfico pulsa el led rojo. 
La próxima subo uno con gráficas de las mediciones.
Todo está hecho con C de mikroC.


----------



## asherar (Oct 15, 2008)

Meta dijo:
			
		

> Los he probado y al cargar el bmp me da error.



Fijate que el display sea de las dimensiones del bmp. 
El archivo de ejemplo que subí es para el KS0108, que maneja el display de 128x64. 

Suerte le próxima.


----------



## Meta (Oct 15, 2008)

Me funciona.

Está muy bien los GLSC, como me encantas esas cosas. Eso si, estoy acostumbrado a manejar los del PLC de Siemens. Cuestan cercda de 500 € el de 4 tono de colores y el de color no te digo nada.

YouTube - Panel tÃ¡ctil TP170A -1 parte - regulador analÃ³gico

EDIT:
Por cierto, ¿las imágenes o esa GLCD lo haces directo del PIC o del PC?


----------



## asherar (Oct 15, 2008)

Meta dijo:
			
		

> Por cierto, ¿las imágenes o esa GLCD lo haces directo del PIC o del PC?



Por esos cables de color que se ven en el video sólo va alimentación. Es el pic el que maneja todo !

Este es el mapa de la memoria (es una de las pruebas, no la del video): 





Una de las diagnósticas que permite el mikroC.


----------



## Meta (Oct 16, 2008)

Hay más resolución de lo que yo creía en las GLCD. PDF

http://www.cct.com.my/index.php?dis=product

Que pena que aún no sean del *A02* con carácter con tildes. Son todos del *A00*, Hitachi 44780*A00*.

Por cierto. en la web http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=107&mid=10&lang=en&pageId=74 he encontrado PIC sea de 16F o 18F que controla bien el GLCD. Si estos PIC señalado que por casualidad no están ni el 18F2550 ni el 18F4550, ¿qué diferencia hay entre programar un GLCD con esos pic que dije con lo que muestra en la web?

Digo yo que los GLCD se puede manejar con casi cualquier PIC.


----------



## asherar (Oct 17, 2008)

Meta dijo:
			
		

> Digo yo que los GLCD se puede manejar con casi cualquier PIC.


Si, pero con suficiente memoria para la aplicación. 
Si no, es sólo un "buffer" de muchas patillas.


----------



## remramon2007 (Mar 28, 2011)

Hola, como están?

Les cuento que me compre una GLCD y bueno acá estoy, trabajando con Proteus hasta que me llegue la pantalla WG240128B-FMIVZ que tiene el controlador T6963C.
Hasta el momento logré escribir textos, pero no encuentro como cargar una imagen.

Agradecería si alguien me puede ayudar con esto.

Por cierto si alguien quiere el código de como escribir texto me lo dice!!

Un abrazo Ramón!!


----------



## deputinnai (Mar 8, 2012)

Hola, por favor necesitamos ayuda con la pantalla que pegó Meta en el post #4. Gracias por adelantado, mandadme un mensaje privado.


----------

