Autor Tema: Display LCD con PIC16f877  (Leído 26020 veces)

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

Desconectado Murdco25

  • PIC10
  • *
  • Mensajes: 13
Display LCD con PIC16f877
« en: 28 de Mayo de 2009, 15:11:38 »
Este codigo de mi pic  lo trato de simular en proteus pero no muestra nada estoy mal? espero me ayuden gracias solo quiero escribir el mensaje Hola.

Código: C
  1. #include <16f877.h>
  2. #fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
  3. #use delay(clock=4000000)
  4.  
  5. #define LCD_DB4   PIN_B4
  6. #define LCD_DB5   PIN_B5
  7. #define LCD_DB6   PIN_B6
  8. #define LCD_DB7   PIN_B7
  9.  
  10. #define LCD_RS    PIN_C0
  11. #define LCD_RW    PIN_C1
  12. #define LCD_E     PIN_C2
  13.  
  14. #include "flex_lcd_2.c"
  15.  
  16.  
  17. void main()
  18. {
  19. lcd_init();
  20. do{
  21.   lcd_setcursor(1,0);
  22.   lcd_put_string_xy('x',1,1);
  23.  }while(TRUE);
  24. }

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Display LCD con PIC16f877
« Respuesta #1 en: 28 de Mayo de 2009, 15:18:29 »
Hola Murdco25! Bienvenido al foro. Muéstranos la librería para detectar el problema.
No contesto mensajes privados, las consultas en el foro

Desconectado Murdco25

  • PIC10
  • *
  • Mensajes: 13
Re: Display LCD con PIC16f877
« Respuesta #2 en: 28 de Mayo de 2009, 16:49:08 »
Hola gracia spor la respuesta tan rapida nuevamente agrego mi programa solo agregue  1 linea pero sigo con el y agrego la libreria gracias.

#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_RS    PIN_C0
#define LCD_RW    PIN_C1
#define LCD_E     PIN_C2

#include "flex_lcd_2.c"


void main()
{
lcd_init();
do{
  lcd_setcursor(1,0);
  LCD_PUTC("hola");
  lcd_put_string_xy('x',1,1);
 }while(TRUE);
}



Libreria que  Utilizo.


// flex_lcd_2.c

//#define LCD_DB4   PIN_B4
//#define LCD_DB5   PIN_B5
//#define LCD_DB6   PIN_B6
//#define LCD_DB7   PIN_B7
//
//#define LCD_RS    PIN_C0
//#define LCD_RW    PIN_C1
//#define LCD_E     PIN_C2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

// #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
   }
delay_ms(15);
}

//----------------------------
// Posiciones válidas:
// de x=1 a x=16 y
// de y=1 a y=2

void lcd_gotoxy(int8 x, int8 y){

   int8 address;

   if(x > 0 && y > 0){
      if(y > 1)
         address = lcd_line_two;
      else
         address=0;

      address += x-1;

      lcd_send_byte(0, 0x80 | address); // Manda cursor a la posición
   }
}

//-----------------------------
void lcd_putc(char c)
{


/*'   LCD
'   Command     Operation
'   *********** *****************************************
'   $FE, 1      Clear display
'   $FE, 2      Return home
'   $FE, $0C    Cursor off
'   $FE, $0E    Underline cursor on
'   $FE, $0F    Blinking cursor on
'   $FE, $10    Move cursor left one position
'   $FE, $14    Move cursor right one position
'   $FE, $80    Move cursor to beginning of first line
'   $FE, $C0    Move cursor to beginning of second line
'   *********** ***************************************** */

 if(c>'\0'){
   switch(c){

      case '\f':
        lcd_send_byte(0,1);
        lcd_send_byte(0,2);
        delay_ms(2);
        break;

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

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

      case '\t':
        lcd_send_byte(0,0x14);
        delay_ms(2);
        break;

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

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

void lcd_put_string(char *string){
   //put string, starting  from the curren cursor position
   //assume that string not excides from lcd displayed RAM
   char index=0;

   while(string[index]!=0){
      lcd_putc(string[index++]);
   }
}


//------------------------------
void lcd_put_string_xy(char *string, char x, char y){
   //assume that string not excides from lcd displayed RAM
   lcd_gotoxy(x,y);
   lcd_put_string(string);
}


//------------------------------
#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(short visible, short blink) {
  lcd_send_byte(0, 0xC|(visible<<1)|blink);
}

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Display LCD con PIC16f877
« Respuesta #3 en: 28 de Mayo de 2009, 20:53:21 »
Proba con la librería que adjunto que funciona correctamente.
No contesto mensajes privados, las consultas en el foro

Desconectado Murdco25

  • PIC10
  • *
  • Mensajes: 13
Re: Display LCD con PIC16f877
« Respuesta #4 en: 29 de Mayo de 2009, 00:43:55 »
Hola muchas gracias funciona correctamente te agradesco tu ayuda es epor poder hacerte otra sprenta smas adelante ya que soy nuevo en esto de los pics y esoy haciendo un proyecto de unos contadores  bye.

Desconectado Murdco25

  • PIC10
  • *
  • Mensajes: 13
Re: Display LCD con PIC16f877
« Respuesta #5 en: 29 de Mayo de 2009, 00:46:49 »
Hola se me paso les  coloco  el programa por si les sirve a alguien solo borre 1 linea pero funciona bien despliegamuchas veces la palabra Hola.

#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_RS    PIN_C0
#define LCD_RW    PIN_C1
#define LCD_E     PIN_C2

#include "flex_lcd.c"


void main()
{
lcd_init();
do{
  lcd_setcursor(1,0);
  LCD_PUTC("hola");
 }while(TRUE);
}

Desconectado Murdco25

  • PIC10
  • *
  • Mensajes: 13
Re: Display LCD con PIC16f877
« Respuesta #6 en: 03 de Junio de 2009, 23:06:22 »
Hola gracia spro la respeusta mira coloco mi programa en el cual   no funcina cada ves que  coloco la interrupcion global "" enable_interrupts(global); " deja de funionar mi programa  ya no me muestar pero si la quito la muestra y cuando lo quiero conectar con otro pic no funciona o puedes orientarme paar  conectar 2 pics. gracias


Código: C
  1. #include <16f877.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
  5. #use delay(clock=4000000)
  6. #use standard_io(b)
  7. #use standard_io(d)
  8. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  9.  
  10.  
  11. #include "flex_lcd.c"
  12.  
  13. char Keypress=' ';
  14. char Serie[10];
  15. char Serie2;
  16. char temp[3];
  17. int i=0;
  18. int y = 0;
  19.  
  20.  
  21. #int_rda
  22. void serial_isr() {
  23.  
  24.   Keypress=0x00;
  25.  if(kbhit()){//Devuelve verdadero si hay un dato en RS232
  26. y = 1;
  27.  
  28.     Keypress=getc(); //El dato recivido lo coloca en keypress
  29.     if (Keypress !='\x0a')
  30.     {
  31.         sprintf(temp,"%c",Keypress);//copia keypress a temp
  32.         strcat(Serie,temp);//Coloca temp al final de serie
  33.     }
  34.     else
  35.        i = 1;//nos indica que ha recivido una cadena de caracteres completa
  36.   }
  37.  
  38.   }
  39.  
  40.  
  41. void main()
  42. {
  43.  
  44.  
  45. enable_interrupts(global);
  46. enable_interrupts(int_rda);
  47. strcpy(Serie2,"CLAVE_X");
  48.  
  49. lcd_init();
  50. do{
  51.  
  52. if ( y == 1 )
  53. lcd_putc("SI");
  54. else
  55. lcd_putc("NO");
  56.  
  57.              if ( i == 1 )
  58.              {
  59.                lcd_putc(Serie);
  60.                strcpy(Serie,"");//limpia
  61.                strcpy(temp,"");//limpia
  62.                i=0; //reinicia
  63.              }
  64.  
  65.    } while (TRUE);
  66.  
  67. }

Desconectado fidodido18

  • PIC18
  • ****
  • Mensajes: 312
Re: Display LCD con PIC16f877
« Respuesta #7 en: 06 de Junio de 2009, 23:59:47 »
Hola gracia spro la respeusta mira coloco mi programa en el cual   no funcina cada ves que  coloco la interrupcion global "" enable_interrupts(global); " deja de funionar mi programa  ya no me muestar pero si la quito la muestra y cuando lo quiero conectar con otro pic no funciona o puedes orientarme paar  conectar 2 pics. gracias


Código: C
  1. #include <16f877.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
  5. #use delay(clock=4000000)
  6. #use standard_io(b)
  7. #use standard_io(d)
  8. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  9.  
  10.  
  11. #include "flex_lcd.c"
  12.  
  13. char Keypress=' ';
  14. char Serie[10];
  15. char Serie2;
  16. char temp[3];
  17. int i=0;
  18. int y = 0;
  19.  
  20.  
  21. #int_rda
  22. void serial_isr() {
  23.  
  24.   Keypress=0x00;
  25.  if(kbhit()){//Devuelve verdadero si hay un dato en RS232
  26. y = 1;
  27.  
  28.     Keypress=getc(); //El dato recivido lo coloca en keypress
  29.     if (Keypress !='\x0a')
  30.     {
  31.         sprintf(temp,"%c",Keypress);//copia keypress a temp
  32.         strcat(Serie,temp);//Coloca temp al final de serie
  33.     }
  34.     else
  35.        i = 1;//nos indica que ha recivido una cadena de caracteres completa
  36.   }
  37.  
  38.   }
  39.  
  40.  
  41. void main()
  42. {
  43.  
  44.  
  45. enable_interrupts(global);
  46. enable_interrupts(int_rda);
  47. strcpy(Serie2,"CLAVE_X");
  48.  
  49. lcd_init();
  50. do{
  51.  
  52. if ( y == 1 )
  53. lcd_putc("SI");
  54. else
  55. lcd_putc("NO");
  56.  
  57.              if ( i == 1 )
  58.              {
  59.                lcd_putc(Serie);
  60.                strcpy(Serie,"");//limpia
  61.                strcpy(temp,"");//limpia
  62.                i=0; //reinicia
  63.              }
  64.  
  65.    } while (TRUE);
  66.  
  67. }

hola, no estoy seguro ahora mismo pero enable_interrups(global); se coloca despues de enable_interrupts(int_rda); prueba y me dices.

Desconectado Vash

  • PIC10
  • *
  • Mensajes: 9
Re: Display LCD con PIC16f877
« Respuesta #8 en: 20 de Junio de 2009, 01:29:38 »
Antes que nada hola a todos los del foro.

Ahora si mi problema.

Acabo de hacer un termometro usando el pic 16f877A, un lm35 y un lcd JHD-162A y el problema al que me enfrento es que el lcd no imprime nada la simulacion me funciona de maravilla pero ya en el proto nada de nada, ya estuve buscando por todos lados y no, ya revise el codigo y las coneccion de los pines y al parecer todo esta bien, asi que es por ello que les pido ayuda para que alguien que ya haya esto fisicamente me oriente ya que simulado trabaja de maravilla, pero ya armado no muestra nada, a continuacion, el codigo, la simulacion y la foto de mi proto.

Código: [Seleccionar]
//Device/Fuses/Etc.-----------------------------
#include <16F877A.h>
#device adc=10
#include <math.h>
#fuses nowdt //No Watch Dog Timer
#fuses xt
#fuses noput //No Power Up Timer
#fuses noprotect //Code not protected from reading
#fuses nobrownout //No brownout reset
#fuses nolvp //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#fuses nocpd //No EE protection
#use delay(clock=4000000)
#include "lcd.c"
#use standard_io (D)

VOID MAIN(VOID){
   float TEMPE,VALUE;

   lcd_init();
   lcd_gotoxy(3,1);
   lcd_putc("Bienvenido");
   delay_ms(1000);
   lcd_putc("\f");
   
   lcd_gotoxy(1,1);
   lcd_putc("Termometro\nDigital");
   delay_ms(1000);
   lcd_putc("\f");
   
   lcd_gotoxy(1,1);
   lcd_putc("Temperatura");
   delay_us(1500);
   
   setup_port_a( ALL_ANALOG );
   while(true){
      setup_adc(ADC_CLOCK_DIV_32);
      set_adc_channel(0);//se elige el RA0
      delay_us(20);
      VALUE = read_adc();
      setup_adc( ADC_OFF );
      TEMPE=(VALUE*(0.48875));
      lcd_gotoxy(1,2);
      printf(lcd_putc,"Actual: %02.1F  C",TEMPE); //XXX.X C
      delay_us(100);
   }
}





el pic y el lcd, no son el problema, ya los probe con un contador que hic en ensamblador y funcionan.

Nos vemos y espero su ayuda

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Display LCD con PIC16f877
« Respuesta #9 en: 20 de Junio de 2009, 02:21:18 »
Prueba cambiando a la librería flex_lcd, unos mensajes mas arriba esta adjuntada. Y también debes agregar un potenciometro para controlar el contraste, que no lo estoy viendo.
No contesto mensajes privados, las consultas en el foro

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Display LCD con PIC16f877
« Respuesta #10 en: 20 de Junio de 2009, 16:41:26 »
cual es la diferencia en usar la libreria flex y la que trae el ccs?...en la libreria flex puedo cambiar los pines de control y los del bus de datos?...es decir cambiar estas lineas

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_RS     PIN_C0
#define LCD_RW    PIN_C1
#define LCD_E       PIN_C2
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Display LCD con PIC16f877
« Respuesta #11 en: 20 de Junio de 2009, 16:57:24 »
Es mas "maleable" ya que se pueden elegir los pines a gusto, de distintos puertos, que en la de CCS no.
No contesto mensajes privados, las consultas en el foro

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Display LCD con PIC16f877
« Respuesta #12 en: 20 de Junio de 2009, 17:05:14 »
pero es q cuando uno hace el proyecto a traves del pic wizard hay una pestaña "lcd" donde se pueden configurar los pines de control y hay q especificar la direccion del puerto a usar
« Última modificación: 20 de Junio de 2009, 17:09:33 por jhozate »
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Display LCD con PIC16f877
« Respuesta #13 en: 20 de Junio de 2009, 18:28:45 »
pero es q cuando uno hace el proyecto a traves del pic wizard hay una pestaña "lcd" donde se pueden configurar los pines de control y hay q especificar la direccion del puerto a usar
:? Mirando la librería de CCS se ve que eso no es posible. Utiliza un puerto para los bits de control y data.
No contesto mensajes privados, las consultas en el foro

Desconectado jhozate

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
Re: Display LCD con PIC16f877
« Respuesta #14 en: 20 de Junio de 2009, 19:25:28 »
mira la imagen q adjunto, esas opciones no son para configurar el lcd con la libreria de ccs? hay se puede escoger el puerto a utilizar y los bit de control
Ser Colombiano es un Premio, Saludos desde CALI-COLOMBIA