Autor Tema: I2c y LCD  (Leído 5095 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
I2c y LCD
« en: 21 de Julio de 2004, 14:55:00 »
Estoy preparando un terminal RS232 con un pic 16F84 y una memoria Eprom 24lc32, ademas de un displiay de 2 lineas y teclado de 16 teclas. Tienen por objeto sacar mensajes de la eprom y visualizarlos en el LCD a partir de los codigos que entren por la rs232.
Serivira por ejemplo como terminal de alarmas de un sistema PLC o para el uso que se le quiera dar.
Los mensajes iran prepogramados en la eprom externa, seran de 16 caracteres.
TEngo la rutinas de teclado y LCD listas, pero me atasco en la cominicacion I2c con la eprom. Esta no responde. Esta conectada al RB1 y RB2 de pic 16f84.
La programacion es en C de CCS y quiero que dando una direccion entre 0 y 255 me lea 16 caracteres y los saque por el LCD.
A ver si podeis ayudarme. Cuando todo este listo prometo publicar esquemas y el codigo abierto para que os sea util si alguien lo quiere
Gracias

Desconectado gfp

  • PIC18
  • ****
  • Mensajes: 274
RE: I2c y LCD
« Respuesta #1 en: 21 de Julio de 2004, 18:00:00 »
Estimado, en este foro he aprendido algo muy importante y asi mismo como tu, necesite de una asesoría y varias personas con buen caracter me respondieron de forma puntutal, pero, es necesario que hagas el esfuerzo y coloques el programa que tienes, la idea es que hagas el esfuerzo de ir creando tu programa y nosostros con gusto te ayudaremos a solucionar tus inquietudes.
Saludos.

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: I2c y LCD
« Respuesta #2 en: 21 de Julio de 2004, 18:44:00 »
Por supuesto sin problemas, aunque es solo una rutina de lectura de la eprom, porque lo que tengo hecho son las rutina de trabajo, nada de la funcion definitiva.

esta es la de lectura de la eprom

#include <16F84.h>
#fuses XT,NOWDT
#use fast_io(A)
#use fast_io(B)
#use delay(clock=4000000)
 

#include <2432.c>
#include <kbd2.c>
#include <lcd2.c>

#ifndef EEPROM_SDA

#define EEPROM_SDA  PIN_B2
#define EEPROM_SCL  PIN_B1

#endif

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

void main() {
   BYTE value,data;
   EEPROM_ADDRESS address;

   int n = 0;  
   address=0x00;
while(n!=16)
   {
   address++;

   init_ext_eeprom();
   
   i2c_start();
   i2c_write((0xa0|(BYTE)(address>>7))&0xfe);
   i2c_write(address);
   i2c_start();
   i2c_write((0xa0|(BYTE)(address>>7))|1);
   data=i2c_read(0);
   i2c_stop();


   lcd_init();
   lcd_gotoxy(n,1);
   lcd_putc(data);
   delay_ms(1000);
   n++;  
   }
      return;
   }

la libreria 24C32.c


#ifndef EEPROM_SDA

#define EEPROM_SDA  PIN_B1
#define EEPROM_SCL  PIN_B2

#endif


#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE    2432

void init_ext_eeprom() {
   output_float(EEPROM_SCL);
   output_float(EEPROM_SDA);
}

BOOLEAN ext_eeprom_ready() {
   int1 ack;
   i2c_start();            // If the write command is acknowledged,
   ack = i2c_write(0xa0);  // then the device is ready.
   i2c_stop();
   return !ack;
}

void write_ext_eeprom(long int address, BYTE data) {
   while(!ext_eeprom_ready());
   i2c_start();
   i2c_write((0xa0|(BYTE)(address>>7))&0xfe);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
}


BYTE read_ext_eeprom(long int address) {
   BYTE data;

   while(!ext_eeprom_ready());
   i2c_start();
   i2c_write((0xa0|(BYTE)(address>>7))&0xfe);
   i2c_write(address);
   i2c_start();
   i2c_write((0xa0|(BYTE)(address>>7))|1);
   data=i2c_read(0);
   i2c_stop();
   return(data);
}


Y la libreria de LCD, todas estas funcionan fien, solo falla la lectura de la eprom y no se porque

#bit  lcd_enable = 5.2
#bit  lcd_rw     = 5.1
#bit  lcd_rs     = 5.0
#byte lcd_a = 5
#byte lcd_b = 6

#define LCD_LINEA2 0x40    // Dirección de memoria para la segunda línea
#define LCD_DATO    1
#define LCD_COMANDO 0

#define LCD_CLEAR        0x01
#define LCD_HOME    0x02

#define LCD_DISPLAY_OFF  0x08
#define LCD_DISPLAY_ON   0x0C
#define LCD_CURSOR_ON    0x0E
#define LCD_CURSOR_BLINK 0x0F

#define LCD_CURSOR_SHIFT_RIGHT  0x10
#define LCD_CURSOR_SHIFT_LEFT   0x14
#define LCD_DISPLAY_SHIFT_RIGHT 0x18
#define LCD_DISPLAY_SHIFT_LEFT  0x1C


int lcd_leer()
{
  int valor;

  set_tris_a(0x18);
  set_tris_b(0xFF);

  lcd_rw = 1;
  delay_cycles(1);
  lcd_enable = 1;
  delay_cycles(1);
  valor = lcd_b;
  lcd_enable = 0;
  delay_cycles(1);

  set_tris_b(0x00);
  return valor;
}


void lcd_enviar(int dir, int valor)
{
  set_tris_a(0x00);
  set_tris_b(0x00);

  lcd_rs = 0;
  while( bit_test(lcd_leer(),7) );
  lcd_rs = dir;
  delay_cycles(1);

  lcd_rw = 0;
  delay_cycles(1);
  lcd_enable = 0;
  lcd_b = valor;
  delay_cycles(1);
  lcd_enable = 1;
  delay_us(2);
  lcd_enable = 0;
}


void lcd_init()
{
  int i;

  set_tris_a(0x18);
  set_tris_b(0x00);

  lcd_enable = 0;
  lcd_rw = 0;
  lcd_rs = 0;
  delay_ms(15);

  for(i=0; i<3; i++)
  {
    lcd_enviar(LCD_COMANDO,0x38);
    delay_ms(5);
  }
  lcd_enviar(LCD_COMANDO,LCD_DISPLAY_ON);
  lcd_enviar(LCD_COMANDO,0x06);
  lcd_enviar(LCD_COMANDO,LCD_CLEAR);
  lcd_enviar(LCD_COMANDO,LCD_HOME);
}


void lcd_gotoxy( byte x, byte y) {
   byte dir;

   if(y!=1)
     dir=LCD_LINEA2;
   else
     dir=0;
   dir+=x-1;
   lcd_enviar(LCD_COMANDO,0x80|dir);
}


void lcd_putc( char c) {
   switch (c) {
     case "f"   : lcd_enviar(LCD_COMANDO,0x01);
                   delay_ms(2);
                   break;
     case "
"   : lcd_gotoxy(1,2);               break;
     case ""   : lcd_enviar(LCD_COMANDO,0x10);  break;
     default     : lcd_enviar(LCD_DATO,c);        break;
   }
}


char lcd_getc( int x, int y) {
   char valor;

    lcd_gotoxy(x,y);

    lcd_rs = 1;
    valor = lcd_leer();
    lcd_rs = 0;

    return valor;
}

Mirad a ver si alguien puede solucionarmelo, si necesitais mas informacion por supuesto que no hay problema, asi como colaboracion de lo que querais como hago en otros foros. Gracias

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: I2c y LCD
« Respuesta #3 en: 22 de Julio de 2004, 00:29:00 »
Vaya mezcladillo que has hecho.

Es más sencillo que todo eso. Las funciones que aparecen en el include de la eeprom para qué las gastas en el main? quita todo eso y deja el fichero principal supercorto.

Un saludo


Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: I2c y LCD
« Respuesta #4 en: 22 de Julio de 2004, 02:55:00 »
Estan ahi porque se usaran en la version definitiva, de momento el main es solo para probar a leer la eeprom y sacar u mensaje en el lcd.
No uso de momento las rutinas  de teclado aunque funcionan.
TAmbien funcionan bien todas las de la LCD con las de teclado, pero no consigo leer nada de la eprom. Ahi es donde esta el problema.
Lo que sobra sobra ahora, pero no cuando este la funcion completa, es mas, aun falta la libreria de comunicacion RS232.
Solo necesito que lea el pic de la eeprom, que no se el porque no lo hace. Siempre devuelve que no esta correcto con la funcion de chequeo despues de la de inicializacion.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: I2c y LCD
« Respuesta #5 en: 22 de Julio de 2004, 06:51:00 »
Hazlo así y no te compliques:

Codigo:
#include <16F876.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#include <2416.c> // SDA=PIN_C4 , SCL = PIN_C3
#include <lcd.c>

#define MAX 5

void main()
{
int const dato_write[5]={0,1,2,3,4};   
int dato_read;
int n;

EEPROM_ADDRESS direccion;
init_ext_eeprom();
lcd_init();

for (n=0;n<MAX;n++)
   write_ext_eeprom(n,dato_write[n]);
   
delay_ms(20);

for (n=0;n<MAX;n++)
{
   dato_read = read_ext_eeprom(n);
   printf(lcd_putc," %u",dato_read);
   delay_ms(1000);
}
for(; {}
}


Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: I2c y LCD
« Respuesta #6 en: 22 de Julio de 2004, 07:08:00 »
Muchas gracias por responderme, el problema sigue siendo que yo uso el 16F84 con un lcd 16 caracteres dos lineas y la libreria lcd.c no me la compila bien porque es para el 16f87XX
El lcd esta conectado al puerto B y tres lineas de control al puerto A
EL teclado al puerto B
La eprom esta en RB1 y RB2
y el puerto serie esta en las lineas que quedan libres en el puerto A
Una cuestion mas es si la patilla PP de la Eprom hay que ponerla a 1 o a 0, porque segun veo en varios usos en unos esta a 1 y en otros a 0. De todas forma he probado en ambos casos y no va.
Todo funciona inisito. El LCD con la libreria que publico arriba
El teclado con la libreria de arriba.
Trabajan bien conjuntamente las dos.
Solo surge problemas al leer por i2c la eprom.
Por favor, se que soy pesado, pero llevo tiempo con esto. Mira a ver las librerias que uso a ver donde esta el fallo, las estandar son para 16FXXX habria que acoplarlas al 16F84.

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: I2c y LCD
« Respuesta #7 en: 22 de Julio de 2004, 07:15:00 »
HE recompilado el programa usando mi libreria de LCD y no va, mira este es el codigo que uso a ver si ves porque.



#include <16F84.h>
#use delay(clock=4000000)
#fuses XT,NOWDT  
#include <2416.c>  
#include <lcd2.c>

#define MAX 5

void main()
{
int const dato_write[5]={0,1,2,3,4};   
int dato_read;
int n;

EEPROM_ADDRESS direccion;
init_ext_eeprom();
lcd_init();

//for (n=0;n<MAX;n++)
//   write_ext_eeprom(n,dato_write[n]);
   
//delay_ms(20);

for (n=0;n<MAX;n++)
{
   dato_read = read_ext_eeprom(n);
   printf(lcd_putc," %u",dato_read);
   delay_ms(1000);
}

}


LA Eprom ya tiene escrito el mensaje por eso no la programo
 la libreria la tienes arriba
lcd2.c

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: I2c y LCD
« Respuesta #8 en: 22 de Julio de 2004, 10:55:00 »
La librería lcd2.c es la de Microsystems, no? Esta librería usa 8 bits de datos en el PORTB con lo que si usas las dos líneas de I2C en RB0 y RB1 estas interfiriendo con la LCD.

Solución con tu PIC 16F84 usa RA0 y RA1 como SCL y SDA  (tienes que hacer estos cambios en la librería de la memoria) y luego usa la librería de CCS lcd.c que solo gasta 4 líneas de datos en RB4..RB7 (tendrás que habilitar en ella el uso del PORTB en lugar del PORTD).

Un saludo y a funcionar.

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: I2c y LCD
« Respuesta #9 en: 22 de Julio de 2004, 11:07:00 »
HE pensado sobre ese asunto de usar otro hardware.
Si supongo que es interferir sobre las linea s de datos del puerto B el lcd y el I2C.
Uso el compilador de CCS con la libreria de CCS. Pero ¿como se usa un LCD de 8 bits de datos con solo 4 bits?, donde hay una aclaracion sobre eso?. Seria una ventaja desde luego porque me deja 4 salidas libres.
De todas formas necesitaria las 8 para el teclado pero ese supongo que no interferira con la I2c ¿o si?.
¿Si es asi como conecto el teclado?.
La verdad es que es un empeño el hacerlo con un 16F84 porque no el 16Fxxx estaria resuelto con facilidad creo.
No tengo experiencia apenas sobre C para pics, si en Borland C para dos.
Solo he programado un control de valvula de escape para una moto, con un servo y funciona bien.
Tambien he programado el tipico Bot de seis patas y ese en assembler y tambien esta en marcha.
Me dedico a los PLCs profesionalmente y esto es un juguete para el tiempo libre, el cual cuando este terminado publicare completo, hard y soft. Si funciona alguna vez.
Gracias eres muy amable.

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: I2c y LCD
« Respuesta #10 en: 22 de Julio de 2004, 11:44:00 »
ME vas a mandar lejos pero no se como modificar la libreria.
Simplemente habilito el
// #define use_portb_lcd TRUE
y con eso ya esta todo conectado en PORT_B?
por lo que seria lo siguiente si no me equivoco


El LCD lo conecto con 4 bits de datos en RB4 B5 B6 B7, y los de control serian
los rb1 rb2 y rb3? asi va la libreria?
En Ra0 y RA1 para scl y sda neceitaria resistencias de pull ups externas supongo
Y otra cosa
la patilla PP de la eeprom la conecto a 0 o a 1?
Demasiadas preguntas?
Siento ser tan pesado de veras



Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: I2c y LCD
« Respuesta #11 en: 22 de Julio de 2004, 11:59:00 »
Por fin me deja responder el dichoso servidor ... ¡¡¡dita sea!!!

Te mando por privado el dibujo con las conexiones.

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: I2c y LCD
« Respuesta #12 en: 22 de Julio de 2004, 12:02:00 »
Mil Millones de gracias, ya se como modificar las librerias.
En cuanto funcione el terminal estara a vuestra disposicion aqui.
Llevo tiempo queriendo terminarlo.
Para lo que os haga falta aqui estoy.

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: I2c y LCD
« Respuesta #13 en: 24 de Julio de 2004, 14:07:00 »
Ando de nuevo liado
Bien hice el sistema como dijiste, funciona bien con el teclado y el LCD, pero en cuanto trato de leer la eprom no va
Me explico, he tenido que usar la libreria propia KBD2 porque la KBD solo lleva 3/4 teclas y yo quiero usar 4/4
Funciona, pero en el codigo que te paso no va en cuanto habilito las rutinas de lectura de la eprom.
A ver que se te ocurre
El mismo montaje con tu codigo si va
#include <16f84.h>

#use delay(clock=4000000,RESTART_WDT)
#use fast_io(A)
#use fast_io(B)
#fuses XT,NOWDT

#include <kbd2.c>
#include <lcd.c>
#include <2432.c>
#define MAX 16

main()
{
int dato_read;
int n;


  char k;
EEPROM_ADDRESS direccion;
   
   port_b_pullups(TRUE);
  lcd_init();         // Inicializar LCD
  lcd_gotoxy(1,1);
  lcd_putc("Tecla pulsada:";

  while(1)
  {
     k = kbd_getc();      // Leer tecla.
     if(k)              // si no ha devuelto 0
     {
        lcd_gotoxy(16,1);
        lcd_putc(k);      // Visualizar la tecla pulsada en el LCD.
     }
   init_ext_eeprom();
      for (n=0;n<MAX;n++)
      {
     dato_read = read_ext_eeprom(n);
     printf(lcd_putc,"%u",dato_read);
     delay_ms(1000);
      }
 }
}

La libreria que uso para el teclado es
/*-------------------------------------------*
 |  KBD2.C                                   |
 |  Autor: Pedro Mª Jiménez                  |
 |  (c) Microsystems Engineering (Bilbao)    |
*-------------------------------------------*/

// Funciones para la gestión del teclado de la Trainer PLUS.

// char kbd_getc()   Devuelve el código ASCII de la tecla pulsada.
//         Si no se pulsó ninguna, devuelve 0.


// Conexiones del teclado.
/*
            RB0 RB1 RB2 RB3
             ^   ^   ^   ^
             |   |   |   |
           |---|---|---|---|
  RB4 ---> | 1 | 2 | 3 | F |
           |---|---|---|---|
  RB5 ---> | 4 | 5 | 6 | E |
           |---|---|---|---|
  RB6 ---> | 7 | 8 | 9 | D |
           |---|---|---|---|
  RB7 ---> | A | 0 | B | C |
           |---|---|---|---|
*/

// Caracteres ASCII asociados a cada tecla:
char const KEYS[4][4] = {{"1","2","3","D"},
                         {"4","5","6","E"},
                         {"7","8","9","F"},
                         {"A","0","B","C"}};

#byte kbd_port_b = 6


char kbd_getc()
{
  char tecla=0;
  int f,c,t,i,j;

  port_b_pullups(true);
  set_tris_b(0b00001111); // RB7-RB4 salidas, RB3-RB0 entradas

  for(f=0x10, i=0; i<4; f<<=1, i++)
  {
    for(c=0x01, j=0; j<4; c<<=1, j++)
    {
      kbd_port_b = ~f;
      delay_cycles(1);
      t = kbd_port_b & 0x0F;
      t = ~(t | 0xF0);
      if(t == c)
      {
        delay_ms(20);
        tecla=KEYS[j];
        while(t==c)
        {
          restart_wdt();
          t = kbd_port_b & 0x0F;
          t = ~(t | 0xF0);
        }
        break;
      }
    }
    if(tecla)
      break;
  }


  return tecla;
}


El resto son la estandar con los cambios para el puerto B en el lcd y pines A para eprom


Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: I2c y LCD
« Respuesta #14 en: 24 de Julio de 2004, 14:18:00 »
Si te fijas en la rutina no se ejecuta nunca el leer la eprom, pero aun asi no va el teclado en cuanto incluyes esa parte del codigo
Se me habia olvidado comentartelo


 

anything