TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: mrgse en 11 de Mayo de 2009, 12:49:28

Título: LCD BASICO
Publicado por: mrgse en 11 de Mayo de 2009, 12:49:28
(Nose porque el anterior no se ha publicado)
Estoy buscando por el foro un programa de LCD pero todos los k veo son demasiado complejos. Yo simplemente quiero que se vea en mi LCD un : "HOLA"
Uso un PIC16F877, conectado al LCD por el puerto B.
El programa que tengo escrito es este, pero no se como simularlo y poder ver si funciona. A ver si podeis recomendarme algun simulador o almenos decir si es correcto.

#include "16F877.h"
#use delay(clock=4000000)
#include "lcd.c"
#define use_portb_lcd TRUE

void main(void)
   {
    set_tris_b(0x00);
    lcd_init();
    lcd_putc("HOLA";
    }

A parte, que diferencia hay entre:
lcd_putc("HOLA");
i
printf(lcd_putc,"HOLA",);


Gracias
Título: Re: LCD BASICO
Publicado por: Suky en 11 de Mayo de 2009, 13:10:59
Un buen programa para simular seria el Proteus, aquí en este mismo foro hay bastante información para que comiences con el.

La diferencia entre putc y printf radica en que este ultimo puedes enviarles al lcd variables convertidas a string:
printf:
Te permite especificar el formato en que queremos mostrar los datos.

Parámetros: Cadena de formato (cómo se visualizan los datos) y Lista de valores (datos que se visualizan)
Formatos:
%d Entero con signo.
%u Entero sin signo.
%x Hexadecimal minúscula.
%X Hexadecimal mayúscula.
%f Flotante

Ejemplo:
Código: C
  1. printf(lcd_putc,“Hola”);

Hola

Código: C
  1. Data=10;
  2. printf(lcd_putc,“El valor es : %u”,Data);

El valor es : 10

Código: C
  1. Data=10;
  2. printf(lcd_putc,“El valor es : %03u”,Data);

El valor es : 010

Código: C
  1. Data=3.12;
  2. printf(lcd_putc,“El valor es : %1.2f,Data);

El valor es : 3.12

Título: Re: LCD BASICO
Publicado por: migsantiago en 11 de Mayo de 2009, 13:11:58
Hola

Te puedes ahorrar la parte de la configuración del trisb, ya se hace en la librería. Ese programa no te va a funcionar porque lcd_putc solo envía caracter por caracter, para enviar cadenas debes usar printf, esa es la diferencia.

Código: [Seleccionar]
#include "16F877.h"
#use delay(clock=4000000)
#include "lcd.c"
#define use_portb_lcd TRUE

void main(void)
   {
    delay_ms(1000);
    lcd_init();
    printf(lcd_putc,"HOLA");
    }

jeje Suky me ganó la respuesta  :P
Título: Re: LCD BASICO
Publicado por: Suky en 11 de Mayo de 2009, 13:15:33
Ese programa no te va a funcionar porque lcd_putc solo envía caracter por caracter, para enviar cadenas debes usar printf, esa es la diferencia.

Migsantiago, lcd_putc no envia caracter por caracter. Y un lcd_putc("Hola"); funciona bien (En la libreria flex_lcd  :mrgreen:).
Título: Re: LCD BASICO
Publicado por: migsantiago en 11 de Mayo de 2009, 13:19:54
Ah bueno, modificando librerías todo se puede  :D

En la nueva lcd.c original de CCS 4.088 quién sabe si se pueda.  :?: :?: :?:
Título: Re: LCD BASICO
Publicado por: mrgse en 11 de Mayo de 2009, 13:51:35
Muchas gracias por las respuestas!!!!!!!
Título: Re: LCD BASICO
Publicado por: MGLSOFT en 11 de Mayo de 2009, 15:02:41
Lcd_putc() deberia funcionar bien.
Lo que debes tener en cuenta es siempre borrar el display antes de enviar el primer mensaje (la vieja libreria hace un borrado del display al final de Lcd_init() ).
Esto debe ser costumbre para adaptarlo a todas las marcas, ya que algunos al hacer el reset lo hacen y otros no... :mrgreen:
Título: Re: LCD BASICO
Publicado por: alexysar en 11 de Mayo de 2009, 19:12:21
Lo que debes tener en cuenta es siempre borrar el display antes de enviar el primer mensaje...

Es fundamental lo que dice mi colega, sino el display se cuelga. Si te fijas la hoja de datos de los display en la maquina de estado de inicialización,  generalmente no figura , pero te aseguro que sino borras no funciona porque hice la programación de una rutina de inicialización a pulmón. Y no por masoquista, sino porque era para un micro cypress y no te lo dan resuelto como en los pics.

Si te interesa te dejo las funciones que hice, pero son para cypress, pero supongo que la idea puede servier:

Funciones para Display Gráfico (http://www.kiteducativo.com.ar/foro/index.php?topic=7.0)
Título: Re: LCD BASICO
Publicado por: mrgse en 12 de Mayo de 2009, 07:13:48
Hola, con este programa:
#include "16F877.h"
#use delay(clock=4000000)
#include "lcd.c"
#define use_portb_lcd TRUE

void main(void)
   {
    delay_ms(1000);
    lcd_init();
    printf(lcd_putc,"HOLA");
    }

al darle tension al circuito, la primera linea del LCD marca todos los cuadros de negro, y la segunda no hace nada. No entiendo ... :S
que hago mal??

Uso el pic 16f877, tengo conectado:  los dos Vdd a 5 V 
los dos Vss a 0 V
Entre Vdd i Vss cond de 100nF
Entre OSC1 i OSC2 un cristal de 4Mhz, a la vez con dos cond de 15pF que van a tierra.
RB7 del PIC a DB7 del LCD
RB6 del PIC a DB6 del LCD
RB5 del PIC a DB5 del LCD
RB4 del PIC a DB4 del LCD
RB2 del PIC a R/W del LCD
RB1 del PIC a RS del LCD
RB0 del PIC a E del LCD

El LCD lo alimento correctamente y con buen contraste ya que en la primera linea veo todos los cuadros en negro.
Título: Re: LCD BASICO
Publicado por: mrgse en 12 de Mayo de 2009, 07:30:46
Acabo de desconectar el PIC del circuito, i le doy tension al LCD tan solo, y la primera linea sigue poniendose oscura, (los cuadros). Nose si servira de ayuda esta informacion
EL PIC funciona correctamente pork he realizado un programa que encienda y apague un LED y lo he probado practicamente y funciona.
Título: Re: LCD BASICO
Publicado por: MGLSOFT en 12 de Mayo de 2009, 08:05:33
Podras pegar aqui una copia de la libreria lcd.c que estas utilizando??
Es para saber que pines vienen configurados alli... :lol:
Título: Re: LCD BASICO
Publicado por: MGLSOFT en 12 de Mayo de 2009, 08:08:04
UPPSS!!
Prueba a cambiar el orden de tus intrucciones asi:

Citar
#define use_portb_lcd TRUE
#include "lcd.c"

Puede ser por alli que no funciona...
Título: Re: LCD BASICO
Publicado por: mrgse en 12 de Mayo de 2009, 08:08:53
Código: [Seleccionar]
///////////////////////////////////////////////////////////////////////////
////                             LCDD.C                                ////
////                 Driver for common LCD modules                     ////
////                                                                   ////
////  lcd_init()   Must be called before any other function.           ////
////                                                                   ////
////  lcd_putc(c)  Will display c on the next position of the LCD.     ////
////                     The following have special meaning:           ////
////                      \f  Clear display                            ////
////                      \n  Go to start of second line               ////
////                      \b  Move back one position                   ////
////                                                                   ////
////  lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)    ////
////                                                                   ////
////  lcd_getc(x,y)   Returns character at position x,y on LCD         ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
//     D0  enable
//     D1  rs
//     D2  rw
//     D4  D4
//     D5  D5
//     D6  D6
//     D7  D7
//
//   LCD pins D0-D3 are not used and PIC D3 is not used.

// Un-comment the following define to use port B
//#define use_portb_lcd TRUE


struct lcd_pin_map {                 // This structure is overlayed
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rs;               // access to the LCD pins.
           BOOLEAN rw;               // The bits are allocated from
           BOOLEAN unused;           // low order up.  ENABLE will
           int     data : 4;         // be pin B0.
        } lcd;


#if defined use_portb_lcd
   #locate lcd = getenv("sfr:PORTB")    // This puts the entire structure over the port
   #define set_tris_lcd(x) set_tris_b(x)
#else
   #locate lcd = getenv("sfr:PORTD")    // This puts the entire structure over the port
   #define set_tris_lcd(x) set_tris_d(x)
#endif


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


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.


                             // The following are used for setting
                             // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in



BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(5);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING[i]);
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE 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;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}
Título: Re: LCD BASICO
Publicado por: Suky en 12 de Mayo de 2009, 09:37:19
UPPSS!!
Prueba a cambiar el orden de tus intrucciones asi:

Citar
#define use_portb_lcd TRUE
#include "lcd.c"

Puede ser por alli que no funciona...

Deberías hacer lo que te propone MGLSOFT o directamente habilitarlo en la librería, fíjate que tiene la opción.

Citar
// Un-comment the following define to use port B
//#define use_portb_lcd TRUE
Título: Re: LCD BASICO
Publicado por: mrgse en 12 de Mayo de 2009, 10:16:51
He quitado las // de la libreria, pero sigue pasando lo mismo.
Título: Re: LCD BASICO
Publicado por: migsantiago en 12 de Mayo de 2009, 15:33:09
Perdona, cometí dos omisiones en tu programa.

La primera ya te la comentaron, debes declarar primero el puerto y después invocar el lcd.c.

Y la segunda es que falta por completo la declaración de los fusibles del pic  :D Disculpa por no fijarme, usa estos...

Código: [Seleccionar]
#include "16F877.h"
#use delay(clock=4000000)
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#define use_portb_lcd TRUE
#include "lcd.c"

El pic ni siquiera estaba funcionando porque no estaba declarada la forma en que entraba el oscilador  :mrgreen:
Título: Re: LCD BASICO
Publicado por: Suky en 13 de Mayo de 2009, 00:18:57
Perdona, cometí dos omisiones en tu programa.

La primera ya te la comentaron, debes declarar primero el puerto y después invocar el lcd.c.

Y la segunda es que falta por completo la declaración de los fusibles del pic  :D Disculpa por no fijarme, usa estos...

Código: [Seleccionar]
#include "16F877.h"
#use delay(clock=4000000)
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#define use_portb_lcd TRUE
#include "lcd.c"

El pic ni siquiera estaba funcionando porque no estaba declarada la forma en que entraba el oscilador  :mrgreen:

(http://img254.imageshack.us/img254/7936/auch.gif) Yo tampoco me dí cuenta!
Título: Re: LCD BASICO
Publicado por: mrgse en 13 de Mayo de 2009, 05:28:01
Con el siguiente programa:
Código: [Seleccionar]
#include "16F877.h"
#use delay(clock=4000000)
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#define use_portb_lcd TRUE
#include "lcd.c"

void main(void)
   {

    delay_ms(1000);
    lcd_init();
    printf(lcd_putc,"HOLA");
    }
Sigue pasandome lo mismo. Todas las connexiones del LCD estan a 5V exceptuando la de GND i la de control de contraste. Incluso si desconecto las entradas de datos! Necesito ayuda urgente!! GRACIAS!!
Título: Re: LCD BASICO
Publicado por: mrgse en 13 de Mayo de 2009, 06:01:55
Hola acabo de ver que en mi libreria lcd.c en los comentarios pone lcdd.c, i dice que los pines van al puerto D, puede ser eso?¿ Alguien me puede pasar una libreria de lcd que trabaje con el puerto B i con los pines que he escrito en post anteriores?
Incluso si podeis pasarme un programa muy senzillo que tan solo ponga Hola en el LCD. Eso si, incluir la libreria, porque me temo que es allio donde esta el error. Gracias!
Título: Re: LCD BASICO
Publicado por: mrgse en 13 de Mayo de 2009, 07:41:03
FINALMENTE: FUNCIONO! Nose porque porque he usado el mismo programa que he puesto anteriormente...pero funciono!
Título: Re: LCD BASICO
Publicado por: juansi en 13 de Mayo de 2009, 08:24:58
mrgse si usaste una protoboard probablemente hubo una mala conexion de un pin del pic o del lcd,
si funciona en proteus funciona en la realidad.

Título: Re: LCD BASICO
Publicado por: migsantiago en 13 de Mayo de 2009, 13:26:17
Vaya qué bien  :D

Otro cliente Todopic satisfecho.  8)
Título: Re: LCD BASICO
Publicado por: mrgse en 15 de Mayo de 2009, 04:51:35
Por cierto, siempre se conectan las paas de la D4 a la D7 del LCD, pero se podria conectar de la D0 a la D3?? Como??
Título: Re: LCD BASICO
Publicado por: MGLSOFT en 15 de Mayo de 2009, 10:20:53
No, en modo a 4 bits solo se usan desde D4 a D7, D0 a D7 es para modo a 8 bits...
Título: Re: LCD BASICO
Publicado por: pajaro en 17 de Mayo de 2009, 08:33:43
hola amigos

MGLSOFT el amigo mrgse, se refiere que si es posible enviar datos en vez de D4 a d7 la parte alta del puesto B, hacerlo con laparte baja usando D0 a D3, y si es asi como se hace.

Creo que bastaria con cambiar los pines de nombre en la parte de la definicioón, o si tiene una función en la cual le pasas los pines se los cambias ahi, vosotrosque opinais.

Un saludo
Título: Re: LCD BASICO
Publicado por: alexysar en 17 de Mayo de 2009, 10:11:48
Si miras del lado del Pic podes usar los pines que quieras, D0~D3 ó D4~D7, o inclusive pines de éste u otros puertos mezclados.
Si te fijas del lado del LCD, para entrar en modo 4 bits,  tenes que usars si o si los pines D4~D7, no hay otra alternativa.
Título: Re: LCD BASICO
Publicado por: mrgse en 17 de Mayo de 2009, 15:23:53
Era por parte del LCD, pero si no se puede nada, a usar D4 a D7.