TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: LAFUMAT en 20 de Junio de 2012, 05:51:05

Título: BUS I2C EN HITECH
Publicado por: LAFUMAT en 20 de Junio de 2012, 05:51:05
Saludos:

llevo tiempo afianzando los conocimientos que fui recogiendo con las librerias LCD y RS232.

ahora quisiera meterme con el bus I2C, el cual creo comprender que podria usarlo tanto para manejar sensores de temperatura, memorias , asi como comunicacion entre micros...

el caso es que me he documentado y he mirado mucho sobre el bus.

mi problema viene cuando usando hitech, con un pic16f1937, voy a usar las librerias que viene incluida y siempre me da error.Error   [500] ; 0. undefined symbols:

yo creia que con incluir el "i2c.h" y poner el i2c_Start(), por ejemplo ya se podia ver algo.

es decir, usar los comando de escribir y leer.

la alternativa que seria, hacerse una libreria paso a paso??

Espero que alguien consiga darme luz en esto...

mil gracias de antemano
 :-/
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 20 de Junio de 2012, 09:36:51
YA EMPEZAMOS:

Era que no incluia las rutinas del ejemplo.

ya me compila, y hago pruebas, pero no me funciona.

en el oscilos me salen señales muy malas....

a ver que me recomiendan...

que estoy muy perdido, jaja
Título: Re: BUS I2C EN HITECH
Publicado por: AngelGris en 20 de Junio de 2012, 10:32:18
  Yo me hice la siguiente librería, que simula bien en proteus tanto para master como para slave. La probé en protoboard con un PIC 16F876A como master y una 24C04 y funcionó joya.

  No sé si haya cambios en los registros del SSP de distintos pics así que no estoy seguro que funcione en todos... sería cuestión de probarla.


Código: C
  1. /**************************************************************************
  2. *      Libreria para protocolo I2C Master por HardWare para HiTech        *
  3. ***************************************************************************
  4.  
  5. ***************************************************************************
  6. *                                                                         *
  7. * Antes de incluir este archivo en nuestro programa hay que definir       *
  8. * algunos parametros. Estos son                                           *
  9. *                                                                         *
  10. * PIC_CLK        (se usa para calcular el valor de SSPADD)                *    
  11. * I2C_BAUD       (velocidad de transferencia)                             *
  12. *                                                                         *
  13. ***************************************************************************
  14.  
  15. ***************************************************************************
  16. *                                                                         *
  17. * En esta libreria se encuentran las siguientes funciones                 *
  18. *                                                                         *
  19. * setup_i2c(char)               (inicializa el puerto I2C)                *
  20. * start_i2c()                   (envia start, inicia transmision)         *
  21. * rstar_i2c()                   (envia restart, reinicia transmision)     *
  22. * stop_i2c()                    (envia stop, termina transmision)         *
  23. * write_i2c(char)               (envia un byte)                           *
  24. * read_i2c(char)                (recibe un byte y envia ack o noack)      *
  25. *                                                                         *
  26. *  La funcion write_i2c() devuelve 0 si el dispositivo responde o 1 si el *
  27. * dispositivo no responde.                                                *
  28. *                                                                         *
  29. *  A la funcion read_i2c() hay que pasarle 0 si se quiere responder al    *
  30. * disipositivo o 1 si no se quiere responder                              *
  31. *                                                                         *
  32. *  En esta libreria estan definidos los parametros I2C_MASTER, I2C_SLAVE, *
  33. * I2C_10BIT_ADDRESS. Eston son utilizados en la funcion setup_i2c(char)   *
  34. *                                                                         *
  35. *  Tambien estan definidos ACK y NOACK que son los utilizados para        *
  36. * responder o no al dispositivo                                           *
  37. *                                                                         *
  38. ***************************************************************************
  39.  
  40. /* Ejemplo de configuracion y utilizacion
  41.  
  42.  #define PIC_CLK   10000000   // cristal 10MHz
  43.  #define I2C_BAUD  100000     // velocidad 100 KHz
  44.  #include "HardI2c.c"
  45.  
  46.  void main (void);
  47.  {
  48.    unsigned char respuesta;
  49.    unsigned char dato;  
  50.  
  51.    ......
  52.    ......
  53.    ......
  54.    setup_i2c (I2C_MASTER);
  55.    start_i2c();
  56.    respuesta = write_i2c (0b10101110);    // comunicacion para escribir en una 24C02C
  57.    if (respuesta == ACK)
  58.    {
  59.      write_i2c (0x00);                    // indico la direccion a escribir
  60.      write_i2c (0xF5);                    // escribo el dato F5
  61.      write_i2c (0x06);                    // escribo el dato 06
  62.    }
  63.    stop_i2c();
  64.  
  65.    // colocar un delay necesario para que termine de grabar la memoria
  66.  
  67.    start_i2c();
  68.    respuesta = write_i2c (0b10101110);    // comunicacion para escribir en una 24C02C
  69.    if (respuesta == ACK)
  70.    {
  71.      write_i2c (0x00);                    // indico la direccion de memoria
  72.      rstart_i2c();                       // reinicio la transmisión
  73.      respuesta = write_i2c (0b10101111);  // comunicacion para leer en una 24C02C
  74.      if (respuesta == ACK)
  75.      {
  76.        dato = read_i2c (ACK);             // leo el dato y respondo
  77.        dato = read_i2c (NOACK);           // leo el dato y no respondo
  78.      }
  79.    }
  80.    stop_i2c();
  81.  }
  82.  
  83. */
  84.  
  85. #if defined (PIC_CLK) && defined (I2C_BAUD)
  86.  
  87.   #define I2C_MASTER          0x38
  88.   #define I2C_SLAVE           0x26
  89.   #define I2C_10BIT_ADDRESS   0x01
  90.  
  91.   #ifndef ACK
  92.     #define ACK   0
  93.   #endif
  94.   #ifndef NOACK
  95.     #define NOACK 1
  96.   #endif
  97.  
  98.  
  99.   void setup_i2c (char x)
  100.   {
  101.     TRISC3 = 1;
  102.     TRISC4 = 1;
  103.     SSPSTAT = 0;
  104.     SSPCON = x;
  105.     SSPCON2 = 0;
  106.     if (SSPM3 == 1) SSPADD = (unsigned char)((PIC_CLK/(4*I2C_BAUD)) - 1);
  107.   }
  108.  
  109.   char start_i2c (void)
  110.   {
  111.     while (( SSPCON2 & 0x1F ) || RW );
  112.     SEN = 1;
  113.     return !BCLIF;
  114.   }
  115.  
  116.   void rstart_i2c (void)
  117.   {
  118.     while (( SSPCON2 & 0x1F ) || RW );
  119.     RSEN = 1;
  120.   }
  121.  
  122.   void stop_i2c (void)
  123.   {
  124.     while (( SSPCON2 & 0x1F ) || RW );
  125.     PEN = 1;
  126.   }
  127.  
  128.   char write_i2c (unsigned char data)
  129.   {
  130.     if (SSPM3 == 1)
  131.     {
  132.       while (( SSPCON2 & 0x1F ) || RW );
  133.       SSPBUF = data;
  134.       while (RW == 1);
  135.       return ACKSTAT;
  136.     }
  137.     else
  138.     {
  139.       SSPBUF = data;
  140.       CKP = 1;
  141.       return 0;
  142.     }
  143.   }
  144.  
  145.   unsigned char read_i2c (unsigned char respuesta)
  146.   {
  147.     unsigned char dato;
  148.  
  149.     if (SSPM3 == 1)
  150.     {
  151.       while (( SSPCON2 & 0x1F ) || RW );
  152.       RCEN = 1;
  153.       while (( SSPCON2 & 0x1F ) || RW );
  154.       dato = SSPBUF;
  155.       while (( SSPCON2 & 0x1F ) || RW );
  156.       ACKDT = respuesta;
  157.       ACKEN = 1;
  158.       return dato;
  159.     }
  160.     else
  161.     {
  162.       dato = SSPBUF;
  163.       return dato;
  164.     }
  165.   }
  166. #else
  167.   #error Faltan definir parametros
  168. #endif
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 20 de Junio de 2012, 12:02:32
GRACIAS:

Como siempre angelgris está ahí!!

podrias pasarme en fichero para incluirlo y el Hardi2c.c del que se refiere la libreria.

he estado retocando la libreria de hitech y me da que no esta bien tanta definicion de pines y puertos, algo no lo reconoce bien o no lo ejecuta bien en un pic16.
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 20 de Junio de 2012, 12:15:27
por cierto y a modo de comentario.

tODAVIA NO HE CONSEGUIDO USAR UNA LIBRERIA DE HITECH Y QUE FUNCIONE!!

No se si es problema mio o de hitech, o que las librerias estan muy enreversadas, etc

las librerias de rs232 y lcd y A/D al final las que angelgris posteo, pero soy incapaz de hacer rular las dee hitech

será que soy torpe, me desanimo mucho con esto
Título: Re: BUS I2C EN HITECH
Publicado por: AngelGris en 20 de Junio de 2012, 13:26:06
GRACIAS:

Como siempre angelgris está ahí!!

podrias pasarme en fichero para incluirlo y el Hardi2c.c del que se refiere la libreria.

he estado retocando la libreria de hitech y me da que no esta bien tanta definicion de pines y puertos, algo no lo reconoce bien o no lo ejecuta bien en un pic16.

  El código que subí es justamente la librería, y el archivo que contiene dicho código es el que se llama HardI2c.c, yo no hago un archivo con extensión C y uno con extensión H por librería sino que hago sólo el de extensión C. De todos modos te adjunto el archivo.

Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 21 de Junio de 2012, 04:45:38
SALUDOS:

Me he puesto con ello, y he metido en el programa tu libreria.

yo quiero leer un sensor de temperatura pero veo que tu ejemplo es con una memoria 24lc02. yo tengo una placa de demo de microchip con varios dispositivos, y entre ellos el 24lc02B, definido en la posicion 0XAx, al mirar el esquema veo que las entradeas A2,A1 y A0 estan a cero, con lo que supongo que la direccion es 0xA0.

ademas al compilar me decia que RW no estaba definido, y lo he puesto como variable tipo char.

me compila pero en el oscilo veo algo pero no muy limpio.

he puesto al final del ejemplo escribir en LCD para comprobar, pero no llega ahi.

te posteo el codigo a ver si me hechas una mano a hacer andar esto...

y como siempre mil gracias

Código: [Seleccionar]

//********************************************************************
// INCLUDES NECESARIOS
//********************************************************************
#include <pic16f1937.h>
#include <htc.h>
#include <EEPROM_ROUTINES.H>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

//********************************************************************
//DEFINEs PRINCIPALES
//********************************************************************
#define _XTAL_FREQ 10000000
#define PIC_CLK   10000000   // cristal 10MHz
#define I2C_BAUD  100000     // velocidad 100 KHz               
                                                   
//CONFIGURACION DE LA LCD
#define LcdControlPort PORTC // Uso el puerto A para los bits de control
#define LcdRWBit 1 // El bit 2 del puerto A para RW
#define LcdRSBit 0 // El bit 3 del puerto A para RS
#define LcdENBit 2 // El bit 1 del puerto A para EN
#define LcdDataPort  PORTA // Uso el puerto D para los datos
#define LcdD4 0 // Solo utilizar para protocolo de 4 Bits(USA 0, AL 3)
//
//********************************************************************
//OTROS INCLUDEs
//********************************************************************
#include <LIB_LCD.H>
//
//********************************************************************
//FUNCIONES DE BITS
//********************************************************************
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define flip_bit(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define test_bit(ADDRESS,BIT) (ADDRESS & (1<<BIT))
//
//********************************************************************
//DEFINICION DE VARIABLES
//********************************************************************
unsigned char data1,i;
char text[10];
unsigned char respuesta;
unsigned char dato; 
char RW;
//

//********************************************************************
//***************************RUTINAS**********************************
//********************************************************************
/**************************************************************************
*      Libreria para protocolo I2C Master por HardWare para HiTech        *
***************************************************************************

***************************************************************************
*                                                                         *
* Antes de incluir este archivo en nuestro programa hay que definir       *
* algunos parametros. Estos son                                           *
*                                                                         *
* PIC_CLK        (se usa para calcular el valor de SSPADD)                *     
* I2C_BAUD       (velocidad de transferencia)                             *
*                                                                         *
***************************************************************************

***************************************************************************
*                                                                         *
* En esta libreria se encuentran las siguientes funciones                 *
*                                                                         *
* setup_i2c(char)               (inicializa el puerto I2C)                *
* start_i2c()                   (envia start, inicia transmision)         *
* rstar_i2c()                   (envia restart, reinicia transmision)     *
* stop_i2c()                    (envia stop, termina transmision)         *
* write_i2c(char)               (envia un byte)                           *
* read_i2c(char)                (recibe un byte y envia ack o noack)      *
*                                                                         *
*  La funcion write_i2c() devuelve 0 si el dispositivo responde o 1 si el *
* dispositivo no responde.                                                *
*                                                                         *
*  A la funcion read_i2c() hay que pasarle 0 si se quiere responder al    *
* disipositivo o 1 si no se quiere responder                              *
*                                                                         *
*  En esta libreria estan definidos los parametros I2C_MASTER, I2C_SLAVE, *
* I2C_10BIT_ADDRESS. Eston son utilizados en la funcion setup_i2c(char)   *
*                                                                         *
*  Tambien estan definidos ACK y NOACK que son los utilizados para        *
* responder o no al dispositivo                                           *
*                                                                         *
***************************************************************************

* Ejemplo de configuracion y utilizacion

 #define PIC_CLK   10000000   // cristal 10MHz
 #define I2C_BAUD  100000     // velocidad 100 KHz
 #include "HardI2c.c"

 void main (void);
 {
   unsigned char respuesta;
   unsigned char dato; 
 
   ......
   ......
   ......
   setup_i2c (I2C_MASTER);
   start_i2c();
   respuesta = write_i2c (0b10101110);    // comunicacion para escribir en una 24C02C
   if (respuesta == ACK)
   {
     write_i2c (0x00);                    // indico la direccion a escribir
     write_i2c (0xF5);                    // escribo el dato F5
     write_i2c (0x06);                    // escribo el dato 06
   }
   stop_i2c();

   // colocar un delay necesario para que termine de grabar la memoria

   start_i2c();
   respuesta = write_i2c (0b10101110);    // comunicacion para escribir en una 24C02C
   if (respuesta == ACK)
   {
     write_i2c (0x00);                    // indico la direccion de memoria
     rstart_i2c();                       // reinicio la transmisión
     respuesta = write_i2c (0b10101111);  // comunicacion para leer en una 24C02C
     if (respuesta == ACK)
     {
       dato = read_i2c (ACK);             // leo el dato y respondo
       dato = read_i2c (NOACK);           // leo el dato y no respondo
     }
   }
   stop_i2c();
 }

*/

#if defined (PIC_CLK) && defined (I2C_BAUD)

  #define I2C_MASTER          0x38
  #define I2C_SLAVE           0x26
  #define I2C_10BIT_ADDRESS   0x01

  #ifndef ACK
    #define ACK   0
  #endif
  #ifndef NOACK
    #define NOACK 1
  #endif


  void setup_i2c (char x)
  {
    TRISC3 = 1;
    TRISC4 = 1;
    SSPSTAT = 0;
    SSPCON = x;
    SSPCON2 = 0;
    if (SSPM3 == 1) SSPADD = (unsigned char)((PIC_CLK/(4*I2C_BAUD)) - 1);
  }

  char start_i2c (void)
  {
    while (( SSPCON2 & 0x1F ) || RW );
    SEN = 1;
    return !BCLIF;
  }

  void rstart_i2c (void)
  {
    while (( SSPCON2 & 0x1F ) || RW );
    RSEN = 1;
  }

  void stop_i2c (void)
  {
    while (( SSPCON2 & 0x1F ) || RW );
    PEN = 1;
  }

  char write_i2c (unsigned char data)
  {
    if (SSPM3 == 1)
    {
      while (( SSPCON2 & 0x1F ) || RW );
      SSPBUF = data;
      while (RW == 1);
      return ACKSTAT;
    }
    else
    {
      SSPBUF = data;
      CKP = 1;
      return 0;
    }
  }

  unsigned char read_i2c (unsigned char respuesta)
  {
    unsigned char dato;

    if (SSPM3 == 1)
    {
      while (( SSPCON2 & 0x1F ) || RW );
      RCEN = 1;
      while (( SSPCON2 & 0x1F ) || RW );
      dato = SSPBUF;
      while (( SSPCON2 & 0x1F ) || RW );
      ACKDT = respuesta;
      ACKEN = 1;
      return dato;
    }
    else
    {
      dato = SSPBUF;
      return dato;
    }
  }
#else
  #error Faltan definir parametros
#endif
//********************************************************************
//ROUTINE FOR INICIALICE ALL PORTS AND DEVICES OF SYSTEM
//********************************************************************
void init(void)
{
//OSCCON = 0b11101011; //RELOJ INTERNO A 4MHz
//OSCCON = 0b11101011;//OSCCON = 0b11101011; //RELOJ INTERNO
OSCTUNE = 0b00000000;
INTCON=0b00000000;//DESABILITA LAS INTERRUPCIONES
FVRCON = 0b10000011; //REGULADOR DE VOLTAJE lo cambiamos en cada lectura (depende de que midamos)
//BIT 7: 0- APAGADO 1- ENCENDIDO
//INIC PORTA
//IOCA  = 0x00; WPUA  = 0x00;
PORTA = 0x00; LATA = 0x00; ANSELA = 0b11100000; TRISA = 0b11100000;
//INIC PORTB
//IOCB  = 0x00;
WPUB = 0X00;
PORTB = 0x00; LATB = 0x00; ANSELB = 0b00011111; TRISB = 0b11011111;//ver en ansel b el rb0 si es dig o ana (cap)
//INIC PORTC
//PORTC = 0x00; LATC = 0x00;  TRISC = 0b00000000;
//INIC PORTD
PORTD = 0x00; LATD = 0x00; ANSELD = 0b00000000; TRISD = 0b00000000; //COMPRUEBA LAS ENTRADAS PARA LAS ANALOGICAS E/V
//INIC PORTE
PORTE = 0x00; LATE = 0x00; ANSELE = 0x00; TRISE = 0b00000001; //
//
IOCIF=0;
IOCBF = 0b00000000;
IOCIF=0;
InitLcd();
di();
IOCBF = 0b00000000;
IOCIF=0;
}

//********************************************************************
//RUTINA DE INTERRUPCIONES
//********************************************************************
static void interrupt isr(void)
{
}//fin de isr
//

//********************************************************************
//RUTINA PRESENTA EN LCD
//********************************************************************
//
void SHOW_LCD(void)
{
//char * SHOW_TEMP;
//int * seba;
ClearLcd();
GotoxyLcd (1,1);
WriteStrLcd ("TEMP= ");
//itoa(text,MCP,10);
GotoxyLcd (7,1);
//WriteStrLcd(dato);
//GotoxyLcd (12,1);
//WriteStrLcd (" ßC  ");
 __delay_ms(2000);
}
//*********************************************************************************
//**************************PROGRAMA PRINCIPAL*************************************
//*********************************************************************************
void main(void)
{

init();

   setup_i2c (I2C_MASTER);

   start_i2c();
   respuesta = write_i2c (0b10100000);    // comunicacion para escribir en una 24C02C
   if (respuesta == ACK)
   {
     write_i2c (0x00);                    // indico la direccion a escribir
     write_i2c (0xF5);                    // escribo el dato F5
     write_i2c (0x06);                    // escribo el dato 06
   }
   stop_i2c();

   // colocar un delay necesario para que termine de grabar la memoria
__delay_ms(1000);

   start_i2c();
   respuesta = write_i2c (0b10100000);    // comunicacion para escribir en una 24C02C
   if (respuesta == ACK)
   {
     write_i2c (0x00);                    // indico la direccion de memoria
     rstart_i2c();                       // reinicio la transmisión
     respuesta = write_i2c (0b10100001);  // comunicacion para leer en una 24C02C
     if (respuesta == ACK)
     {
       dato = read_i2c (ACK);             // leo el dato y respondo
       dato = read_i2c (NOACK);           // leo el dato y no respondo
     }
   }
   stop_i2c();


SHOW_LCD();


 }


Título: Re: BUS I2C EN HITECH
Publicado por: AngelGris en 21 de Junio de 2012, 09:18:57
  Hola LAFUMAT.

  Como primer punto te comento que no es necesario incluir todo el código de la librería en el programa (aunque seguramente ya lo sabrás, y lo habrás hecho para que otros puedan ver el código de la librería y aportar ideas), basta con poner

Código: C
  1. #include "HardUart.c"

  Otra cosa que noté en estos días es que MicroChip en algunos pics tiene distintos los nombres de los registros. Por ejemplo, para el 876 existe el registro SSPCON, pero para el 1937 no existe SSPCON y sí existe SSPCON1. Aunque el archivo pic16f1937.H de HiTech mantiene los dos nombres por compatibilidad (lo cual es muy bueno).
 
  Ahora bien, mantuvieron la compatibilidad con el nombre de los registros pero no con el nombre de los bits de los mismos. Para el 876 el bit RW es quien determina si se quiere leer o escribir en un dispositivo cuando está trabajando como esclavo, o nos indica que hay actividad en el bus cuando está trabajando como maestro. También existe el bit DA que indica que lo que está almacenado en SSPBUF  se trata de un dato o de una dirección (al estar el pic funcionando como esclavo nos sirve para determinar si es un dato lo que llegó). Para el 16F1937 estos bits pasaron a llamarse R_nW y D_nA respectivamente.

  Por lo tanto en el código de la librería, tendrías que reemplazar RW por R_nW. Para que quede compatible con tu PIC.
 
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 21 de Junio de 2012, 09:38:29
ok. entiendo lo que me dices.

lo he cambiado pero no rula.... :(

¿puede pasar lo mismo con BFLIP, SSPBUF , ACK Y NOACK.

en la hoja del pic1937 no veo esas.

¿como veis las cosas tan claras?, donde puedo mirar para enterarme más?
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 21 de Junio de 2012, 09:47:47
PUES NO, NO VA POR AHI, ESOS REGISTROS ESTAN BIEN Y EL ACK ESTA DEFINIDO.

El caso es que no me rula ni en proteus ni en la placa real.

algo estoy haciendo mal, seguro.

lo que me da rabia es que el ejemplo de la demo de microchip va de lujo.

 :?
por cierto y como siempre gracias por tu paciencia
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 21 de Junio de 2012, 09:54:58
aparentemente en proteus ahora funciona, pero en la placa real no.

tengo puesto al final el mostrar un texto en LCD, y no llega ahi el programa.

en el oscilo, veo que al empezar hay actividad, pero luego nada, como si se quedara tonto.

alguna config esta mal, ....

tambien podria ser que necesitara apantallar un poco más las señales ¿no?
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 21 de Junio de 2012, 10:36:54
 :-/
bravo

solucionado el primer problema.

ya funciona, se me habia movido un pin de la LCD.

ahora voy a jugar on escribir datos en la eeprom, y luego leerlos y pressentarlos en la pantalla, a ver si funciona.

espero que cacharreando, me vaya enterando a ver si se me mete este bus en el coco.

Título: Re: BUS I2C EN HITECH
Publicado por: AngelGris en 21 de Junio de 2012, 19:29:56

¿como veis las cosas tan claras?, donde puedo mirar para enterarme más?

  ¿Claras?  :x

  No, para nada... Yo había hecho la librería para el 876 y después me puse a ver los datasheets de otros PICs y noté lo del cambio de nombre en varios registros. Después de eso se me dio por ver los archivos de cabecera (extensión H) de HiTech para ver si había diferencias entre los nombres de registros y de los bits... O sea, no nos queda otra que leer detenidamente la parte del datasheet que nos interese (en este caso la del módulo SSP) y ver los archivos .H para comparar como se llaman los registros en uno y otro lugar.

  Que bueno que lo hayas hecho funcionar  :-/ :-/
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 22 de Junio de 2012, 04:17:28
BUENO, HARE LO QUE ME DICES.

Ahora me funciona, pero la placa real se queda parada aveces, y me funciona la escritura y lectura de la eprom, pero ahora estoy detras del MCP9804, y no hay forma de leer la temperatura.

primero simulo en proteus para verificar que la trama es correcta, pero en proteus tengo que usar el 9803, y los registros son distintos.

¿existe alguna aplicacion para usar el PICKIT serial como lector de tramas en la aplicacion...?

saludos
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 22 de Junio de 2012, 06:03:38
PUES SI...

HAY UNA APLICACION CON LA QUE PUEDO VER LAS TRAMAS.

ES MUY RUDIMENTARIO PERO ALGO ES ALGO
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 22 de Junio de 2012, 12:15:01
VALE:

HE podido con esta libreria usar el puerto de expansion de 8 bits, el conversor A/D de 12 bits y la eeprom. !!genial!!

pero el sensor MCP9804 se me resiste.

me lee, pero la conversion hago algo mal o el data sheet tiene algun error.

me lee siempre el mismo dato y no cuadra.

yo sigo la secuencia, pero nada de nada.


el sensor de la demo esta en la direccio 0x90 y para leer en la 0x91.

posteo la parte del codigo a ver si se ve algun fallo:

Código: [Seleccionar]
ClearLcd();
GotoxyLcd (1,1);
WriteStrLcd ("sensor mcp9804");
 __delay_ms(10);


start_i2c();
 respuesta = write_i2c (0b10010010);
 if (respuesta == ACK)
   {
     write_i2c (0x01);                   
    write_i2c (0x00);                   
     write_i2c (0x00);                   
  }
   stop_i2c();
__delay_ms(10);

while(1)
{
start_i2c();
 respuesta = write_i2c (0b10010010);
if (respuesta == ACK)
   {
     write_i2c (0x05);                   
 
  }

//rstart_i2c();                       
start_i2c();
     respuesta = write_i2c (0b10010011); 
     if (respuesta == ACK)
     {
// write_i2c (0x00);
MSB = read_i2c (ACK);           
// dato = read_i2c (NOACK);           
LSB = read_i2c (NOACK); 
       
     }
stop_i2c();

//convertir

MSB = MSB & 0x1F;
if ((MSB & 0x10)== 0x10)
{
MSB = MSB & 0x0F;
TEMP = 256 - (MSB*16 + LSB /16);
}
else
{
TEMP = (MSB*16 + LSB /16);
}



ClearLcd();
GotoxyLcd (1,1);
WriteStrLcd ("TEMP= ");
itoa(text,TEMP,10);
GotoxyLcd (7,1);
WriteStrLcd(text);
__delay_ms(100);
}



Tambien me queda la terea sobre lo que me comentas angelgris, verificar que la libreria incluida en hitech no funciona por algun cambio de nombre de algun registro.

de todas formas tu libreria funciona de maravilla,, y me pregunto si valdria para usarse en multimaster. ¿se podria usar para comunicar varias placas en multimaster ademas de tener algun slave?

saludos
Título: Re: BUS I2C EN HITECH
Publicado por: AngelGris en 22 de Junio de 2012, 16:27:24
  Hola.

  En el primer intente de comunicación estás poniendo

Código: C
  1. respuesta = write_i2c(0b10010010);

  pero ese valor en hexa es 0x92 y no 0x90 como mencionas que es la dirección del MCP9804.

  Dentro del while ocurre lo mismo en la primer llamada y en la segundo le estás mandando 0x93 como dirección de lectura.
Para escritura creo que la dirección sería 0b10010000 y para lectura 0b10010001 que son 0x90 y 0x91 respectivamente.


  En cuanto a utilizar la librería en multimaster, no lo sé porque no lo simulé nunca pero no creo ya que no implemento nada como para saber si hay colisión en el BUS
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 25 de Junio de 2012, 05:06:25
hola:

he revisado, y no, resulta que mi placa demo, el mcp9804 esta en la direccion 0x92H para la escritura y entonces la lectura estará en la 0x93h.

el caso es que segun el datasheet, el registro de la temperatura esta en el 0x05h, pero siempre me devuelve el mismo valor y cuando pongo el puntero en la 0x00h , me da valores pero no los se pasar a temperatura pero ese registro el datasheet dice que es para cosas futuras.

asi que estoy estancado en ese punto.
Título: Re: BUS I2C EN HITECH
Publicado por: AngelGris en 25 de Junio de 2012, 12:31:41
  Estoy mirando un poco el datasheet del sensor... aparentemente para leer el dispositivo no es necesario configurar nada, aunque sí lo es apuntar el registro 0x05 que es donde se almacena el valor de temperatura. Por lo tanto debería funcionar el siguiente código.

Código: C
  1. start_i2c();
  2. respuesta = write_i2c(0x92);
  3. if (respuesta == ACK)
  4. {
  5.   write_i2c(0x05);
  6.   rstart_i2c();
  7.   write_i2c(0x93);
  8.   bytealto = read_i2c(ACK);
  9.   bytebajo = rear_i2c(NOACK);
  10. }
  11. stop_i2c();

  Que prestándole más atención es lo que hace tu código dentro del while.

  Otra posibilidad es que haya un error en cuanto a la información de la dirección del MCP en tu placa...
  También se podría activar algún led si es que al respuesta del MCP, como para asegurarse que la dirección es la correcta.
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 25 de Junio de 2012, 12:41:38
PUES yo leyendo una vez mas el datasheet, me he fijado que este sensor funciona en modo standart (100kHz) ¿puede ser esa la causa?

¿tu libreria a que velocidad transmite? ¿cuales son los parametros de tiempos que hebria que tocar.??

gracias
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 25 de Junio de 2012, 13:33:21
el caso es que siempre me devuelve el mismo valor, que pasados a la lcd con itoa me quedan:

MSB= 84
LSB = 1

y no cambia nunca.

si cambio a otra direccion de dispositivo, me devuelve 255 y 255, puesto que no lee nada (imagino), pero he vuelto a comprobar y la direccion esta bien 0x92.
Título: Re: BUS I2C EN HITECH
Publicado por: AngelGris en 25 de Junio de 2012, 13:34:27
  La librería calcula la velocidad en base a PIC_CLK e I2C_BAUD.

  El primero de los dos, sería la velocidad a la cual queda trabajando el núcleo del PIC. Es decir que si el PIC tiene puesto un cristal de 8Mhz pero en la configuración tiene activado el PLL del oscilador, la frecuencia a la que trabaja el PIC es de 32Mhz.

  El segundo nos indica a que velocidad tiene que trabajar el I2C.

  Volviendo al ejemplo del cristal de 8MHz con el PLL activado... hay que poner las siguientes líneas en el programa antes de incluir la librería

Código: C
  1. #define PIC_CLK 32000000            // esta usa la libreria
  2. #define _XTAL_FREQ 32000000         // esto es de HiTech para los delays
  3. #define I2C_BAUD 100000             // I2C en 100KHz
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 26 de Junio de 2012, 05:06:18
pues lo tengo igual que me dices, con la diferencia de que en vez de a 32MHZ lo tengo a 16MHz.

Código: [Seleccionar]
#define PIC_CLK   16000000   // cristal 10MHz para lib de i2c
#define _XTAL_FREQ 16000000 //para los delays
#define I2C_BAUD  100000     // velocidad 100 KHz       
       

Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 26 de Junio de 2012, 06:48:37
VALE, YA LO VOY TENIENDO, VAYA TELA:

En la placa tengo un MCP9801 y me empecine en que era un mcp9804.

ya leo pero no termino de entender como hacer la conversion a decimal. me coge datos de MSB Y LAB y se supone que unos bit son los de despues del punto y otro los enteros y que estan en complemento a dos, pero bueno, dandole a ver que saco
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 26 de Junio de 2012, 07:34:42
YA LEO Y LO QUE NOTO ES QUE LA MEDIDA ES MUY VARIABLE, DE 20 A 30 Y ASI CONTINUAMENTE.

no veo una conversion corecta, por ejemplo al poner un dedo en el chip ver como sube la temperatura o cosas asi...
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 03 de Julio de 2012, 05:36:13
BUENO, CONSEGUIDO.

YA LO LEO, CADA MCP98xx LEE DE UNA FORMA Y EN EL MCP9801 DEPENDIENDO DE LA RESOLUCION HAY QUE TRATAR DE UNA FORMA, COMO LO TENGO A 0.5 DE RESOLUCION ME IMAGINO QUE LOS SALTOS SE DEBEN A LA POCA PRECISION.

GRACIAS DE NUEVO ANGELGRIS, VOY A SEGUIR DANDOLE AL I2C Y PRACTICAR MAS. YA IRE CONTANDO
Título: Re: BUS I2C EN HITECH
Publicado por: AngelGris en 03 de Julio de 2012, 09:03:11
  Que bueno que lo hayas conseguido  :-/ :-/

  Es un dolor de cabeza cuando hacen integrados con prestaciones similares y sin embargo son tan diferentes en su manejo  :5] Y pero aún eso que comentas que según la resolución lo tengas que leer de una forma u otra... que molesto por favor!!!!!!!!  :x
Título: Re: BUS I2C EN HITECH
Publicado por: LAFUMAT en 03 de Julio de 2012, 09:38:38
ASI ES AMIGO,

y aun asi, tengo que practicar, pues me lee entre 19 y 22 grados dando saltos, y ya no es problema de leer, sino que son los valores que devuelve, a ver que saco en claro

jaja
Título: Re: BUS I2C EN HITECH
Publicado por: Rseliman en 28 de Mayo de 2013, 14:27:38
Hola Amigos , estoy tratando de usar esta libreria en xc8 con un pic 16f819...mirando un poco me encuentro que el chip que uso AngelGris ..pic16f876 tiene los registros muy parecidos ...por ejemplo el SSPSTAT Y EL SSPCON son identicos , mi problema viene con el SSPCON2 QUE NO ESTA EN EL PIC819 ...ALGUEIN ME DA UNA MANO POR FAVOR

Muchas gracias