Haz una pregunta
  Foros de Electrónica » Temas de Interés » Dudas en general
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

29/09/2016 #1


Ayuda con librería felxlcd para Pic C Compiler
Hola Buen día, tengo un problema con la librería Flexlcd para manejar una lcd de 20X4, a las primeras 2 lineas todo normal como una 16x2 pero al poner las coordenadas de las lineas 3 y 4 lo que hace es sobre escribir la segunda linea con las demás quisiera saber como modificar esta librería o si existe una que me facilite las cosas

Adjunto código de la librería que he utilizado

Código:
// flex_lcd.c 

 // These pins are for the Microchip PicDem2-Plus board, 
 // which is what I used to test the driver.  Change these 
 // pins to fit your own board. 

 #define LCD_DB4   PIN_B0 
 #define LCD_DB5   PIN_B1 
 #define LCD_DB6   PIN_B2 
 #define LCD_DB7   PIN_B3 

 #define LCD_E     PIN_B5 
 #define LCD_RS    PIN_B4 
 //#define LCD_RW    PIN_A2 

 // 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[i]); 
     
     // 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
29/09/2016 #2

Avatar de TRILO-BYTE

yo no he usado esa libreria pero yo escribi mi propia libreria.

por lo que te puedo decir que las coordenadas en X es un comando propio de la LCD
el comando Y tambien pero este solo desplaza 1.

deberias checar la data sheet de dicha LCD

y agregar en Y si Y==1 comando fulano, si Y==2 comando sutano.

me imagino que es un comando propio para dicha LCD que no esta disponible en la 16x2
29/09/2016 #3


mas o menos en que parte de la data puedo ver eso
29/09/2016 #4

Avatar de TRILO-BYTE

bueno me encuentro escribiendo nuevamente y explicare como se hace:

primero que nada necesitamos una tabla de comandos en este caso es la de 16x2 pues es la LCD que tengo y uso:



esta tabla de comandos dice que:

0X80 se encarga de poner el cursor en la linea 1 y que 0xC0 pone el cursor en la siguiente linea.

si nosotros queremos hacer una funcion X,Y necesitamos hacer solamente una suma para obtener 0XC0 que es el comando segunda linea.

ejemplo:

Código:
void lcdxy(char x,char y)
{
   char direccion;
   if(y!=1)
   {
      direccion=0x40;
   }
   else  {
            direccion=0;
         }
   direccion +=x-1;
   comando(0x80|direccion);
}
direccion es la que se va a usar para hubicar X y por que no Y tambien al mismo tiempo.
lo que hacemos es precargar a direccion con el comando indicado

supongamos que Y vale 1

if(y!=1)
{
direccion=0x40;
}
else {
direccion=0;
}
direccion +=x-1;
comando(0x80|direccion);

como Y es 1 es no se cumple el IF entonces se va al esle donde direccion vale 0
despues se precarga con el valor que tenga X se le resta una posicion

y el comando solamente se enmascara con una OR quedando 0X80 y su direccion en X
bien facilito

digamos que Y ahora vale 2

se cumple el IF y direccion se carga con 0x40
ahora direccion se le suma el valor que tenga X , se le resta una posicion

y despues se le hace una OR logica dando como resultado 0X80 + 0X40= 0XC0 mas su valor en X

lo que tienes que hacer es ahora buscar la tabla de comandos y modificar la funcion


void lcd_gotoxy(int8 x, int8 y)

animo si se puede
30/09/2016 #5


Tambien podrias probar la Flex_LCD420, yo personalmente no la he probado, pero algo lei en su dia. suerte
30/09/2016 #6


donde puedo conseguir esa librería??
30/09/2016 #7

Avatar de TRILO-BYTE

en lugar de agregarle las lineas de codigo faltantes
pero bueno
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Buscar más temas sobre:
Lupa Dudas en general

Aquí se tratan todos los temas relacionados con la electrónica en general.

Cerrar
Foros de Electrónica » Temas de Interés » Dudas en general

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.