Autor Tema: periféricos_LCD  (Leído 4387 veces)

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

Desconectado pepiño

  • PIC10
  • *
  • Mensajes: 11
periféricos_LCD
« en: 21 de Febrero de 2007, 18:34:47 »
hOLA fenómenos!!! Llevo ya unos dias cacharreando con un LCD y gracias a lo que aqui encontré pude por fin visualizar un mensaje; ahora tengo varias dudas pero os mando el programa que si funciona:

#include <16f84a.h>
#include <stdio.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPUT,NOPROTECT
#use fast_io(b)
#use fast_io(a)

#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7
#define LCD_RS  PIN_A0
#define LCD_RW  PIN_A1
#define LCD_E   PIN_A2

#include <flexlcd.c>//la de redpic

void main()
{
while(1)
{
set_tris_a(0x00);
set_tris_b(0x00);
lcd_init();
output_low(pin_A1);//***
lcd_gotoxy(3,1);
lcd_putc(".:PROYECTO_PIC:.");
lcd_putc("\n");
lcd_gotoxy(3,2);
lcd_putc("LCD_CONTROL_16F84");
delay_ms(200);//***
output_high(pin_A1);//***
}
}

Las dudas que me surgen son las siguientes:

¿esta libreria vale para LCD de 4lineas?

sobre el pin RW he observado que sin las lineas (***) y conectandolo a masa se ve mal el mensaje. ¿tiene esto algún sentido o mi LCD se ha vuelto loco?

gracias a todos, un saludo desde Galiza

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: periféricos_LCD
« Respuesta #1 en: 21 de Febrero de 2007, 18:44:14 »
Pues quitar las lineas

output_low(pin_A1);//***  y
output_high(pin_A1);//***

no deberian hacer diferencia, excepto que la libreria utilice el modo READ para leer el estado del LCD(busy) y saber cuando ha terminado de procesar el comando enviado.

Si la libreria no usa el modo READ para leer el estado del LCD, podes eliminar esas dos, pero NO esta:

delay_ms(200);//***

podrias bajarle un poco el tiempo ya que 200ms es medio mucho, pero no eliminar el retardo por completo ya que sino estas bombardeando al LCD con informacion y no mostrara nada.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado pepiño

  • PIC10
  • *
  • Mensajes: 11
Re: periféricos_LCD
« Respuesta #2 en: 21 de Febrero de 2007, 19:00:44 »
Gracia BrunoF por contestar. He hecho lo que me dices y el mensaje parpadea un poco.

RW está conectado a A1 y en la libreria #define USE_LCD_RW 1 como un cometario; ¿tendrá esto algo que ver en el mal funcionamienteo?

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: periféricos_LCD
« Respuesta #3 en: 21 de Febrero de 2007, 19:43:03 »
Proba desconectando RW de A1.
Conecta directamente el pin RW del LCD a GND.

No hagas un while. Envia el mensaje solo 1 vez y el parpadeo deberia irse.

Saludos.

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado pepiño

  • PIC10
  • *
  • Mensajes: 11
Re: periféricos_LCD
« Respuesta #4 en: 22 de Febrero de 2007, 09:43:32 »
Efectivamente BrunoF!!! Así se ve todo claro, aunque no entiendo lo de eliminar
#define USE_LCD_RW 1 de la libreria.

Ah!!! por cierto pongo aqui la libreria que estoy usando, vale para LCD 4x20; sólo consigo ver mensajes en la 2 primeras líneas.

En el programa he incluido stdio.h pero solo consigo mandar mensajes con lcd_putc() pero con el printf() no hay modo.

Un saludo y gracias por la ayuda aportada, pero no paro de tener dudas; esto de los pic engancha de verdad.

Desconectado pepiño

  • PIC10
  • *
  • Mensajes: 11
Re: periféricos_LCD
« Respuesta #5 en: 22 de Febrero de 2007, 09:47:38 »
la libreria que uso es esta:


//flexlcd.c

//#define USE_LCD_RW 1


#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
  0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
  0xc, // Display on
  1, // Clear display
  6 // Increment cursor
};


//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
  // Note: !! converts an integer expression
  // to a boolean (1 or 0).
  output_bit(LCD_DB4, !!(nibble & 1));
  output_bit(LCD_DB5, !!(nibble & 2));
  output_bit(LCD_DB6, !!(nibble & 4));
  output_bit(LCD_DB7, !!(nibble & 8));

  delay_cycles(1);
  output_high(LCD_E);
  delay_us(2);
  output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
  int8 retval;
  // Create bit variables so that we can easily set
  // individual bits in the retval variable.
  #bit retval_0 = retval.0
  #bit retval_1 = retval.1
  #bit retval_2 = retval.2
  #bit retval_3 = retval.3

  retval = 0;

  output_high(LCD_E);
  delay_cycles(1);

  retval_0 = input(LCD_DB4);
  retval_1 = input(LCD_DB5);
  retval_2 = input(LCD_DB6);
  retval_3 = input(LCD_DB7);

  output_low(LCD_E);

  return(retval);
}
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
  int8 low;
  int8 high;

  output_high(LCD_RW);
  delay_cycles(1);

  high = lcd_read_nibble();

  low = lcd_read_nibble();

  return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
  output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

  if(address)
  output_high(LCD_RS);
  else
  output_low(LCD_RS);

  delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

  output_low(LCD_E);

  lcd_send_nibble(n >> 4);
  lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
  int8 i;

  output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

  output_low(LCD_E);

  delay_ms(15);

  for(i=0 ;i < 3; i++)
  {
    lcd_send_nibble(0x03);
    delay_ms(5);
  }

  lcd_send_nibble(0x02);

  for(i=0; i < sizeof(LCD_INIT_STRING); i++)
  {
    lcd_send_byte(0, LCD_INIT_STRING);

    // If the R/W signal is not used, then
    // the busy bit can't be polled. One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}

}

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

void lcd_gotoxy(int8 x, int8 y)
{
  int8 address;

  if(y != 1)
  address = lcd_line_two;
  else
  address=0;

  address += x-1;
  lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
  switch(c)
  {
    case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;

    case '\n':
      lcd_gotoxy(1,2);
      break;

    case '\b':
      lcd_send_byte(0,0x10);
      break;

    default:
      lcd_send_byte(1,c);
      break;
  }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
  char value;

  lcd_gotoxy(x,y);

  // Wait until busy flag is low.
  while(bit_test(lcd_read_byte(),7));

  output_high(LCD_RS);
  value = lcd_read_byte();
  output_low(lcd_RS);

  return(value);
}
#endif

void lcd_setcursor_vb(short visible, short blink) {
  lcd_send_byte(0, 0xC|(visible<<1)|blink);
}

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: periféricos_LCD
« Respuesta #6 en: 22 de Febrero de 2007, 12:20:55 »
Efectivamente BrunoF!!! Así se ve todo claro, aunque no entiendo lo de eliminar
#define USE_LCD_RW 1 de la libreria.

Fijate que esa instruccion solo se utiliza si queres leer el estado del LCD o bien data del mísmo. Como solamente escribis en el LCD pero no lees nada, podes dejarla comentada.

Ah!!! por cierto pongo aqui la libreria que estoy usando, vale para LCD 4x20; sólo consigo ver mensajes en la 2 primeras líneas.

Nunca he usado displays LCD de 4x20 pero segun veo los intervalos de posicion de cada linea son:
Línea 1: [0x00;0x13]
Línea 2: [0x40;0x53]
Línea 3: [0x14;0x27]
Línea 4: [0x54;0x67]

Asegurate de estar trabajando en las posiciones RAM del LCD correctas, O utiliza gotoxy para posicionarte donde desees comenzar a escribir.

En el programa he incluido stdio.h pero solo consigo mandar mensajes con lcd_putc() pero con el printf() no hay modo.

Un saludo y gracias por la ayuda aportada, pero no paro de tener dudas; esto de los pic engancha de verdad.

Ahi me raspas. Date una vuelta por:
Ejemplitos en C para 16F648A

pero por lo que veo, siguen usando la  lcd_putc() dentro.

Jejeje si que engancha!!! :D
Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado polo1984

  • PIC10
  • *
  • Mensajes: 13
Re: periféricos_LCD
« Respuesta #7 en: 26 de Febrero de 2007, 08:30:11 »
hola a todos!!

estoy probando varios ejemplitos para visualizar en el lcd de este foro y de los que he probado ninguno me funciona. estoy compilando en ccs, el lcd es uno de cebek de 2x16 y el pic  que uso es el pic16f876a (aunque cambiandando el pic no creo que se cree ningun problema si se asignan bien los pines)
en este ejemplo que poneis me da un error al compilar que no se como solucionarlo, asi que no se que puedo hacer, abajo os lo pongo.

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
  {
    lcd_send_byte(0, LCD_INIT_STRING);

    // If the R/W signal is not used, then
    // the busy bit can't be polled. One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}


en la linea    lcd_send_byte(0, LCD_INIT_STRING); me aparece un error: "Attemp to create a pointer to a constant"

la verdad que estoy perdido, no se como solucionarlo. si alguien me da alguna pista, me dice con que compilador puede funcionar o me da algun ejemplito sencillo que le funcione le estaria agradecido

gracias por el trabajo que haceis aqui

Desconectado pepiño

  • PIC10
  • *
  • Mensajes: 11
Re: periféricos_LCD
« Respuesta #8 en: 26 de Febrero de 2007, 19:34:11 »
hola polo1984, yo tambien soy novato en esto pero a raiz de este hilo mi lcd si se ilumino!!!

Bueno, al tema: Lo más habitual es utilizar un LCD con driver específico, el HD44780 por lo que todo se hace más sencillo ya que en sintesis todos los LCD´s se programaran de igual modo.

El ejemplo de arriba con las correcciones indicadas va muy bien con el 16f84 y un LCD 2x20; mira por el datasheet de tu micro, algún fuse o si algun puerto de los que empleas esta multiplexado; ahora mismo es lo que se me ocurre....

Un saludo, seguimos en contacto

Desconectado polo1984

  • PIC10
  • *
  • Mensajes: 13
Re: periféricos_LCD
« Respuesta #9 en: 27 de Febrero de 2007, 07:15:15 »
hola

he mirado las hoja que venia con el lcd y si es compatible con el hitachi hd44780, lo unico que he conseguido con otro programa es que se ilumine la fila superior con cuadrados (cuando supuestamente deberian aparecer letras :D). Con el 16f84 no he probado a compilarlo, luego hare una pruebecita a ver k pasa, y el lcd que tengo es uno de 2x16 ¿sera por eso que no me compila? ya que si dices que funciona mejor con el de 2x20...
voy a seguir investigando un poco a ver si consigo ver cualquier caracter

gracias por las pistillas

Desconectado polo1984

  • PIC10
  • *
  • Mensajes: 13
Re: periféricos_LCD
« Respuesta #10 en: 27 de Febrero de 2007, 08:13:44 »
yo de nuevo

ya he conseguido compilar sin que me de problemas, pero me aparecen los cuadraditos en la fila superior. pero no he usado la libreria que poniais arriba, aqui os dejo el enlace de la que he usado

http://picmania.garcia-cuervo.com/PICC.htm#FLEXLCD

otra cosa que se me habia olvidado comentar, el programa que uso es el que habeis escrito arriba ya que aguno le funciona por lo que comentan. Estoy usando un cristal de 20 Mhz, he probado con los retardos que aparecian en la libreria y salian cuadrados de nuevo, asi que he vuelto a probar pero esta vez multiplicando por 5 los tiempos que ponian en las instrucciones delay_ms() y me salian igualmente cuadrados en la primera fila.

revisare las conexiones y demas problemillas que puedan aparecer y a ver si saco algo en claro jeje

saludos

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
Re: periféricos_LCD
« Respuesta #11 en: 27 de Febrero de 2007, 08:43:38 »
Es raro que no te funcionen los ejepmlitos básicos con lcd, aunque sea compatible. Como comentas, mirate bien las conexiones y el ajuste de la lcd (el potenciómetro ese famoso).

Incluso pudes probar con usar un cristal de 4MHz, a ver si anda de esa forma.



Suerte!!! ;)
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado polo1984

  • PIC10
  • *
  • Mensajes: 13
Re: periféricos_LCD
« Respuesta #12 en: 28 de Febrero de 2007, 07:48:08 »
buenasssss

ya he conseguido visualizar mi lcd, pero al final lo he hecho con la libreria que incorpora el compilador ccs. por lo que se ve tenia un problema de conexiones, ya que he apretado un poco con la mano el lcd y despues de un reseteo he conseguido visualizarlo. ¿por cierto que tipo de conectores usais para los lcd y evitar los falsos contactos? o simplemente ¿usais cables soldados que salgan de la placa?

un saludo y gracias por todo

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
Re: periféricos_LCD
« Respuesta #13 en: 28 de Febrero de 2007, 09:08:31 »
Yo en la proto uso cables.


Suerte!!! ;)
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado perry

  • PIC10
  • *
  • Mensajes: 12
Re: periféricos_LCD
« Respuesta #14 en: 28 de Febrero de 2007, 09:33:31 »
Hola!!

Estoy probando tu ejemplo con el ICD2pero no consigo visualizar nada. Estoy usando la libreria de ccs y uso el puerto d para las conexiones. Lo máximo que veo es un intento de encederse los pixeles pero nada más. ¿sabeis qué es lo que estoy haciendo mal? las conexiones las tengo bien, así que no sé. ¿puede ser por la frecuencia de trabajo? Estoy usando 20Mhz. Con el osciloscopio he visto que las lineas E y R/W están siempre a 0 y RS siempre a 1.

gracias


 

anything