Touch Screen GLCD 160x80, desarrollo con ASM + PIC18F4550

De tema de tesis tengo que hacer algo con xbee, el punto es que compre una pantalla touch 160x80 http://www.infinitumpage.mx/GIOSYS/pagina2680.html
El manual esta adjuntado.
Leyendo el mini-manual que viene en .txt me dispuse a trabajarlo y logre satisfactoriamente enviar una cadena de caracteres al GLCD.
La mayor parte de las instrucciones las saque del manual.
No quiero trabajar con C, ya que se me hace algo muy complejo, en especial la modificacion de librerias.

Tenemos 3 pines de control: E,R/W y RS:

RS=1: instruccion
RS=0: datos

E : habilita la funcion write durante la transicion de 1 a 0
(ver manual)

Aqui se observa que para lograr comunicacion con el display solo tenemos que indicar si vamos a enviar una instruccion o un dato (RS), luego poner el dato en D(0-7), y despues generar la transicion de 1 a 0 en (E), para que el display acepte la informacion, asi por cada dato o inst. que enviemos.

Para trabajar con el 18F4550 debemos declarar su propia libreria y los configuration bits:

Código:
LIST P=18F4550 ;Directiva para definir el procesador
    #include <P18F4550.INC> ;Definicion de SFRs para el procesador
  ;******** Configuracion del Oscilador **********
           CONFIG FOSC = INTOSCIO_EC        ;Osc interno, RA6 como pin, USB usa Osc EC
    ;******** Otros bits de configuracion **********
    CONFIG PWRT = ON ;PWRT habilitado
    CONFIG BOR  = OFF ;Brown out reset deshabilitado
    CONFIG WDT = OFF ;Watchdog deshabilitado
    CONFIG     MCLRE = OFF ;MCLR como entrada
    CONFIG PBADEN = ON ;Todos los pines como entradas analogicas
    CONFIG LVP = ON ;Programacion en bajo voltaje apagado
    ;********* Bits de proteccion ******************
    CONFIG CP0 = OFF ;los bloques del codigo de programa
    CONFIG CP1 = OFF ;no estan protegidos
    CONFIG CP2 = OFF
    CONFIG CP3 = OFF
    CONFIG CPB = OFF ;Sector Boot no esta protegido
    CONFIG CPD = OFF ;La EEPROM no esta protegida

Despues debemos de considerar variables para hacer rutinas de retardo:

    CBLOCK 0x000 ;Variables en la ACCESS RAM (Banco 0) max 96 bytes
    Cantms:2 ;variable para generar hasta 65535 ms
    CantSeg ;Variable para producir retardos de hasta 255 seg
    ENDC

    #DEFINE    pine    LATE,1   
    #DEFINE    pinrs    LATE,0 

Iniciando perifericos

    ORG 0x0000
     
    goto Main ;Se va al inicio del codigo principal
     
    Main
    ;******************* Inicializamos perifericos ***************************
    clrf    LATD
    clrf     TRISE,.0
    movlw     B'01100000'     ;Ajustamos el oscilador interno a 4 MHz
    movwf     OSCCON,.0
    movlw     B'00001111'
    movwf     ADCON1,.0     ;Todos los pines como I/O digitales
    clrf           TRISD,.0

Mandar datos a la GLCD es sencillo, como si se tratara de una 16x2, El problema es el PIN R/W, ya que el fabricante dice que: "el display tiene una bandera de espera la cual tiene que ser leiday comprobada antes de enviar el siguiente dato. Para evitar esto, solo debemos poner a tierra R/W para que siempre estemos escribiendo en el display, cuando mandemos un dato el PIN E debe de tener una cierta espera, yo le puse un retardo de casi 20 uS, con un oscilador interno a 4 Mhz.

Los pasos para configurar el GLCD modo caracter, 20 char x 10 renglones son los siguientes:


tabla1= 00,38,01,77,02,13,03,4F,04,07,08,00,09,00,0A,00,0B,00,0C

pone RS=0
variable X=13h (19 datos de la primer tabla)

ciclo1 pone RS=RS xor 1 (*)
Pone E=1
Lee dato de TABLA1
manda dato al puerto (display)
pone E=0
rutina de retardo (opcional)
decrementa en uno a variable X
si variable X es diferente de cero regresa a ciclo1

En el MPLAB quedaria asi:

Código:
;******************INICIA GLCD********************
    bcf    pinrs
    movlw    0x13        ;
    movwf    0x003    
    movlw    0x0B
    movwf    0x004    ;

    clrf     TBLPTRU
    clrf    TBLPTRH ; limpia TBLPTRU
    movlw    0x82
    movwf     TBLPTRL  ; carga a 82 en TBLPTRL

ciclo:    
    movlw      0x01
    xorwf        LATE,1,.0
    bsf            pine
    TBLRD*+  ; TABLAT++
    movf        TABLAT, W ; W <- TABLAT
    movwf     LATD     ; dato <- W
    bcf            pine
    rcall         retarm
    decfsz     0x003,f
    goto        ciclo     ; bucle eterno

    bcf    pinrs
    goto    pruebas

    ORG     0x82
    DB    0X00,0X38,0X01,0X77,0X02,0X13,0X03,0X4F,0X04,0X07,0X08,0X00,0X09,0X00,0X0A,0X00,0X0B,0X00,0X0C
    ; *************FIN DE LA TABLA ****************


El proveedor recomienda ejecutar una funcion XOr entre el valor de el bit que se haya designado para RS y "1", Ej: RS = Ra2(pic) entonces Ra2=Ra2 [XOR] 04h (0000 0100).
esto hará que el valor se invierta en forma alternada y nos de los valores para (RS) conforme a la primer tabla, observemos que se ha iniciado RS=0 para que en el primer ciclo esta se convierta en "1" para la primer instruccion, posteriormente cambiara su valor alternando 0,1,0,1,etc.
En el ciclo2 RS no cambia su valor de CERO ya que solo mandaremos DATOS al display.

Ahora enviamos caracteres al display, yo envie la palabra: "Hamburguesa".
La secuencia es:
variable X=11h (1 datos de la segunda tabla porque la palabra hamburguesa tiene 11 letras)

ciclo2 pone E=1
Lee dato de TABLA2
manda dato al puerto (display)
pone E=0
rutina de retardo (opcional)
decrementa en uno a variable X
si variable X es diferente de cero regresa a ciclo2
FIN de secuencias

;***********MANDA CARACTERES*************

clrf TBLPTRU
clrf TBLPTRH ; limpia TBLPTRU
movlw 0XEE
movwf TBLPTRL ; carga a 101 en TBLPTRL
cicda:
bsf pine
TBLRD*+ ; TABLAT++
movf TABLAT, W ; W <- TABLAT
movwf LATD ; dato <- W
bcf pine
rcall retarm
decfsz 0x004,f
goto cicda
push
goto sigue

ORG 0XEE
DB "Hamburguesa"

;*************FIN DE ENVIO DE CARACTERES**************


sigue:
retarm
movlw 0x20
movwf 0x005
mass
decfsz 0x005,f
goto mass
return


END ;Directiva fin del programa




Bueno, el proveedor de esta pantalla dice que despues de configurar la GLCD apareceran caracteres basura, el recomienda una rutina sencilla que posteo con algunas de sus propias palabras:

El Display no posee instruccion alguna para borrar el contenido de la memoria RAM por lo que despues del ciclo de inicializacion apareceran caracteres basura. por lo tanto habra que realizar un ciclo de borrado (clear screen):


--------- este ciclo va despues de la inicializacion TABLA1

variable X=C8h (200 caracteres)

ciclo3 pone E=1
manda 00 al puerto (display)
pone E=0
rutina de tiempo
decrementa en uno variable X
si variable X es diferente de cero regresa a ciclo3

** pone RS=1
pone E=1
manda 0A al puerto (instruccion RAM ADD LOWER)
pone E=0
pone RS=0
pone E=1
manda XX al puerto (direccion 00 a C7)
pone E=0
pone RS=0

------- aqui continua el ciclo2 que envia la TABLA2 al display



Recordar que al terminar la rutina de borrado el apuntador interno de el display estara en 00C8 el cual señala una posicion de RAM fuera de el display, tienes que volver a mandar el SET para la instruccion: RAM ADD lower y upper y juntas (16bits) forman la direccion para escribir en la memoria RAM destinada al display.

En el ejemplo se configura el display a 20x10 caracteres, quedando la memoria de la siguiente manera (hexadecimal):

0000 0001 0002 0003 0004 0005 0006 ...... 0013 <--- 20 caracteres renglon 1
0014 0015 0016 0017 0018 0019 001A ...... 0027 <--- 20 caracteres renglon 2
-------
-------
-------
00B4 00B5 00B6 00B7 00B8 00B9 00BA ...... 00C7 <--- 20 caracteres renglon 10



Se observa que los 8 bits de la izq (upper) siempre estan en cero, entonces si queremos "escribir" en el display desde el principio (angulo superior izq) solamente debemos mandar el set para LOWER=cero.

si preferimos ponerlo en cualquier valor de 00h a C7h. esto seria como un goto(xy) Ej: si ponemos "HOLA" al centro (aprox) de la pantalla el valor para LOWER seria 58h.

Asi indicaremos donde queremos empezar a "escribir" en la pantalla.


Realize una rutina para estas instrucciones, metiendolas justo entre el fin de la tabla 1 y el principio de donde dice: ENVIO DE CARACTERES quedando como sigue:

;*****LIMPIA LA PANTALLA***********
movlw 0x0C8 ;PARA LIMPIAR LA PANTALLA
movwf 0x00A ;PARA LIMPIAR LA PANTALLA
limpia bsf pine
movlw 0x00
movwf LATD
bcf pine
rcall retarm ; ***********retardo
decfsz 0x00A,f,.0
goto limpia
bsf pinrs
bsf pine
movlw 0x0A
movwf LATD
bcf pine

bcf pinrs
bsf pine
movlw 0x00 ;*********GOTO(XY)
movwf LATD ; ********GOTO(XY)
bcf pine
rcall retarm ; ***********retardo
bcf pinrs
;*************FIN LIMPIAR LA PANTALLA***********



Bueno la cuestion es que no funciona, no se ve nada en la pantalla, se queda en blanco y no sirve esta minirutina, aqui pido su ayuda, ya que me es urgente hechar a andar esa screen, despues voy a meterle graficos y posteriormente el manejo de la touch, en 3 meses lo debo de terminar, asi que voy a decir siempre como lo hize, gracias.
 

Adjuntos

  • touch.txt
    20.3 KB · Visitas: 44
Última edición:
Saludos... hace algunos meses trabajé con ese mismo GLCD, pero con el uC PIC16F874A. El proyecto consistía básicamente en un contador de oscilaciones en un determinado tiempo programado por el usuario.
De igual manera está hecho en ASM. Te dejo el código, allí viene la rutina que usé para el borrado del GLCD y están declarados los puertos que controlan cada pin del GLCD.

Otra cosa es que revises también la señal de contraste, ya que esta no se conecta como comunmente en los demás LCD's.
 

Adjuntos

  • osc.txt
    14.7 KB · Visitas: 62
Muchas gracias Daniel, me funciona el codigo de limpiar la pantalla, pero no sabes porque razon no funciona mi rutina?, estoy haciendo cada paso como lo dice la nota del proveedor ???
Por cierto veo que le pusiste rutina de demora de 1 milisegundo cuando E =0, yo solo le coloco 20 microsegundos, sera suficiente ???
Por cierto, lo de la sennal del contraste la conecte tal y como el esquema de conexionado que aparece en la pagina de el proveedor.
 
Última edición:
No estoy muy metido aún en el asm de los PIC18, pero me parece que el problema está en que utilizas los registros LATD en lugar de PORTD. Sobre la temporización, utilicé 1 milisegundo para asegurar que no tenga problemas de temporización (peor caso), ese valor me pareció suficiente y no se nota el retardo al momento de mostrar texto en el GLCD, me parece que en el caso de imágenes si se alcanza a notar el llenado de datos.
 
Oye daniel una pregunta, en tu codigo cuando mandas ya sea datos o comandos, mandas primero el dato al puerto y luego habilitas o desahbilitas los pines RS y E, en el manual dice que mandes RS a 0/1, E=1 mandes datos y luego E=0, es lo mismo ??????????
 
Es lo mismo, lo importante es que el byte, ya sea una instrucción o un dato estén estables al momento de mandar E a bajo, no hay falla entre activar primero RS y después enviar el dato o enviar el dato primero y después activar RS, siempre y cuando RS y el dato estén estables al momento de "escribir" los datos en el GLCD por medio de E=0
 
Ahora la pregunta que sigue, despues de que envio caracteres al GLCD, tengo que situar el cursor en donde yo quiera poner el caracter y mandar las palabras no es asi ?.
 
Es correcto como paso inicial, es decir, supongamos que "limpias" el GLCD, en seguida tienes que ajustar la posición del cursor, situándolo en donde quieres que aparezca tu texto (Esto se hace escribiendo la posición correspondiente en los registros de posición, si no mal recuerdo se accede a ellos por medio de los comandos 0x0A y 0x0B, corrobora en la hoja de datos). Una vez situado el cursor, los caracteres se irán desplegando uno en seguida del otro en el orden que los envíes, esto es, internamente el GLCD actualiza el cursor para mostrar el siguiente caracter.
 
Biem, tu ayuda me ha servido de mucho, me atore porque solo mandaba el lower del cursor sin mandar el upper, ahora intentare mandar graficos al glcd, o graficos y texto, haber como me sale. Has trabajado con su modulo Touch ???????
 
Bien... para trabajar los gráficos te recomiendo el programa Bitmap2LCD, es muy fácil convertir imágenes en código para pegarlo en tu programa. Referente al modulo Touch no lo he usado, me he entretenido más intentando hacer funcionar su backlight... ¿ya lo has conseguido tu?
 
ok si tengo el bitmap, lo estoy usando, solo que me cuesta trabajo migrar al 18f4550, es muy diferente, sobre el backlight, en la pagina esa que dan, recomiendan el SP4423, pero no lo he visto en AG, no se si en el salvador lo tengan, supongo que desarmando algun modulo de alguna lcd que tenga backlight, pueda funcionar, o hacerlo con componentes pasivos, unos opamps que generen el pulso que dice es de aprox. 300Hz y algun circuito elevador de tension para los 150Vpp, manejar bien la corriente, y lo que me llama la atencion es poder variar la intensidad luminosa, yo creo que bajando el Vpp se logra, cuando tenga mayor avance de mi tesis hare esa parte, suena interesante.
 
Tampoco encontré ese integrado, intenté armar algo con un inversor pero no me va por el uso de un transformador grande (no tengo mucho espacio).
Recién adquirí el módulo, solicité a la página del distribuidor que me enviara el diagrama para hacerlo funcionar, y aún no recibo respuesta :(.
En varios locales he visto que lo tienen como muestra y haciendo funcionar su backlight con un circuito bien sencillo, he pensado pedirles que me lo muestren para copiarlo jaja.
En fin, ya es otro tema, saludos y suerte con esa tésis.
 
Ahhh ya veo, como metes los datos en la memoria de programa?, es necesario escribir en los registros EECON?.
Para mandar 1600 bytes usas la bandera Z, yo uso un decrementador en 2 registros de 8 bits, asi son 16 bits, para que usas esa bandera?, la vdd nunca he podido mandar graficos a la GLCD.
 
Para almacenar los datos en la FLASH del PIC solamente se declaran como contantes con la directiva DT.

ORG 0x0800
Tabla2

DT 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00

De esta manera, al ensamblar el programa, a partir de la dirección 0x800 (En este caso), estarán los datos definidos por DT.

El registro EECON lo utilizo para controlar la lectura de datos de la tabla anterior, EEADRH y EADR son los bytes alto y bajo respectivamente del puntero de donde se leerán los datos, EEDATA es el registro donde se devuelve el dato leido.

Con respecto a lo del conteo de datos, lo que hago es inicializar dos variables (Puntero alto y bajo) con la dirección de inicio de la tabla por medio de las instrucciónes:

movlw HIGH Tabla2
movwf AdH
clrf AdL

de esta forma AdH contine 0x08 y Adl contiene 0x00, en conjunto apuntan a 0x0800, al inicio de la tabla.
Durante la rutina de lectura de datos la dirección formada por AdH y AdL se copian a los registros EEADRH y EADR para obtener los bytes de la imágen.
Una vez hecho esto, el registro AdL se incrementa para apuntar al siguiente byte, y así sucesivamente hasta que estos registros llegan a AdH=0x0E y AdL=0x40, es decir 0x0800 + 0x640 (1600 en decimal) momento en el cual se han enviado los 1600 bytes.
He de aclarar que la forma que usas tu de 2 registros es más cómoda, yo lo implementé así a modo de prueba.

Espero haber sido claro... si no pues nos estamos comunicando
 
Ahh es direccionamiento indirecto no es asi?, para mi micro yo uso los comandos TBLT que son un dolor de cabeza si no se sabe usarlos, lo malo es que simule el programa con la funcion de debugg y los datos salen uno por uno al glcd, pero por alguna razon la GLCD se ve con lineas raras que no son las que yo mando, lo que veo es que no pusiste la rutina aquella de limpiar la pantalla y poner el cursor en 0X00, ya no vale aqui o ke onda ?
 
Si, es direccionamiento indirecto. ¿Usas algún simulador como proteus?, aunque este no disponga del módulo GLCD puedes ir viendo como salen los datos del uC.
En este caso no utilicé la rutina de limpiar pantalla ya que la misma imágen sustituye a los datos "basura" del comienzo.

pero por alguna razon la GLCD se ve con lineas raras que no son las que yo mando

En este punto, ¿Lo que se ve tiene algún parecido con la imagen que piensas mostrar?, me refiero a que si medio se distingue alguna forma o figura familiar
 
respecto alo del proteus puedo usar el 128 x 64 como si fuera la glcd?, supongo que mas alla de esos limites la pantalla del proteus no mostrara los resultados no?.
ala imagen la adjunto.
 

Adjuntos

  • lcd.JPG
    lcd.JPG
    48.8 KB · Visitas: 43
respecto alo del proteus puedo usar el 128 x 64 como si fuera la glcd?

No es posible. Esta GLCD tiene un controlador distinto al modelo que viene en proteus.

Haz una prueba del GLCD, configurala en modo gráfico y envía un patrón de pixeles. Supongamos 0x55 1600 veces, de esta manera se tendrá que ver una serie de lineas paralelas alternadas entre sí. Si el GLCD pasa esta prueba el problema puede estar en el programa que toma los datos de la memoria del PIC y los envía al GLCD
 
Atrás
Arriba