Autor Tema: LCD con PIC16f877 4bits  (Leído 2565 veces)

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

Desconectado pablofer78

  • PIC10
  • *
  • Mensajes: 20
LCD con PIC16f877 4bits
« en: 12 de Enero de 2009, 16:13:09 »
Hola a todos.
queria preguntar si se puede hacer funcionar un display LCD de 2x16 mandando los datos por un puerto y el control por otro.
Por ejemplo

//     C3  enable
//     C2  rs
//     B4  D4
//     B5  D5
//     B6  D6
//     B7  D7

Sin RW

Trate de modificar el driver q trae el CCs para usar un display con 4bits pero no pude hacer q el LCD me responda.
Desde ya muchas gracias y espero su ayuda.

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: LCD con PIC16f877 4bits
« Respuesta #1 en: 12 de Enero de 2009, 19:42:48 »
si se puede, derepente has modificado erroneamente una parte del código y por eso no funciona. revisa denuevo el código. saludos  :-/
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: LCD con PIC16f877 4bits
« Respuesta #2 en: 12 de Enero de 2009, 19:48:53 »

Hola pana 

Porque no usa la Flex_LCD???


Saludos!

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: LCD con PIC16f877 4bits
« Respuesta #3 en: 13 de Enero de 2009, 00:55:22 »
Como dice AKENAFAB usa flex_lcd, es de 4 bits y se puede modificar facilmente.

Código: C
  1. // flex_lcd.c
  2.  
  3. // Change these pins to fit your own board.
  4. #define LCD_DB4 PIN_D4
  5. #define LCD_DB5 PIN_D5
  6. #define LCD_DB6 PIN_D6
  7. #define LCD_DB7 PIN_D7
  8.  
  9. #define LCD_RS PIN_D0
  10. #define LCD_RW PIN_D1
  11. #define LCD_E  PIN_D2
  12.  
  13. // If you only want a 6-pin interface to your LCD, then
  14. // connect the R/W pin on the LCD to ground, and comment
  15. // out the following line.
  16.  
  17. #define USE_LCD_RW 1
  18.  
  19. //========================================
  20.  
  21. #define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
  22. #define lcd_line_two 0x40 // LCD RAM address for the 2nd line
  23.  
  24. int8 const LCD_INIT_STRING[4] =
  25. {
  26.   0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
  27.   0xc, // Display on
  28.   1, // Clear display
  29.   6 // Increment cursor
  30. };
  31.  
  32.  
  33. //-------------------------------------
  34. void lcd_send_nibble(int8 nibble)
  35. {
  36.   // Note: !! converts an integer expression
  37.   // to a boolean (1 or 0).
  38.   output_bit(LCD_DB4, !!(nibble & 1));
  39.   output_bit(LCD_DB5, !!(nibble & 2));
  40.   output_bit(LCD_DB6, !!(nibble & 4));
  41.   output_bit(LCD_DB7, !!(nibble & 8));
  42.  
  43.   delay_cycles(1);
  44.   output_high(LCD_E);
  45.   delay_cycles(2);// 2us
  46.   output_low(LCD_E);
  47. }
  48.  
  49. //-----------------------------------
  50. // This sub-routine is only called by lcd_read_byte().
  51. // It's not a stand-alone routine. For example, the
  52. // R/W signal is set high by lcd_read_byte() before
  53. // this routine is called.
  54. #ifdef USE_LCD_RW
  55. int8 lcd_read_nibble(void)
  56. {
  57.   int8 retval;
  58.   // Create bit variables so that we can easily set
  59.   // individual bits in the retval variable.
  60.   #bit retval_0 = retval.0
  61.   #bit retval_1 = retval.1
  62.   #bit retval_2 = retval.2
  63.   #bit retval_3 = retval.3
  64.  
  65.   retval = 0;
  66.  
  67.   output_high(LCD_E);
  68.   delay_cycles(1);
  69.  
  70.   retval_0 = input(LCD_DB4);
  71.   retval_1 = input(LCD_DB5);
  72.   retval_2 = input(LCD_DB6);
  73.   retval_3 = input(LCD_DB7);
  74.  
  75.   output_low(LCD_E);
  76.  
  77.   return(retval);
  78. }
  79. #endif
  80.  
  81. //---------------------------------------
  82. // Read a byte from the LCD and return it.
  83. #ifdef USE_LCD_RW
  84. int8 lcd_read_byte(void)
  85. {
  86.   int8 low;
  87.   int8 high;
  88.  
  89.   output_high(LCD_RW);
  90.   delay_cycles(1);
  91.  
  92.   high = lcd_read_nibble();
  93.  
  94.   low = lcd_read_nibble();
  95.  
  96.   return( (high<<4) | low);
  97. }
  98. #endif
  99.  
  100. //----------------------------------------
  101. // Send a byte to the LCD.
  102. void lcd_send_byte(int8 address, int8 n)
  103. {
  104.   output_low(LCD_RS);
  105.  
  106. #ifdef USE_LCD_RW
  107. while(bit_test(lcd_read_byte(),7)) ;
  108. #else
  109. delay_us(60);
  110. #endif
  111.  
  112.   if(address)
  113.   output_high(LCD_RS);
  114.   else
  115.   output_low(LCD_RS);
  116.  
  117.   delay_cycles(1);
  118.  
  119. #ifdef USE_LCD_RW
  120. output_low(LCD_RW);
  121. delay_cycles(1);
  122. #endif
  123.  
  124.   output_low(LCD_E);
  125.  
  126.   lcd_send_nibble(n >> 4);
  127.   lcd_send_nibble(n & 0xf);
  128. }
  129.  
  130. //----------------------------
  131. void lcd_init(void)
  132. {
  133.   int8 i;
  134.  
  135.   output_low(LCD_RS);
  136.  
  137. #ifdef USE_LCD_RW
  138. output_low(LCD_RW);
  139. #endif
  140.  
  141.   output_low(LCD_E);
  142.  
  143.   delay_ms(15);//15ms
  144.  
  145.   for(i=0 ;i < 3; i++)
  146.   {
  147.     lcd_send_nibble(0x03);
  148.     delay_ms(5);//5ms
  149.   }
  150.  
  151.   lcd_send_nibble(0x02);
  152.  
  153.   for(i=0; i < sizeof(LCD_INIT_STRING); i++)
  154.   {
  155.     lcd_send_byte(0, LCD_INIT_STRING[i]);
  156.  
  157.     // If the R/W signal is not used, then
  158.     // the busy bit can't be polled. One of
  159.     // the init commands takes longer than
  160.     // the hard-coded delay of 60 us, so in
  161.     // that case, lets just do a 5 ms delay
  162.     // after all four of them.
  163. #ifndef USE_LCD_RW
  164. delay_ms(5);
  165. #endif
  166. }
  167.  
  168. }
  169.  
  170. //----------------------------
  171. void lcd_gotoxy(int8 x, int8 y)
  172. {
  173.   int8 address;
  174.  
  175.   if(y != 1)
  176.   address = lcd_line_two;
  177.   else
  178.   address=0;
  179.  
  180.   address += x-1;
  181.   lcd_send_byte(0, 0x80 | address);
  182. }
  183.  
  184. //-----------------------------
  185. void lcd_putc(char c)
  186. {
  187.   switch(c)
  188.   {
  189.     case '\f':
  190.       lcd_send_byte(0,1);
  191.       delay_ms(2);//2ms
  192.       break;
  193.  
  194.     case '\n':
  195.       lcd_gotoxy(1,2);
  196.       break;
  197.  
  198.     case '\b':
  199.       lcd_send_byte(0,0x10);
  200.       break;
  201.  
  202.     default:
  203.       lcd_send_byte(1,c);
  204.       break;
  205.   }
  206. }
  207. void lcd_comand(int d)
  208. {
  209. lcd_send_byte(0,d);
  210. }
  211. #org 0x196B,0x1986
  212. void lcd_borrar(void){
  213.    lcd_send_byte(0,1);
  214.    delay_ms(2);//2ms
  215. }
  216.  
  217. //------------------------------
  218. #ifdef USE_LCD_RW
  219. char lcd_getc(int8 x, int8 y)
  220. {
  221.   char value;
  222.  
  223.   lcd_gotoxy(x,y);
  224.  
  225.   // Wait until busy flag is low.
  226.   while(bit_test(lcd_read_byte(),7));
  227.  
  228.   output_high(LCD_RS);
  229.   value = lcd_read_byte();
  230.   output_low(lcd_RS);
  231.  
  232.   return(value);
  233. }
  234. #endif
  235.  
  236. void lcd_setcursor_vb(short visible, short blink) {
  237.   lcd_send_byte(0, 0xC|(visible<<1)|blink);
  238. }
« Última modificación: 28 de Mayo de 2009, 20:45:25 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado pablofer78

  • PIC10
  • *
  • Mensajes: 20
Re: LCD con PIC16f877 4bits
« Respuesta #4 en: 13 de Enero de 2009, 10:01:03 »
mUCHAS GRACIAS POR LA AYUDA.
PERO TENGO OTRO PROBLEMA, AL COMPILAR ME DA UN ERROR EN LA LINEA 25 CON EL SIGUIENTE MENSAJE:
A #DEVICE REQUIRED BEFORE THIS LINE

PERO EL DISPOSITIVO ESTA DEFINIDO.
SI ALGUIEN SABE Q PUEDE SER, AGRADECERIA LA AYUDA, YA Q ESTOY BASTANTE TRABADO EN ESTO.

GRACIAS DE NUEVO

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: LCD con PIC16f877 4bits
« Respuesta #5 en: 13 de Enero de 2009, 16:02:47 »
Sube tu codigo pana!

Para ver que se colo o que falta!


Saludos!

Desconectado pablofer78

  • PIC10
  • *
  • Mensajes: 20
Re: LCD con PIC16f877 4bits
« Respuesta #6 en: 14 de Enero de 2009, 10:28:55 »
Este es el codigo......
si alguien me puede ayudar se lo agradecere mucho.  :? :? :? :?


// flex_lcd.c

// Change these pins to fit your own board.
#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_C2
#define LCD_RW PIN_C1
#define LCD_E  PIN_C3

// 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
};


//-------------------------------------
#org 0x1800, 0x1832
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_cycles(2);// 2us
  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.
#org 0x1833,0x1865
#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.
#org 0x1866,0x187C
#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.
#org 0x187D,0x18AE
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);
}

//----------------------------
#org 0x18AF,0x1912
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);//15ms

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

  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
}

}

//----------------------------
#org 0x1913,0x1926
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);
}

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

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

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

    default:
      lcd_send_byte(1,c);
      break;
  }
}
#org 0x195C,0x196A
void lcd_putd(int d)
{
lcd_send_byte(0,d);
}
#org 0x196B,0x1986
void lcd_borrar(void){
   lcd_send_byte(0,1);
   delay_ms(2);//2ms
}

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

Cuando compilo mi codigo, me dice q hay un error en algunas lineas de este .c, pero no puedo encontrar el problema.
saludos y gracias

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: LCD con PIC16f877 4bits
« Respuesta #7 en: 14 de Enero de 2009, 16:41:28 »
Esta libreria no me da problema al compilar.


La adjunto

Desconectado pablofer78

  • PIC10
  • *
  • Mensajes: 20
Re: LCD con PIC16f877 4bits
« Respuesta #8 en: 15 de Enero de 2009, 10:26:52 »
Muchisimas gracias use esa libreria y con el programa q hice y todo esta funcionando.
mil gracias de nuevo