Noticias:

Grupo en telegram, del foro de meteorología fácil: https://t.me/meteorologiafacil

Para mas detalles, puedes visitar el siguiente tema http://www.meteorologiafacil.com.ar/foros/index.php?topic=1608.0

Espero que les sea de mucha utilidad.

Menú Principal

GLCD y Jal Dudas al por mayor

Iniciado por YO, Marzo 21, 2012, 12:49:30 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

HJ

#15
Hola, encontré esta librería en un par de foros y aparentemente anda... se las dejo en consideración. Obviamente no tengo ni idea si puede o no andar.

Enlace 1
Enlace 2

Saludos
HJ


-- Title: lcd_ks0108 - Library for KS0108 compatible LCD
-- Author: Serkan Ayyýldýz Copyright (c) 2006..2009, all rights reserved.
-- Adapted-by: Joep Suijs
-- some small changes: Michael Watterson (c)2010
-- Compiler: >=2.2
--
-- This file is part of jallib (http://jallib.googlecode.com)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Library for KS0108 compatible graphic lcd with 128x64 resolution.
--
--
-- Notes:
--
const KS0108_LEFT = 0
const KS0108_RIGHT = 1
const KS0108_CMD_ON = 0x3F
const KS0108_CMD_OFF = 0x3E
const KS0108_CMD_PAGE = 0xB8
const KS0108_CMD_COLUMN = 0x40
const KS0108_CMD_TOP_RAM = 0xC0

-- Purpose: Write a byte of data to the specified chip
-- Inputs: 1) chipSelect - which chip to write the data to
-- 2) data - the byte of data to write
procedure _ks0108_write(byte in side, byte in data) is
   if side == 1 then -- Choose which side to write to
      GLCD_CS2 = high
   else
      GLCD_CS1 = high
   end if
   GLCD_RW = low -- Set for writing
   GLCD_DATAPRT = data -- Put the data on the port
   GLCD_DATAPRT_DIR = all_output
   _usec_delay (1)
   GLCD_E = high -- Pulse the enable pin
   _usec_delay (2)
   --delay2_us
   GLCD_E = low
   GLCD_CS1 = low -- Reset the chip select lines
   GLCD_CS2 = low
   --delay_2us()
   _usec_delay (2)
end procedure

-- Purpose: Reads a byte of data from the specified chip
-- Ouputs: A byte of data read from the chip
function _ks0108_read(byte in side) return byte is
var byte data -- Stores the data read from the LCD
   GLCD_DATAPRT_DIR = all_input -- Set port d to input
   if side == 1 then -- Choose which side to write to
      GLCD_CS2 = high
   else
       GLCD_CS1 = high
   end if
   GLCD_RW = high -- Set for reading
   _usec_delay (1) -- delay_cycles(1)
   GLCD_E = high -- Pulse the enable pin
   _usec_delay (2)
   data = GLCD_DATAPRT -- Get the data from the display's output register
   GLCD_E = low
   GLCD_CS1 = low -- Reset the chip select lines
   GLCD_CS2 = low
   _usec_delay (2)

   return data -- Return the read data
end function

-- Purpose: Turn the display on
procedure lcd_on() is
   _ks0108_write(KS0108_LEFT, KS0108_CMD_ON)
   _ks0108_write(KS0108_RIGHT, KS0108_CMD_ON)
end procedure

-- Purpose: Turn the display off
procedure lcd_off() is
   _ks0108_write(KS0108_LEFT, KS0108_CMD_OFF)
   _ks0108_write(KS0108_RIGHT, KS0108_CMD_OFF)
end procedure

-- Purpose: Set the page number
-- Inputs: A page number (0 - 7)
procedure _ks0108_page(byte in side , byte in page) is
  _ks0108_write(side, KS0108_CMD_PAGE | page)
end procedure

-- Purpose: Set the column address
-- Inputs: The column address (0 - 63)
procedure _ks0108_column(byte in side, byte in column) is
   _ks0108_write(side, KS0108_CMD_COLUMN | column)
end procedure

-- Purpose: Specify reads and writes are instructions
procedure _ks0108_inst() is
   GLCD_DI = low
end procedure

-- Purpose: Specify reads and writes are data
procedure _ks0108_data() is
   GLCD_DI = high
end procedure

-- Purpose: Turn a pixel on a graphic LCD on or off
-- Inputs: 1) x - the x coordinate of the pixel
-- 2) y - the y coordinate of the pixel
-- 3) color - ON or OFF
procedure PlotPixel(byte in x, byte in y, bit in onoff) is
var byte data , yy
var byte side = KS0108_LEFT -- Stores which chip to use on the LCD
   if x > 127 then
      x = x -128
   end if
   if x > 63 then -- Check for first or second display area
       x = x - 64
       side = KS0108_RIGHT
   end if
   if y > 191 then
        y = y -192
   elsif y > 127 then
        y = y - 128
   elsif y > 63 then
        y = y -64
   end if
   _ks0108_inst() -- Set for instruction
   _ks0108_column(side,x) -- Set the horizontal address
   _ks0108_page(side,(y / 8)) -- Set the page address
   _ks0108_data() -- Set for data
   data = _ks0108_read(side) -- Need two reads to get data at new address
   data = _ks0108_read(side) -- DO NOT REMOVE 2nd Read!
   -- add XOR code
   if onoff == 1 then
       -- bit_set(data, y%8) -- Turn the pixel on
       yy = y % 8
       data = data | ( 1 << yy )
   else -- or
       -- bit_clear(data, y%8) -- turn the pixel off
       yy = y % 8
       data = data & !( 1 << yy )
   end if
   _ks0108_inst() -- Set for instruction
   _ks0108_column(side,x) -- Set the horizontal address
   _ks0108_data() -- Set for data
   _ks0108_write(side, data) -- Write the pixel data
end procedure

procedure _ks0108_write_byte(byte in x, byte in y, byte in veri) is
var byte side = KS0108_LEFT -- Stores which chip to use on the LCD
   if x > 127 then
      x = x -128
   end if
   if (x > 63)then -- Check for first or second display area
       x = x - 64
       side = KS0108_RIGHT
   end if
   if y > 191 then
        y = y -192
   elsif y > 127 then
        y = y - 128
   elsif y > 63 then
        y = y -64
   end if
   _ks0108_inst() -- Set for instruction
   _ks0108_column(side,x) -- Set the horizontal address
   _ks0108_page(side,(y / 8)) -- Set the page address
   _ks0108_data() -- Set for data
   _ks0108_write(side, ! veri) -- Write the pixel data
end procedure

-- Purpose: Fill the LCD screen with the passed in color
-- Inputs: ON - turn all the pixels on
-- OFF - turn all the pixels off
procedure lcd_fill(byte in data) is
var byte i, j
   i = 0 -- Loop through the vertical pages
   for 8 loop
       _ks0108_inst() -- Set for instruction
       _ks0108_page(KS0108_LEFT,i) -- Set page address
       _ks0108_page(KS0108_RIGHT,i)
       _ks0108_column(KS0108_LEFT,0) -- Set horizontal address to 0
       _ks0108_column(KS0108_RIGHT,0)
       _ks0108_data() -- Set for data
       -- Loop through the horizontal sections
       for 64 loop
           _ks0108_write(KS0108_LEFT ,data) -- Write the byte of data
           _ks0108_write(KS0108_RIGHT,data)
       end loop
       i = i + 1
   end loop
end procedure

-- Purpose: Initialize the LCD.
-- Call before using any other LCD function.
procedure lcd_init() is
   -- Initialze some pins
   GLCD_DATAPRT = 0x00
   GLCD_DATAPRT_DIR = all_output
   GLCD_RW_DIRECTION = output
   GLCD_CS1_DIRECTION = output
   GLCD_E_DIRECTION = output
   GLCD_DI_DIRECTION = output
   --GLCD_RST_DIRECTION = output
   GLCD_CS2_DIRECTION = output
   --GLCD_RST = high
   GLCD_E = low
   GLCD_CS1 = low
   _ks0108_inst() -- Set for instruction
   _ks0108_write(KS0108_LEFT, KS0108_CMD_TOP_RAM | 0) -- First RAM line at the top of the screen
   _ks0108_write(KS0108_RIGHT, KS0108_CMD_TOP_RAM | 0) -- First RAM line at the top of the screen
   _ks0108_page (KS0108_LEFT ,0) -- Set the page address to 0
   _ks0108_page (KS0108_RIGHT,0)
   _ks0108_column(KS0108_LEFT ,0) -- Set the column address to 0
   _ks0108_column(KS0108_RIGHT,0)
   lcd_on() -- Turn the display on
   lcd_fill(0) -- Clear the display
end procedure

-- use for sprites or fonts that are multiple of 8 high
procedure BlitColumn (byte in x, byte in y,  byte in column ) is
   _ks0108_inst() -- Set for instruction
   if (x > 128) then
      x = x -128
   end if
       if y > 191 then
        y = y -192
   elsif y > 127 then
        y = y - 128
   elsif y > 63 then
        y = y -64
   end if
   if (x < 64) then
       _ks0108_column(KS0108_LEFT,x) -- Set the horizontal address
       _ks0108_page(KS0108_LEFT, (y / 8)) -- Set the page address
       _ks0108_data() -- Set for data
       _ks0108_write(KS0108_LEFT, column) -- Write the pixel data
   else
       _ks0108_column(KS0108_RIGHT, x-64) -- Set the horizontal address
       _ks0108_page(KS0108_RIGHT, (y / 8)) -- Set the page address
       _ks0108_data() -- Set for data
       _ks0108_write(KS0108_RIGHT, column) -- Write the pixel data
   end if
end procedure

procedure PlotColumn(byte in x, byte in y, byte in column, bit in ink, bit in replace) is
-- if ink is false, invert column data
-- if replace is true, plot 0 and 1 ink, else plot only only ink value ink
var byte data
var byte side = KS0108_LEFT -- Stores which chip to use on the LCD
   if x > 127 then
      x = x -128
   end if
   if x > 63 then -- Check for first or second display area
       x = x - 64
       side = KS0108_RIGHT
   end if
   if y > 191 then
        y = y -192
   elsif y > 127 then
        y = y - 128
   elsif y > 63 then
        y = y -64
   end if
   if replace then
      if ink then
         data = column
      else
         data = ! column
       end if
   else
       _ks0108_inst() -- Set for instruction
       _ks0108_column(side,x) -- Set the horizontal address
       _ks0108_page(side,(y / 8)) -- Set the page address
       _ks0108_data() -- Set for data
       data = _ks0108_read(side) -- Need two reads to get data at new address
       data = _ks0108_read(side) -- DO NOT REMOVE 2nd Read!
      if ink then
          data = data | column
      else
          data = data & (! column)
      end if
   end if
   _ks0108_inst() -- Set for instruction
   _ks0108_column(side,x) -- Set the horizontal address
   _ks0108_page(side,(y / 8)) -- Set the page address
   _ks0108_data() -- Set for data
   _ks0108_write(side, data) -- Write the pixel data
end procedure


Edito: Cuando hice en MikroC el programa para controlar el LCD del Nokia 1100 tube que trabajar con loas lectras como si fuesen imágenes, es decir, posicionar el cursor y dibujar el punto correspondiente.

Edito 2: Hoja de datos.

YO

Si, con el contraste a fondo se realzan todos los pixeles.

Fijate si tenes el display conectado de esta manera:

Pin 1 = GND
     2 = + 5v.
     3 = Vo (cursor de preset contraste)
     4 = D/I
     5 = R/W
     6 = E
     7 = DB0
     8 = DB1
     9 = DB2
    10 = DB3
    11 = DB4
    12 = DB5
    13 = DB6
    14 = DB7
    15 = CS1
    16 = CS2
    17 = RST
    18 = Vee (salida a preset de contraste 10 K el otro extremo va a GND)
    19 = Led + (conectar a resistor de 220 o 100 ohm y èste a 12 volts )
    20 = Led - ( a misma fuente de 12 volts )

De otra forma no funciona.
Hay muchas formas de conexiòn pero para èste modelo es esta.
Chequealo y contame
Sin saber que era imposible El fue y lo hizo

David Met

¡Ajá! Ahí está mi error.
La salida Vee, la dejé al aire. No lo puse en el contraste.

Probando.......
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

YO

Gracias HJ!
Ya probé con librerías diferentes y todas hechas por la misma gente, pero ninguna funciona completamente, por ejemplo: la librería original funciona con otra libreria adicional llamada common,que a su vez debería trabajar con las otras que son las Font (hay una para cada tamaño de letra y son tres).
Pero como te decía, con la librería original del paquete Jal no puedo poner una palabra completa, solo me deja poner caracteres sueltos, pero el comando print no toma los caracteres de la tabla automáticamente para formar palabras completas.
Si lo puedo hacer con otra librería que no está en el paquete, escribe la palabra completa pero....
esa librería no me deja poner las direcciones de escritura que yo quiero, corrijo, me deja, pero después las pone en forma aleatoria donde se le ocurre, y para peor como el display está dividido en dos controladores diferentes siempre lo hace con el de la derecha, según la dirección que le pongas la librería decide de que lado escribir y a que altura, y ésto en la librería está muy bien definido, pero no hace lo que debería.
Para colmo las librerias que no están en el paquete no son compatibles totalmente con estas y no podes mezclar nada porque directamente no te compila, aunque tengan todas las mismas bases, están renombradas para diferenciarlas y hasta encontré un sitio en donde ellos mismos dicen que tienen algunos problemas no resueltos todavía con el compilador (justamente hablando del tema del glcd)
Es probable que :
1) o estoy haciendo algo mal, que ni siquiera funcionan los ejemplos.
2) que la forma de direccionar no sea la correcta para este display en particular.
3) que las librerías no me entiendan (o al revez  :jeje:)

Una de las cosas que me llama la atención de la librería que encontraste es que no tenga la tabla con todos los caracteres de escritura, será cuestión de probarla, despues te cuento.
Sin saber que era imposible El fue y lo hizo

YO

Hola David!
El contraste trabaja con con tensión negativa según tengo entendido, por lo tanto, por la entrada Vo tendrías una variación de 0 a -5v o lo que salga por Vee
Espero que haya resistido los 5v+ que le mandaste, medio como que me asusta........
Sin saber que era imposible El fue y lo hizo

David Met

Anda  :\ Se encendieron todos los puntos del GLCD.
Se salvó porque jamás los dejo mucho tiempo cuando no anda de una. Es una prevención que tomo y que estoy acostumbrado hacer. Si no anda de una, apago todo.

Ahora a empezar a trabajar en ella.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

YO

Uffff, menos mal!! :\ :\

El Dr. Frankenstein decìa: -Està vivo, viiiivoooo-  jajajajaja
Sin saber que era imposible El fue y lo hizo

David Met

jajajajajaja

Consulta, por casualidad ¿tenés el protocolo de comunicación del controlador KS0108?
Así no me gasto en entender esas librerías que no sabemos si andan y me pongo hacer una yo, paso a paso.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

YO

Si , lo encontrè y me lo puse a descifrar antes de salir de vacaciones, es justamente lo que tengo en borrador pero en la compu de la fàbrica, acà tengo una copia hecha a mano del original, la escaneo y la pego en un rato.
Sin saber que era imposible El fue y lo hizo

YO

#24
Acà estàn los comandos para el glcd:

Fijate la columna RS es lo mismo que D/I = Dato/Instruccion
Sin saber que era imposible El fue y lo hizo

David Met

Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

David Met

Bueno, ahí lo estuve estudiando un poco, más lo que leí por toda la red, no parece ser complicado de usar.

El controlador, tiene una matriz en la RAM con la misma cantidad de pixeles. Esto está dividido en dos columnas. Cada columna tiene un ancho de 64 bit que se controla con un contador. Este contador se manipula el registro de dirección.
Cada fila, tiene un ancho de 8 bit, que son las entradas del LCD. Esto quiere decir que los datos se ingresan en forma vertical y no horizontal ¿es verdad esto?
Finalmente, para manejarnos por las páginas del 0 al 7; tenemos el registro Página.
Me olvidaba; para seleccionar las que columna se trabaja; se selecciona con los pines CS1 y CS2.

Lo que me resta saber, es si hay una configuración previa como los LCD comunes; en donde se configura si se trabaja con 8 o 4 bit; con cursor o sin cursor; si el texto se desplaza o no; etc. Por lo visto no, y hago la conclusión que solo habría que indicar que se debe encender el LCD y empezar a mandarle la información a mostrar.

Bueno, trataré de mañana empezar a escribir una librería al respecto.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

YO

Hola!

Para comenzar a utilizar los comandos hay que tener en cuenta lo siguiente:

Los pines del Pic que seleccionemos para comunicarnos deberían tener los siguientes valores:

Glcd encendido=
D/I = 0      - le decimos al glcd que va una instrucción.
R/W = 0   
Puerto de datos = 00111111 = 0x3F

*****************************************
Glcd apagado=
D/I = 0      - le decimos al glcd que va una instrucción.
R/W = 0   
Puerto de datos = 00111110 = 0x3E

*****************************************

Setear dirección Y=
D/I = 0      - le decimos al glcd que va una instrucción.
R/W = 0   
Puerto de datos = 01xxxxxx
                           [0 a 63]
Sumar 64 al valor Y necesario para colocar el valor correcto en el puerto ej.:

Se quiere dar a Y la posición 12
                                             12 = 00001100 = 0x0C
                                         +  64 = 01000000 = 0x40
                                            ___
                                             76 = 01001100 = 0x4C
Entonces para la dirección Y 12 en el puerto deberíamos poner 01001100

********************************************************

Setear página  (0 a 7) En función de la posición x (posición horizontal)=
D/I = 0      - le decimos al glcd que va una instrucción.
R/W = 0   
Puerto de datos = 10111xxx
                                [0 a 7]
Sumar 184 al valor x necesario para colocar el valor correcto en el puerto
De esta forma dividimos la pantalla en 8 franjas horizontales según valor de los tres bits mas bajos.

*********************************************************************

Setear línea de inicio del display   
D/I = 0      - le decimos al glcd que va una instrucción.
R/W = 0   
Puerto de datos = 11xxxxxx
                           [0 a 63]
Sumar 192 al valor x necesario para colocar el valor correcto en el puerto

**********************************************************

Escribir dato en display
D/I = 1      - le decimos al glcd que va un dato.
R/W = 0   
Puerto de datos = xxxxxxxx
                           
Ahora si en el puerto de datos ponemos el valor completo de 8 bits.
Despues de la instrucción de escritura la dirección "Y" se incrementa automáticamente en 1

********************************************************

Para cualquier instruccion que seleccionemos, deberíamos completarla con:

Seleccion de mitad de pantalla a usar =
Lado Izquierdo
CS1 = 1
CS2 = 0

Lado Derecho
CS1 = 0
CS2 = 1

****************

Pulso de Habilitación
E = 1
Tiempo de toma de datos (por lo menos cuatro ciclos de máquina)
E = 0

(Este parámetro hay que estudiarlo bien porque no lo encontré definido por el fabricante, ya que él asume que se debería Leer el status del display para saber si se liberó de su tarea y puede recibir más información.)
Esto lleva a más código y tiempo de ejecución, por eso simplemente le damos un tiempo prudencial para que resuelva su tarea.


En ningún lado vi la posibilidád de usar solo 4 bits de datos
Lo del cursor me parece que lo tendremos que resolver por código, igual que el desplazamiento
La escritura se realiza en cada página y en forma vertical
El dibujo se realiza pixel por pixel o punto por punto en cualquier sector de la pantalla

Por favor si estoy errado en algo corrijanme.










Sin saber que era imposible El fue y lo hizo

David Met

Perfecto, es lo que pensaba.
A la tarde, intentaré darle vida. Ahora me tengo que poner a estudiar.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

David Met

Al momento, estoy escribiendo un pequeño programa si librerías. Estoy haciendo todo. Pero estoy con una duda. No entiendo que se controla con la línea.

Las columnas, se selecciona con CS1 y CS2. Las páginas, se controlan con el registro PÁGINAS.
Ahora bien, cada página, tiene su columna, que se selecciona con el puntero controlador. Si los valores se agregan en forma vertical, para que son las líneas?

En el adjunto marca así una página:

d0
d1
d2
d3
d4
d5
d6
d7

Si hago una pequeña matrix de 0 a 5, es así:

/  c0 c1 c2 c3 c4 c5
d0 aa bb cc dd ee ff
d1 ab bc cd de ef fg
d2 ac bd ce df eg fh
d3 ad be cf dg eh fi
d4 ae bf cg dh ei fj
d5 af bg ch di ej fk
d6 ag bh ci dj ek fl
d7 ah bi cj dk el fm


Y quiero encender el pixcel aa; debo configurar columna 1 con CS1 = 1 y CS2 = 0. Seleccionar el contador D/I = 0 y R/W = 0 portd = 0x40 (contador = 0) Seleccionar la página 0 colocando D/I = 0 y R/W = 0, y enviar por el puerto D (en mi caso, que está conectado a la entrada de datos del GLCD) portd = 0b10111000
Luego debería configurar la línea ¿?  ???

Entonces, una vez echo esto, coloco los pines D/I = 1 R/W = 0 portd = 0b00000001 y habilito al LCD E = 1 lo dejo por 1000 ms (por dar un tiempo prudente) y luego coloco E = 0

Ahora bien, si yo quiero encender los pixceles aa; ac; ae; ag; hago todo lo mismo pero por el puerto d, en vez de mandar 0x01, envío portd = 0xAA.

Para dejarlo en claro, supongamos que deseamos encender solo el pixcel di (c3,d5); lo que tengo que hacer es:
-- Seleccionamos Columna 1
CS1 = 1
CS2 = 0
D/I = 0 -- Seleccionamos contador 3
R/W = 0
portd = 0x43
E = 1
delay_100ms(10)
E = 0
D/I = 0 -- Seleccionamos página 0
R/W = 0
portd = 0xB8
E = 1
delay_100(10)
E = 0
-- Encendemos el pixcel deseado
D/I = 1
R/W = 0
portd = 0x40 -- d6 = 1, el resto = 0
E = 1
delay_100ms(10)
E = 0
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.