Autor Tema: Ayuda libreria LCD para pic 16F84A  (Leído 7821 veces)

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

Desconectado aka222

  • PIC10
  • *
  • Mensajes: 3
Ayuda libreria LCD para pic 16F84A
« en: 04 de Mayo de 2006, 16:25:36 »
Hola, necesito ayuda porque no consigo configurar ninguna libreria para LCD 2x16 en modo 4 bits.
He probado con varias como con flex_lcd.c y no consigo configurarla para la siguiente configuracion hardware:
#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

Lo defino así, y con un programa de ejemplo lo pruebo, pero el LCD se pone negro.

Saludos y gracias.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #1 en: 05 de Mayo de 2006, 02:01:45 »
Si quieres pega la flex_lcd.c y te la pruebo.

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #2 en: 05 de Mayo de 2006, 06:55:48 »
¿has conectado bien la lcd? el potenciometro en el contraste.....


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

Desconectado aka222

  • PIC10
  • *
  • Mensajes: 3
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #3 en: 05 de Mayo de 2006, 10:39:25 »
Aqui os dejo la libreria por si veis algún fallo y el programa que escribe el mensaje.

Libreria:
// 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_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
   }

}

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

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

Programa:

#include <16f84a.h>

#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_A0
#define LCD_RW    PIN_A1
#define LCD_E     PIN_A2

#include "flex_lcd.c"

#use fast_io(A)
#use fast_io(B)

void main() {

  lcd_init();

  lcd_putc(".:. GRACIAS .:.");
  delay_ms(1000);

}

y graciasssss ....

PD: el potenciometro del contraste funciona bien.

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #4 en: 05 de Mayo de 2006, 11:59:21 »
Quita las instrucciones #use fast_ioo en el main declara los puertos como entradas o salidas con la instruccion set_tris_x donde x es la letra del puerto a definir(a, b, c,....)


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

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #5 en: 08 de Mayo de 2006, 09:16:58 »
Lo siento pero me dá error al compilar en la línea: lcd_send_byte(0, LCD_INIT_STRING);

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);


Aparece un careto en el programa que has pegado, yo le he puesto un 8 ahí. ¿A tí te compila bien?

Si no lo solucionas te pongo una librería de estas flexibles que sí funciona bien

Un saludo

Desconectado aka222

  • PIC10
  • *
  • Mensajes: 3
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #6 en: 10 de Mayo de 2006, 19:11:42 »
Gracias, pocher. El careto lo puso el solo 8) equivale a 8 ).

Si no te importa, ponme esa libreria que me comentas, a ver si así lo hago funcionar.

En asm funciona, pero por no cambiar el hardware, me interesa hacerlo funcionar en C, que es más rapido de programar.

Gracias otra vez y saludos.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #7 en: 12 de Mayo de 2006, 01:33:57 »
Ahí te va:

Código: C
  1. //include LCD para CCS
  2.  
  3. // La ventaja de este codigo es que puedes trabajar si lo quieres con pines
  4. // dispersos es decir no estas sujeto a la mitad de un puerto. Además no se usa el pin R/W,
  5. // se conecta a masa
  6.  
  7. // Registros de Puertos A & B
  8. #define PORTA 0x05 // Puerto A
  9. #define PORTB 0x06 // Registro de direccionamiento Puerto A
  10. #define TRISA 0x85 // Puerto B
  11. #define TRISB 0x86 // Registro de direccionamiento Puerto B
  12. #define PORTC 0x07 // Registro de direccionamiento Puerto C
  13. #define TRISC 0x87 // Puerto C
  14.  
  15. // Definición de Puertos Pantalla LCD 40x20 Hitachi 44780
  16.  
  17. /*
  18. #bit lcd_db4 = PORTC.0
  19. #bit tris_lcd_db4 = TRISC.0
  20. #bit lcd_db5 = PORTC.1
  21. #bit tris_lcd_db5 = TRISC.1
  22. #bit lcd_db6 = PORTC.2
  23. #bit tris_lcd_db6 = TRISC.2
  24. #bit lcd_db7 = PORTC.3
  25. #bit tris_lcd_db7 = TRISC.3
  26.  
  27. #bit lcd_en = PORTC.5
  28. #bit tris_lcd_en = TRISC.5
  29. #bit lcd_rs = PORTC.4
  30. #bit tris_lcd_rs = TRISC.4
  31. */
  32. /*
  33. #bit lcd_db4 = PORTB.0
  34. #bit tris_lcd_db4 = TRISB.0
  35. #bit lcd_db5 = PORTB.1
  36. #bit tris_lcd_db5 = TRISB.1
  37. #bit lcd_db6 = PORTC.0
  38. #bit tris_lcd_db6 = TRISC.0
  39. #bit lcd_db7 = PORTC.1
  40. #bit tris_lcd_db7 = TRISC.1
  41.  
  42. #bit lcd_en = PORTA.0
  43. #bit tris_lcd_en = TRISA.0
  44. #bit lcd_rs = PORTA.2
  45. #bit tris_lcd_rs = TRISA.2
  46.  
  47. */
  48.  
  49. #bit lcd_db4 = PORTB.0
  50. #bit tris_lcd_db4 = TRISB.0
  51. #bit lcd_db5 = PORTB.1
  52. #bit tris_lcd_db5 = TRISB.1
  53. #bit lcd_db6 = PORTB.2
  54. #bit tris_lcd_db6 = TRISB.2
  55. #bit lcd_db7 = PORTB.3
  56. #bit tris_lcd_db7 = TRISB.3
  57.  
  58. #bit lcd_en = PORTA.3
  59. #bit tris_lcd_en = TRISA.3
  60. #bit lcd_rs = PORTA.2
  61. #bit tris_lcd_rs = TRISA.2
  62.  
  63.  
  64. // lcd_init() Inicialización del LCD (debe utilizarse al principio,
  65. // antes de trabajar con el LCD).
  66. //
  67. // lcd_putc(c) Imprime un caracter en el LCD.
  68. //
  69. // lcd_gotoxy(x,y) Selecciona la nueva posicion de escritura en el LCD.
  70. // (la esquina superior izquierda es 1,1)
  71. //
  72. // lcd_getc(x,y) Devuelve el caracter de la posicion x,y del LCD.
  73. //
  74. // void lcd_erase_line(x) Borra una cantidad de caracter hacia la derecha
  75.  
  76. // Conexion a la pantalla LCD 40x4
  77. // RC0 <---> LCD DB4
  78. // RC1 <---> LCD DB5
  79. // RC2 <---> LCD DB6
  80. // RC3 <---> LCD DB7
  81. // RC5 <---> LCD ENABLE
  82. // RC4 <---> LCD RS
  83. //
  84.  
  85. #define LCD_DATO 1
  86. #define LCD_INST 0
  87.  
  88. #define LCD_LINEA1 0x80 // Direccion de memoria para la 1 linea
  89. #define LCD_LINEA2 0xc0 // Direccion de memoria para la 2 linea
  90. #define LCD_LINEA3 0x94 // Direccion de memoria para la 3 linea
  91. #define LCD_LINEA4 0xd4 // Direccion de memoria para la 4 linea
  92.  
  93.  
  94.  
  95. // 7 6 5 4 3 2 1 0
  96. // Function Set 0b 0 0 1 B L F 0 0
  97. // Bus size, B:0=4 bits, B:1=8 bits
  98. // Line Number, L:0=1 Line, L:1=2 Lines
  99. // Font size F:0=5x8, F:1=5x10
  100. #define LCD_FUNCTION_SET 0b00101000 // Bus=4bit, Line=2, Font=5x8
  101.  
  102. // 7 6 5 4 3 2 1 0
  103. // Display/Cursor 0b 0 0 0 0 1 D U B
  104. // Set Display on/off, D:0=off, D:1=on
  105. // Underline cursor, U:0=off, U:1=on
  106. // Blinking cursor, B:0=off, B:1=on
  107. #define LCD_DISPLAY_CURSOR 0b00001100 // Display=on, Scroll=off, Blinkin=off
  108.  
  109. // 7 6 5 4 3 2 1 0
  110. // Entry Mode 0b 0 0 0 0 0 1 M S
  111. // Cursor direction, M:0=left, 1=right
  112. // Display Scroll, S:0=no scroll, S:1=scroll
  113. #define LCD_ENTRY_MODE 0b00000110 // Increment cursor, no disp shift
  114.  
  115. void lcd_set_write() {
  116. tris_lcd_db4 = 0; //
  117. tris_lcd_db5 = 0; //
  118. tris_lcd_db6 = 0; //
  119. tris_lcd_db7 = 0; //---> Set portb RB0-RB3 mode output
  120. }
  121.  
  122.  
  123. void lcd_send_nibble(int8 n) {
  124. if (bit_test(n,0)) //
  125. lcd_db4 = 1; //
  126. else //
  127. lcd_db4 = 0; //
  128.  
  129. if (bit_test(n,1)) //
  130. lcd_db5 = 1; //
  131. else //
  132. lcd_db5 = 0; //
  133.  
  134. if (bit_test(n,2)) //
  135. lcd_db6 = 1; //
  136. else //
  137. lcd_db6 = 0; //
  138.  
  139. if (bit_test(n,3)) //
  140. lcd_db7 = 1; //
  141. else //
  142. lcd_db7 = 0; //---> Set data nibble
  143. delay_cycles(5); // nop
  144. lcd_en = 1; // Habilita LCD Eneable __
  145. delay_us(20); // Espera 2 uSeg. | |
  146. lcd_en = 0; // Desabilita LCD Eneable __| |__
  147. }
  148.  
  149. void lcd_send_byte (int1 select, int8 n) {
  150. lcd_rs = 0; // Modo de instruccion
  151. lcd_rs = select; // Escoje entre RS=0 : Instruccion & RS=1 : Data
  152. delay_cycles(5); // nop
  153. lcd_en = 0; // Desabilita LCD Eneable
  154. lcd_send_nibble(n >> 4); // Envia los datos superiores MSB
  155. lcd_send_nibble(n); // Envia los datos inferiores LSB
  156. }
  157.  
  158. void lcd_init() {
  159. int8 i, count=0;
  160. lcd_set_write(); // Prepara el puerto DB4-DB7 como salida
  161. tris_lcd_en = 0; //
  162. tris_lcd_rs = 0; //---> Set porta RA0, RA1 & RA2 mode output
  163. lcd_en = 0; //
  164. lcd_rs = 0; //---> Clear LCD_EN, LCD_RW & LCD_RS
  165. delay_ms(100);
  166. retry:
  167. for(i=1; i<=3; ++i) {
  168. lcd_send_nibble(0b0011); // 8 bit mode 3 times
  169. delay_ms(30);
  170. }
  171. lcd_send_nibble(0b0010); // 4 bit mode
  172. lcd_send_byte(LCD_INST, LCD_FUNCTION_SET); // Function Set
  173. lcd_send_byte(LCD_INST, LCD_DISPLAY_CURSOR); // Display Cursor
  174. lcd_send_byte(LCD_INST, LCD_ENTRY_MODE); // Entry Mode
  175. }
  176.  
  177. void lcd_gotoxy(int8 x, int8 y)
  178. {
  179. int8 const address[4]={LCD_LINEA1,LCD_LINEA2,LCD_LINEA3,LCD_LINEA4};
  180. int8 pos;
  181. pos=address[y-1]+(x-1);
  182. lcd_send_byte (LCD_INST, pos);
  183. }
  184.  
  185.  
  186. void lcd_putc(char c) {
  187. lcd_send_byte(LCD_DATO,c);
  188. }
  189.  
  190. void lcd_clear() {
  191. lcd_send_byte(LCD_INST,0x01);
  192. }
  193.  
  194. void lcd_home() {
  195. lcd_send_byte(LCD_INST,0x02);
  196. }
  197.  
  198. void lcd_erase_line(int8 x) {
  199. int8 i;
  200. for(i=1;i<=x;++i) {
  201. lcd_send_byte(LCD_DATO,32);
  202. }
  203. }

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #8 en: 02 de Abril de 2007, 08:38:15 »
Hola,

Tengo el mismo problema que Aka.

La configuración es la siguiente:

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

#define LCD_RS    PIN_A2
#define LCD_RW    PIN_A3
#define LCD_E     PIN_A4

#define LED PIN_A1                                 
#include <flex_lcd.c>

Y en el main lo único que hago es:

void main(void)
{
   port_b_pullups(FALSE);                          //pullups portb desactivadas
   setup_TIMER_0(RTCC_INTERNAL | RTCC_DIV_128);
   set_tris_a(0b00000000);                         //porta todo como salida
   set_tris_b(0b00000000);                         //portb todo como salida

   lcd_init();

   do
   {
      printf(lcd_putc,"hola mundo");
      delay_ms(2000);
      printf(lcd_putc,"soy Marc");
      delay_ms(2000);

   }while(TRUE);
}

Al alimentar el LCD se encienden todas las casillas de color negro. La primera fila más fuerte que la segunda. El contraste funciona bien, he usado un potenciómetro de 1K entre Gnd y 5V (que es a lo que alimento PIC y LCD).

Alguna idea de lo que puede pasar?

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #9 en: 02 de Abril de 2007, 11:36:56 »
He ejecutado el ejemplo de VsZener "Hola Mundo" con la librería lcd.c que trae el CCS y todo ha funcionado PERFECTO!!

Así pués las conexiones del lcd son correctas y éste funciona bien.

Cuál puede ser el fallo entonces? En teoría en la librería flex_lcd sólo hay que cambiar los pines a utilizar y listo, no?

Gracias!!

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #10 en: 03 de Abril de 2007, 11:36:27 »
SOLUCIONADO!!

Maldito PIN_A4 en colector abierto!! Fue ponerle con la pull-up y funcionar.

Un saludo!!

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3206
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #11 en: 16 de Febrero de 2008, 17:50:27 »
Retomo este tema por una pequeña duda. He utilizado esta libreria en una ocasion, y lo que hice fue modificar la disposicion de los pines en la propia libreria, pero no se si se puede hacer fuera, en el programa en concreto, para no tener que modificar la libreria cada vez.

1 saludo.
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #12 en: 17 de Febrero de 2008, 03:44:09 »
Sí también también te puedes llevar las líneas de control de la LCD para fuera.

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3206
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #13 en: 17 de Febrero de 2008, 15:27:56 »
Pero eliminando las de la libreria?, o poniendo fuera las que yo necesito, y dejando la libreria tal cual?

1saludo y gracias.
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
Re: Ayuda libreria LCD para pic 16F84A
« Respuesta #14 en: 17 de Febrero de 2008, 16:16:14 »
Mejor las dejas como comentarios en la libreria y las activas fuera cambiando lo que desees.

Un saludo