Inicializar LCD con controlador T6963C

Hola, tengo un problema con un LCD gráfico el MGLS128128 el cual se controla con el controlador T6963C, pero no he podido hacer que escriba lo que yo quiero, solo escribe basura y ya he intentado con todos los programas en C que he visto en los pdf's.

Para controlarlo estoy utilizando un DSP de Texas, ya cheque que todas las señales llegaran bien y en los tiempos y ya no se que mas probar para que funcione, si alguien ya utilizo este controlador que me pudiera dar unos tips o como fue que inicializo y escribio se los agradecería mucho.


atte: brownie
 
Hola.

Hace un par de años que utilice este mismo display para una aplicación y tengo echas mis librerias para su control.

Estoy en el trabajo y aquí no las tengo. En cuando llege a mi casa te lo mando.

Las Librerias las hice en C para PIC's, pero supongo que te serviran igualmente para ver como funcionan las señales.

Un Saludo.
 
Lo siento por la tardanza, pero no encuentro las librerias.
Seguramente las tengo en algún CD que no he localizado.

No te preocupes, que continuo buscando.
 
Hola Brownie, siento el retraso, pero ya lo he encontrado.

Lo tenia perdido en un CD del año 2003.

He encontrado unas pruebas que realize con el display y el PIC16F876.
El programa está en Ensamblador ASM para PIC.

Espero que te sirva.

Saludos
 

Adjuntos

  • pruebas_t6963c_730.rar
    3.3 KB · Visitas: 891
Paloky

Muchas gracias ojala si me sirva aunque ya voy avanzado y ya pude hacer graficos, pero de todos modos gracias por la atención de mandarmelo. saludos.
 
Hola como estan, tengo una inquietud y es poder usar este material que se coloco aca para hacer trabajar una lcd grafica marca plotech 194v-0 , de 240 x 128 puntos. O que tendria que tener en cuenta. Gracias
 
Ruben Andrade dijo:
Hola como estan, tengo una inquietud y es poder usar este material que se coloco aca para hacer trabajar una lcd grafica marca plotech 194v-0 , de 240 x 128 puntos. O que tendria que tener en cuenta. Gracias
A partir de algo que ya hemos "hablado" por MP nos podemos venir a este foro.
Vamos a ir juntando aquí los elementos más importantes y luego vemos que falta.

1.- El esquema de conexionado que dan en el foro "alemán" es el de la figura
(EDITADO: comienzo a dudar que ese sea el esquema adecuado para tu display ...,
sólo digo que dudo !).
"CS" puede ser "Column Select" o "Character Size".
(uno que tengo de 128x64 pixels, que usa el MPU KS0108B, tiene CS1 y CS2 y es selector de columna: cols. 1 a 64 con CS1=H, y cols. 65 a 128 con CS2=H).
Res seguro es Reset signal.
2.- Del esquemático del micro elegido sólo importan las conexiones al micro interno del display.
3.- Del programa en assembler sólo se deberá cambiar la parte relacionada con el lenguaje
del micro en que se basa el GLCD. Este se debería poder bajar de la red.
Yo te puedo subir un programa en C, para PC, que maneja un GLCD controlado por T6963C desde el LPT. (!)

Yo te aconsejo que te pases a C, ya que estás al principio del proyecto, y porque si el micro no es compatible va a haber varias cosas que modificar.
Esto depende de las ganas que tengas y de con qué herramientas trabajás más cómodo.
El argumento más importante es que si la aplicación crece y necesitás memoria, los pics tienen
un problemita con el direccionamiento de las páginas que te puede volver loco.
El compilador C lo resuelve por tí, y santo remedio. Te lo digo por experiencia: años de renegar!

Por lo visto la gente de los foros alemanes han tenido problemas en encontrar datos del display (por lo poco que entiendo del alemán traducido al español, con el "babylon")

Los enlaces que dan allí son estos:

http://www.lc-design.de/Sanyo_LC7981.pdf
http://www.lcd-module.de/eng/pdf/zubehoer/lc7981.pdf
http://www.lcd-module.de/deu/pdf/grafik/w160-6.pdf
http://www.datasheetcatalog.com/datasheets_pdf/L/C/7/9/LC7981.shtml
http://www.bue.de/tabdata/datasheet/ds_de_mtgrb.pdf
http://www.bue.de/support/archiv/pdf/mtgrman.pdf
http://www.pacificdisplay.com/gdm/GDM-16080-00.pdf

...und hier die Vielversprechendsten: (... y aquí los más prometedores:)

http://forum.lcdinformación.com/viewtopic.php?t=548
http://www.skippari.net/lcd/forumstuff/hitachi_lmg6401plge_data.png

La hoja de datos del HD61830 (que se indica en la figura) es ésta
La hoja de datos del LC981 que está acá

----------------------------------------------------------------------------------------------------------

Pero sólo vos tenés a la vista el micro. Si usas otro patillaje podés quemar alguna I/O aplicando tensión negativa o mayor que 5V. CUIDADO
Ojo que puede haber otros chips en la placa, como memorias, latches y demás.
Por lo que me decís en los MP el micro que tienes es el SCN0080G y la hoja de datos que corresponde debés bajarla de internet. Yo la encontré ACÁ
En el sitio http://www.avantsemi.com.tw/.
Ahora falta conseguir el documento que indica las instrucciones que debés mandarle a ese micro para que haga cada cosa.

La única tabla de equivalencias entre micros que encontré es ESTA.
De donde sale que a vos te sirve el LC7940ND/YD/YC SANYO

Una recomendación IMPORTANTE: antes de aplicar tensión conviene verificar, téster en mano, la ruta de las patillas del micro hacia los terminales de la placa para estar seguro a qué patilla corresponde cada cosa. Por si las moscas ...

Respecto de la alimentación negativa: podés probar con -9 V. A mi con eso me sobra.

Saludos...
 

Adjuntos

  • esquema_lcd_209.jpg
    esquema_lcd_209.jpg
    46.6 KB · Visitas: 875
Una aplicación completa con protector de pantalla y todo está en este archivo "txt"que subo.
Se puede cambiar un par de lineas y sirve para 128x128 o para 240x64 pixel.
Quien tenga una duda, no dude en plantearla! Sin dudarlo, trataré de ayudar.

La única pregunta tonta es la que no se hace.

Saludos !
 

Adjuntos

  • t6963_135.txt
    25.6 KB · Visitas: 544
Alejandro y demas compañeros, gracias por sus comentarios. Alejandro hago caso a utilizar C en el diseño de la GLCD, tengo ya el mikroC (thanks) y estoy seguro en utilizar un GLCD mas comercial, por ejemplo uno basado en controlador T6963C. Tengo una inquietud y es que como no la he comprado aun, pienso simular en el proteus el funcionamiento del codigo, pero en proteus me salen las siguientes GLCD:
- LM 3238 128x64 graphical display (Vsm Dll model)
- LM 4228 128x64 graphical display (Vsm Dll model)
- PG12864F 128x64 graphical display (Vsm Dll model)
- LGM12641BS1R 128x64 graphical lcd con controlador ks0108 (Modelo squematico)
- HDG12864F-3 128x64 graphical lcd con controlador SED1565 (Entrada paralela)
- HDG12864l-4 128x64 graphical lcd con controlador SED1565 (Entrada Paralela)
- HDG12864L-6 128x64 graphical lcd con controlador SED1565 (Interfaz seleccionable)

Como veo que no esta el controlador T6963c del cual tengo la libreria en C en el mikroC, sera que puedo utilizar alguna de estas sin tener problemas de compatibilidad? Hasta pronto.
 
Señores que pena el desorden que he generado, definitivamente abrire un nuevo for ya definitivo para el desarrollo con GLCD, lo llamare LCD grafico GLCD basado en controlador KS0108 ya que mirando por ahi en el MikroC, tiene esta herramienta para generar codigo directamente de imagenes cargadas. Alla los espero.
 
Fijate Rubén que la forma de cableado del GLCD que ponen en el mikroC es diferente a la del programa que posteé yo antes. Otros esquemas de la ayuda también muestran algunos errores (como el reset en el ejemplo del ADC).
Yo armé una biblioteca propia para mi display basado en la hoja del T6963C, y modificando las rutinas del código C posteado antes, para adaptarlas al C de mikroC. Están disponibles en la zona de descargas de mi página.
Buscar: Biblioteca para Pic16F873/6/A ... y bajarse el archivo Bib_0y1.zip.
 
Hola, yo tengo un glcd t6963cfg de 240x128. Resulta que quiero mostrar una sola letra (por ejemplo la "A") y en el lugar que yo quiera de la pantalla y la pantalla muestra 8 veces la misma letra y en cualquier lado. Subo el archivo con la libreria (escrita en C) para que la prueben (si quieren). Estoy usando el compilador CCS.
 

Adjuntos

  • otro_2_870.c
    6.5 KB · Visitas: 208
picproblema dijo:
Hola, yo tengo un glcd t6963cfg de 240x128. Resulta que quiero mostrar una sola letra (por ejemplo la "A") y en el lugar que yo quiera de la pantalla y la pantalla muestra 8 veces la misma letra y en cualquier lado. Subo el archivo con la libreria (escrita en C) para que la prueben (si quieren). Estoy usando el compilador CCS.

Hola:
Estuve revisando tu programa.
Código:
#include <16f877.h>
#use delay(clock=4000000) 
#fuses XT, PUT

const int CURSOR_PTR_SET = 0x021;	//Cursor Pointer Set: Data = X,Y
const int OFFSET_REG_SET = 0x022;   //Offset Register Set: Data = data,0
const int ADDR_PTR_SET = 0x024;   	//Address Pointer Set: Data = low, high addr

/*Control Word Set commands:-*/
const int TEXT_HOME_SET = 0x040;	//Text Home Address Set: Data = low, high addr
const int TEXT_AREA_SET = 0x041;	//Text Area Set: Data = columns, 0
const int GRAPH_HOME_SET = 0x042;   //Graphics Home address Set: Data = low, high addr
const int GRAPH_AREA_SET = 0x043;   //Graphics Area Set: Data = columns, 0

/* Mode Set commands (OR with CG rom commands):-*/
const int OR_MODE = 0x080;			//OR mode
//const int XOR_MODE = 0x081;			//XOR mode
//const int AND_MODE = 0x083;			//AND mode
//const int TEXT_ATTR_MODE = 0x084;	//Text Attribute mode
//const int INT_CG_MODE = 0x080;		//Internal CG ROM mode
//const int EXT_CG_MODE = 0x088;		//External CG ROM mode

/* Display Mode commands (OR together required bits):-*/
//const int DISPLAY_OFF = 0x090;		//display off
//const int BLINK_ON = 0x091;
//const int CURSOR_ON = 0x092;
//const int TEXT_ON = 0x094;
//const int GRAPHIC_ON = 0x098;

/*Cursor Pattern Select*/
//const int CURSOR_1LINE = 0x0A0;
//const int CURSOR_2LINE = 0x0A1;
//const int CURSOR_3LINE = 0x0A2;
//const int CURSOR_4LINE = 0x0A3;
//const int CURSOR_5LINE = 0x0A4;
//const int CURSOR_6LINE = 0x0A5;
//const int CURSOR_7LINE = 0x0A6;
//const int CURSOR_8LINE = 0x0A7;

/*Data Auto Read/Write*/
const int DATA_AUTO_WR = 0x0B0;
//const int DATA_AUTO_RD = 0x0B1;
const int AUTO_DATA_RESET = 0x0B2;

/*Data Read/Write*/
const int DATA_WR_INC = 0x0C0;	//Data write and increment addr: Data = data
//const int DATA_RD_INC = 0x0C1;	//Data read and increment addr
//const int DATA_WR_DEC = 0x0C2;	//Data write and decrement addr: Data = data
//const int DATA_RD_DEC = 0x0C3;	//Data read and decrement addr
//const int DATA_WR = 0x0C4;		//Data write - no addr change: Data = data
//const int DATA_RD = 0x0C5;		//Data read - no addr change

/*Screen Peek*/
//const int16 SCREEN_PEEK = 0x0E0;

/*Screen Copy*/
//const int16 SCREEN_COPY = 0x0E8;

/*Bit Set/Reset (OR with bit number 0-7)*/

//const int BIT_RESET = 0x0F0;
//const int BIT_SET = 0x0F8;

const int16 GRAPHICS_HOME = 0x0200;
const int16 TEXT_HOME = 0x0000;
//const int16 CGRAM_HOME = 0x1800;

const int MaxBytePorFila = 30;	//240/8=30 8 es el tamaño de letra
const int MaxCantFilas = 16;	//16=128/8 8 es el tamaño de letra
const int MaxPixelsFila = 240;

#byte	PORTC	=	0x07
#byte	TRISC	=	0x87
#bit	PORTC3	=	PORTC.3
#bit	PORTC4	=	PORTC.4
#bit	PORTC5	=	PORTC.5
#bit	PORTC6	=	PORTC.6
#bit	PORTC7	=	PORTC.7

#byte	PORTD	=	0x08
#byte	TRISD	=	0x88

//Control pin setting
#define RESET			PORTC3		// LCD RST_ line
#define RD				PORTC5		// LCD Read control line  pin number
#define WR				PORTC6		// LCD Write control line pin number
#define CD				PORTC4		// LCD Control/data Select line
#define CE		    	PORTC7

#define salidas 0x00
#define entradas 0xff

void CheckEstado();
void EnviarComando(int dato);
void EnviarByte(int dato);
void PunteroHome();
void PunteroHomeGraficos();
void Inicializar();
void Barras();
void BorraTodoGrafico(int1 dato);
void BorraTodoTexto();
void GoToXY(int x, int y);
void AutoEscribir(int dato);

void PunteroHomeGraficos(){
EnviarByte(0x00);
EnviarByte(GRAPHICS_HOME >> 8);	//parte alta de GRAPHICS_HOME
EnviarComando(ADDR_PTR_SET);
}

void PunteroHome(){
EnviarByte(0x00);
EnviarByte(TEXT_HOME >> 8);	//parte alta de TEXT_HOME
EnviarComando(ADDR_PTR_SET);
}

void EnviarByte(int dato){
TRISC = salidas;
TRISD = salidas;
CheckEstado();

PORTD = dato;

CE = 0;
WR = 0;
RD = 1;
CD = 0;

delay_us(5);

WR = 1;
CE = 1;

}

void EnviarComando(int dato){
TRISC = salidas;
TRISD = salidas;
CheckEstado();

PORTD = dato;

CE = 0;
WR = 0;
RD = 1;
CD = 1;

delay_us(5);

WR = 1;
CE = 1;
}

void CheckEstado(){
int estado = 0;
TRISC = salidas;
do{
	CE = 1;
	TRISD = entradas;
	CD = 1;
	WR = 1;
	CE = 0;
	RD = 0;
	estado = PORTD;
}while ((estado & 0x03) != 0x03);

RD = 1;
CE = 1;
TRISD = salidas;
}

void Inicializar(){
int16 c=0;
TRISC=salidas;
TRISD=entradas;

EnviarComando(OR_MODE);
EnviarComando(0x9c);

EnviarByte(0x00);
EnviarByte(GRAPHICS_HOME >> 8);	//parte alta de GRAPHICS_HOME
EnviarComando(GRAPH_HOME_SET);

EnviarByte(MaxBytePorFila);
EnviarByte(0x00);
EnviarComando(GRAPH_AREA_SET);

EnviarByte(0x00);
EnviarByte(TEXT_HOME >> 8);	//parte alta de TEXT_HOME
EnviarComando(TEXT_HOME_SET);

EnviarByte(MaxBytePorFila);
EnviarByte(0x00);
EnviarComando(TEXT_AREA_SET);

EnviarByte(0x03);
EnviarByte(0x00);
EnviarComando(OFFSET_REG_SET);

EnviarByte(0x00);
EnviarByte(0x00);
EnviarComando(CURSOR_PTR_SET);

EnviarByte(0x00);
EnviarByte(0x00);
EnviarComando(ADDR_PTR_SET);

EnviarComando(DATA_AUTO_WR);
for(c=0;c<0x1fff;c++)
{
AutoEscribir(0x00);
}
EnviarComando(AUTO_DATA_RESET);
}

void BorraTodoGrafico(int1 dato){
//bit 3 = 1 toda la pantalla "negra", bit 3 = 0 se borra
int a = 0, b = 0, reg = 0;

PunteroHomeGraficos();
if (dato != 0){
reg = 0xff;
}
else{
reg = 0x00;
}
for(a=0;a<128;a++)
{
	for(b=0;b<MaxPixelsFila;b++)
	{
		EnviarByte(reg);
		EnviarComando(DATA_WR_INC);
	}
}
}

void BorraTodoTexto(){
int t = 0, t1 = 0, reg = 0;

PunteroHome();
for(t=0;t<MaxCantFilas;t++)
	{
	for(t1=0;t1<MaxPixelsFila;t1++)
			{
			EnviarByte(reg);
			EnviarComando(DATA_WR_INC);
			}
	}
}

void Barras(){
int t = 0, t1 = 0, t2 = 0;
PunteroHomeGraficos();
for(t=0;t<MaxCantFilas;t++)
	{
	t2 = ~t2;
	for(t1=0;t1<MaxPixelsFila;t1++)
			{
			t2 = ~t2;
			EnviarByte(t2);
			EnviarComando(DATA_WR_INC);
			}
	}
}

void AutoEscribir(int dato){
int estado = 0;
do{
	CE = 1;
	TRISD = salidas;
	TRISD = entradas;
	CD = 1;
	WR = 1;
	RD = 0;
	CE = 0;
	estado = PORTD;
}while ((estado & 0x08) !=0x08);

CE = 1;
TRISD = salidas;

PORTD = dato;

CE = 0;
WR = 0;
RD = 1;
CD = 0;

delay_us(1);

CE = 1;
}

void GoToXY(int x, int y){
int16 t = 0;
t = x*MaxCantFilas + y + TEXT_HOME;
//t = TEXT_HOME + (((int16)y) * MaxBytePorFila ) + x;
EnviarByte(t & 0xff);
EnviarByte(t >> 8);
EnviarComando(ADDR_PTR_SET);
}

void main(){

Inicializar();

Barras();
BorraTodoGrafico(0);

//GoToXY(5, 5);
EnviarByte(0);
EnviarByte(0x00);
EnviarComando(ADDR_PTR_SET);

EnviarByte(0x21);
delay_ms(150);
EnviarComando(DATA_WR_INC);
}

Veo que enviás el byte "A" (0x21), pones una espera de 150 ms y luego después mandás el comando para escribir.
En principio no es necesario esperar entre una cosa y otra. El micro del T6963 ejecuta una instrucción más rápido que cualquier pic.
Si es para ver todo más lento 150 ms no te sirven de mucho, en todo caso ponele 1500 ms (1 seg y medio).

Si te repite un dato 8 veces, el error debería estar en el comando de escritura.
Probablemente en lugar de llegarle el comando DATA_WR_INC que vos mandás, le esté llegando el comando AUTO_DATA_RESET, o AUTO_DATA_WR.
Fijate los bits en que difieren los dos comandos y te dará la pista qué cables puedan estar sueltos, en corto o no hacer buen contacto.

P. Ej:
.........DATA_WR_INC = 0x0C0 = 0 1100 0000
.....AUTO_DATA_WR = 0x0B0 = 0 1011 0000
.AUTO_DATA_RESET = 0x0B2 = 0 1011 0010

Bueno, la idea es buscar por ahí.

Éxitos
 
Hola Alejandro Sherar. El delay_ms(150) si era para ver un poco mas lento pero me quedo de un for que hice para ver si podia ver las letras de la "A" a la "J". Con ese for lo que se mostraba era que las letras de la "A" a la "D" se superponian, luego al lado de la "D" salia la "E" y se le superponia la "F" y de ahi en mas salian las demas letra (todas en grupo de 8 siempre, que mal :( ). Voy a probar con el cableado de la glcd al pic a ver si le doy solucion por ese lado. Gracias por el dato y despues comento a ver como me fue.
 
Que tal Alejandro Sherar:

Fijate los bits en que difieren los dos comandos y te dará la pista qué cables puedan estar sueltos, en corto o no hacer buen contacto.

Ayer pude probar las conexiones y arme una ficha (en vez de tener cables sueltos). Lamentablemente sigue dando el mismo error. Por lo tanto voy a descartar que sean las conexiones de la glcd al pic y tambien el ruido (todo el cicuito trabaja a 5v), porque ya probe con un capacitor electrolitico de 470uF. Asi que voy a dedicarme a revisar el codigo. Gracias por el tip, la verdad ahora queda un poquito mas prolijo todo.
 
Hola:
Ahora fijate que en la rutina CheckEstado, y otras de acceso al display, los pines que cambian deben ser seteados bien antes de hacer la lectura estado = PORTD; (o la escritura). Esto te asegura que estén en los valores correctos para la transición.
Los tiempos de espera durante la lectura o escritura son críticos.
Para comparación te copio mi rutina (es otro compilador y otro pic).

Tu rutina:
Código:
void CheckEstado(){
int estado = 0;
TRISC = salidas;
do{
	CE = 1;
	TRISD = entradas;
	CD = 1;
	WR = 1;
	CE = 0;
	RD = 0;
	estado = PORTD;
}while ((estado & 0x03) != 0x03);

RD = 1;
CE = 1;
TRISD = salidas;
}

Mis rutinas (yo uso el puerto B para los datos y el C para control, el TRISC lo seteo afuera):
Código:
// ----------------------------------------------------------------

unsigned short sget(void)  // lee estado del LCD
{
  unsigned short lcd_status;

  TRISB=0xFF;     //  ES_ENTRADA

  CEHI;   // desactiva chip (CE=1)
  CDHI;   // modo status  (CD=1)
  WRHI;   // desactiva grabacion  (WR=1)
  RDLO;	 // activa lectura  (RD=0)

  CELO;	 // activa chip (CE=0)
  CELO;   // repite para superar los 80 ns
  lcd_status = PORTB; // lee el puerto

  CEHI;   // desactiva chip
  RDHI;   // desactiva lectura

  return(lcd_status);
} // sget()

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

unsigned short dget(void)      // lee dato del LCD
{
  unsigned short lcd_byte;

  espera();  // usa sget() para esperar a que el estado del LCD sea "libre" y deja el puerto como ENTRADA

  CEHI;   // desactiva chip
  CDLO;   // modo dato
  WRHI;   // desactiva grabacion
  RDLO;	 // activa lectura

  CELO;	 // activa chip
  CELO;   // repite para superar los 80 ns
  CELO;   // repite para superar los 150 ns
  lcd_byte = PORTB; // lee el puerto

  CEHI;   // desactiva chip
  RDHI;   // desactiva lectura

  return(lcd_byte);
} // dget()

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

void dput(unsigned short byte) // escribe dato al LCD
{
  espera();  // usa sget() para esperar a que el estado del LCD sea "libre" y deja el puerto como ENTRADA

  TRISB=0;         //  ES_SALIDA

  CEHI;   // desactiva chip
  CDLO;   // modo dato
  RDHI;   // desactiva lectura
  WRLO;   // activa grabacion

  PORTB = byte; // escribe en el puerto
  CELO;	 // activa chip
  CELO;   // repite para superar los 80 ns

  CEHI;   // desactiva chip
  WRHI;   // desactiva grabacion

} // end dput()

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

void cput(unsigned short byte) // escribe comando al LCD
{
  espera();  // usa sget() para esperar a que el estado del LCD sea "libre" y deja el puerto como ENTRADA

  TRISB=0;         //  ES_SALIDA

  CEHI;   // desactiva chip
  CDHI;   // modo comando
  RDHI;   // desactiva lectura
  WRLO;   // activa grabacion

  PORTB = byte; // escribe en el puerto
  CELO;	 // activa chip
  CELO;   // repite para superar los 80 ns

  CEHI;   // desactiva chip
  WRHI;   // desactiva grabacion
  } // cput()

// ----------------------------------------------------------------
No aflojes, que si esto no anda lo adapto a mi compilador y lo pruebo con mi display.
 
Alejandro Sherar, probe el codigo que posteaste pero sigue dando el mismo problema. Comento que tambien hice el cambio del portd al portb porque pense que podira estar por defecto habilitado el psp del pic (a pesar que despues lo deshabilito por software cuando volvi al portd). Algo extraño es que cuando volvi al portd no solo salieron las 8 "A" sino que se repitieron en las 16 filas (fuente de 8x8 pixels, glcd de 240x128 pixels). Inmediatamente reseteo y ya no salen mas. Me pregunto si tendra algo que ver la hubicacion del mapa de memoria de la glcd? En fin, voy a ver la rutina que me verifica el estado (CheckEstado en mi "intento" de libreria), ya que es la unica con un bucle. Cuando tenga novedades las hago saber.
 
Atrás
Arriba