Autor Tema: Liberia propia para I2C  (Leído 1590 veces)

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

Desconectado shadow_smdk

  • PIC10
  • *
  • Mensajes: 7
Liberia propia para I2C
« en: 31 de Enero de 2012, 14:41:12 »
Buenos dias muchachos! Mi nombre es Diego y hace rato que vengo leyendo el foro. Por lo general no soy de postear consultas, pero la verdad que estoy desconcertado.

No me gusta trabajar con librerias ajenas, asi que yo mismo hago todas las librerias que uso. Ahora estoy haciendo un programa de comunicacion I2C para un 18F. Converti la libreria que tenia en assembler para poder usarla en C18, pero no hay forma de que me comunique, y la verdad que no puedo encontrar el error.

Aca se las copio.... Cualquier ayuda sera agradecida... y por ahi le sirve a alguien tambien:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                 Prototipos de las funciones                                    ////
////                                                                                    ////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void I2C_SDA_ES (unsigned char);
void I2C_SCL_AB    (unsigned char);
void I2C_Envia_Start (void);
void I2C_Envia_Stop (void);
void I2C_Envia_Byte (unsigned char);
unsigned char* I2C_Lee_Byte (unsigned char cantbytes);
void I2C_24XX_InicializaEscritura (unsigned char ,unsigned char);
void I2C_24XX_InicializaLectura (unsigned char ,unsigned char);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                 Defines   y variables gloables                                 ////
////                                                                                    ////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

unsigned char aux;
unsigned char aux2;
unsigned char cont;
unsigned char cont2;
unsigned char i=0;
unsigned char datos[4];
unsigned char* f;

#define      SDA      TRISCbits.TRISC4
#define      SCL      TRISCbits.TRISC3
#define      RC4      LATCbits.LATC4
#define      RC3      LATCbits.LATC5

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                     I2C_SDA_ES                                          ////
////                                                                                    ////                     
////   Proposito: Establece a SDA con entrada o salida                                                ////
////   Parametros:   tipo: 0 = salida 1 = entrada                                                                  ////
////                                                                                    ////                                          
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void I2C_SDA_ES (unsigned char tipo)
{   
   if (tipo == 0)    // Salida
   {
      SDA = 0;
      RC4 = 0;
   }
   else
      SDA = 1;   // Entrada
      RC4 = 1;
}   

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                     I2C_SCL_AB                                          ////
////                                                                                    ////                     
////   Proposito: Establece a SCL con entrada o salida   y establece el nivel                              ////
////   Parametros:   tipo: 0 = salida 1 = entrada                                                   ////
////                                                                                    ////                                          
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void I2C_SCL_AB    (unsigned char tipo)
{   
   if (tipo == 0)
   {            
      SCL = 0;         // Salida
      RC3 = 0;         //Mantiene en nivel bajo
   }
   else
   {
      SCL = 1;         // Entrada
      RC3 = 1;         //Mantiene en nivel alto
      while (RC3 == 0)
      {               // Si algun esclavo mantiene la linea en bajo hay que esperar
      }
   }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                    I2C_Envia_Start                                       ////
////                                                                                    ////                     
////   Proposito: Envia lacondicion de Start                                                      ////
////   Parametros:   Ninguno                                                                     ////
////                                                                                    ////                                          
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void I2C_Envia_Start ()      // Crital de 8MHz
{
   I2C_SDA_ES(1);   // SDA Nivel Alto
   I2C_SCL_AB(1);   // SCL Nivel Alto
   Delay10TCYx(1);   // Espera de 5us
   I2C_SDA_ES(0);   // SDA Nivel Bajo
   Delay10TCYx(1);   // Espera de 5us
   I2C_SCL_AB(0);   // SCL Nivel Bajo
   Delay10TCYx(1);   // Espera de 5us
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                    I2C_Envia_Stop                                       ////
////                                                                                    ////                     
////   Proposito: Envia la condicion de Stop                                                      ////
////   Parametros:   Ninguno                                                                     ////
////                                                                                    ////                                          
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void I2C_Envia_Stop ()      // Crital de 8MHz
{
   I2C_SDA_ES(0);   // SDA Nivel Bajo
   I2C_SCL_AB(1);   // SCL Nivel Alto
   Delay10TCYx(1);   // Espera de 5us
   I2C_SDA_ES(1);   // SDA Nivel Alto
   Delay10TCYx(1);   // Espera de 5us
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                    I2C_Envia_Byte                                       ////
////                                                                                    ////                     
////   Proposito: Envia un byte                                                               ////
////   Parametros:   BYTE: Byte a enviar                                                            ////
////                                                                                    ////                                          
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void I2C_Envia_Byte (unsigned char BYTE)      // Crital de 8MHz
{
   aux = 0x80;
   cont = 8;

   for (cont=8 ; cont!=0 ; cont--)   // Envio de a uno los bits
   {
      aux2 = aux & BYTE;         // Verifico si es un 0 o un 1
      if (aux2 == aux)
      {
         I2C_SDA_ES(1);         // SDA Nivel Alto
      }
      else   
      {
         I2C_SDA_ES(0);         // SDA Nivel Bajo
      }

      I2C_SCL_AB(1);            // SCL Nivel Alto
      Delay10TCYx(1);            // Espera de 5us
      I2C_SCL_AB(0);            // SCL Nivel Bajo
      Delay10TCYx(1);            // Espera de 5us
      aux >>= 1;
   }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                    I2C_Lee_Byte                                       ////
////                                                                                    ////                     
////   Proposito: Lee un byte                                                                  ////
////   Parametros:   BYTE: Byte a enviar                                                            ////
////                                                                                    ////                                          
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

unsigned char* I2C_Lee_Byte (unsigned char cantbytes)      // Crital de 8MHz
{
   cont = 8;
   aux = 0x08;            // Mascara para agregar los 1 que voy leyendo
   aux2 = 0;            // Aca almaceno el byte leido

   I2C_SDA_ES(1);         // SDA Nivel Alto
   
   for (cont2 ; cont2!=0 ; cont2--)
   {
      for (cont=8 ; cont!=0 ; cont--)   // Envio de a uno los bits
      {
         I2C_SCL_AB(1);            // SCL Nivel Alto
         if (SDA == 1)            // Si es un 1, se lo agrego
            aux2 += aux;
         I2C_SCL_AB(0);            // SCL Nivel Bajo
         Delay10TCYx(1);            // Espera de 5us
         aux >>= 1;
      }
      
      datos=aux2;
      i++;

      if (cont2!=0)               // Veo si es el ultimo byte a leer. Si es, no tengo que enviar el ACK
         I2C_SDA_ES(0);            // SDA Nivel Bajo: Envio el ACK
      
      I2C_SCL_AB(1);               // SCL Nivel Alto
      Delay10TCYx(1);               // Espera de 5us
      I2C_SCL_AB(0);               // SCL Nivel Bajo
      Delay10TCYx(1);               // Espera de 5us
   }

   I2C_SDA_ES(0);            // SDA Nivel Alto ////////////////////
   I2C_Envia_Stop ();

//datos[0]=0x34;
   f=datos;
   return f;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                I2C_24XX_InicializaEscritura                                 ////
////                                                                                    ////                     
////   Proposito: Prepara la memoria para la escritura                                                ////
////   Parametros:   unisgned char AddressHight: Parte alta de la direccion donde se va a escribir               ////
////            unisgned char AddressLow: Parte baja de la direccion donde se va a escribir                  ////
////                                                                                    ////                                          
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void I2C_24XX_InicializaEscritura (unsigned char AddressHight, unsigned char AddressLow)
{
   I2C_Envia_Start ();            // Envia Start
   I2C_Envia_Byte (0xA0);         // Direccion de escritura del esclavo (Con A0,A1 y A2 conectados a masa)
   I2C_Envia_Byte (AddressHight);   // Envio la parte alta de la direccion de memoria a escribir
   I2C_Envia_Byte (AddressLow);   // Envio la parte baja de la direccion de memoria a escribir
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////                                I2C_24XX_InicializaLectura                                 ////
////                                                                                    ////                     
////   Proposito: Prepara la memoria para la lectura                                                ////
////   Parametros:   unisgned char AddressHight: Parte alta de la direccion donde se va a leer                  ////
////            unisgned char AddressLow: Parte baja de la direccion donde se va a leer                     ////
////                                                                                    ////                                          
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void I2C_24XX_InicializaLectura (unsigned char AddressHight, unsigned char AddressLow)
{
   TRISC = 0x00;
   I2C_Envia_Start ();            // Envia Start
   I2C_Envia_Byte (0xA0);         // Direccion de escritura del esclavo (Con A0,A1 y A2 conectados a masa)
   I2C_Envia_Byte (AddressHight);   // Envio la parte alta de la direccion de memoria a escribir
   I2C_Envia_Byte (AddressLow);   // Envio la parte baja de la direccion de memoria a escribir
   I2C_Envia_Stop ();            // Envia Stop

   I2C_Envia_Start ();            // Envia Start
   I2C_Envia_Byte (0xA1);         // Direccion de lectura del esclavo (Con A0,A1 y A2 conectados a masa)
}

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Liberia propia para I2C
« Respuesta #1 en: 31 de Enero de 2012, 17:52:58 »
Mejor utilizar el hardware (Módulo MSSP) y se puede aprovechar las funciones propias de C18 y crear por ejemplo:

Código: C
  1. #include <p18cxxx.h>
  2. #include <i2c.h>
  3. #include "GenericTypeDefs.h"
  4.  
  5. #define SEND_ACK        0
  6. #define SEND_NACK       1
  7.  
  8. void vHW_i2c_Start(void){
  9.         IdleI2C();
  10.         StartI2C();
  11.         IdleI2C();
  12. }
  13. UINT8 ui8HW_i2c_Write(UINT8 Data){
  14.         UINT8 Ack;
  15.        
  16.         Ack=WriteI2C(Data);
  17.        
  18.         if(Ack==0){return(0);}
  19.         else{return(1);}
  20. }
  21. void vHW_i2c_ReStart(void){
  22.         RestartI2C();
  23.         IdleI2C();
  24. }
  25. UINT8 ui8HW_i2c_Read(UINT8 Ack){
  26.         UINT8 Data;
  27.                
  28.         Data=ReadI2C();
  29.         if(Ack==0){
  30.                 AckI2C();
  31.         }else{
  32.                 NotAckI2C();
  33.         }
  34.         IdleI2C();
  35.        
  36.         return(Data);
  37. }
  38.  
  39. void vHW_i2c_Stop(void){
  40.         StopI2C();
  41.         IdleI2C();
  42. }

Y después para trabajar con una memoria haces, por ejemplo:

Código: C
  1. UINT8 ui8Status_Eeprom(void){
  2.         UINT8 Status;
  3.        
  4.    vHW_i2c_Start();
  5.    Status=ui8HW_i2c_Write(0xA0);
  6.    vHW_i2c_Stop();
  7.    
  8.    return(Status);
  9. }
  10.  
  11. void vWrite_Single_Eeprom(UINT16 Address,UINT8 Data){
  12.  
  13.    vHW_i2c_Start();
  14.    ui8HW_i2c_Write(0xA0);
  15.    ui8HW_i2c_Write(*((UINT8 *)&Address+1));
  16.    ui8HW_i2c_Write(Address);
  17.    ui8HW_i2c_Write(Data);
  18.    vHW_i2c_Stop();  
  19. }


Saludos!

No contesto mensajes privados, las consultas en el foro