Autor Tema: Problema con I2C en C18  (Leído 8848 veces)

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

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Problema con I2C en C18
« Respuesta #15 en: 19 de Octubre de 2010, 17:16:13 »
No logro encontrar el hilo, seguiré buscando si alguien se sabe el nombre le agradecería que me lo dijera por aquí

Saludos  :mrgreen:

Vaya qué memoria tienes.  :shock: :shock: :shock:

Una pista: tú mismo abriste el hilo y Manwenwe y Suky te respondieron.

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Problema con I2C en C18
« Respuesta #16 en: 19 de Octubre de 2010, 18:58:26 »
Ocupo vacaciones..... :shock: ya se cual es el hilo, enserio que no me acordaba.... jajajjaja  :oops:

Gracias

Saludos
Lo que no me destruye, me fortalece

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema con I2C en C18
« Respuesta #17 en: 19 de Octubre de 2010, 19:43:53 »
Ocupo vacaciones..... :shock: ya se cual es el hilo, enserio que no me acordaba.... jajajjaja  :oops:

Naaaa!!!  :shock: Hay que aflojarle a las bebidas alcohólicas!  :D :D  ;-)


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Problema con I2C en C18
« Respuesta #18 en: 19 de Octubre de 2010, 19:47:21 »
Jajajajaja :D :D  Ojala permitieran bebidas alcoholicas en el trabajo jejeje... seria la onda 8)
Lo que no me destruye, me fortalece

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Problema con I2C en C18
« Respuesta #19 en: 19 de Octubre de 2010, 20:01:44 »
Estoy probando la librería del de I2C por software y tengo algunas dudas, no se si alguien de por aqui ya la habrá probado y le le haya funcionado al 100....

Tengo mi siguiente código simplemente para probar la escritura y según yo no se me esta habilitando la comunicación entre la memoria 24lc256 y el microcontrolador PIC18F4610.

El codigo de prueba es el siguiente:

Código: [Seleccionar]
#include <p18f4610.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <sw_uart.h>
#include <delays.h>
#include <sw_i2c.h>
#include "./Include/lcd_serial.h"
//#include "./Include/LCD_CRYSTAL.h"
//#include "./Include/Teclado.h"
//#include "./Include/ds1302.h"

#pragma config OSC=HS,FCMEN=OFF,IESO=OFF
#pragma config PWRT=ON,BOREN=OFF,BORV=0,WDT=OFF,WDTPS=32768
#pragma config MCLRE=ON,LPT1OSC=OFF,PBADEN=OFF,CCP2MX=PORTBE
#pragma config STVREN=OFF,LVP=OFF,XINST=OFF,DEBUG=OFF
#pragma config CP0=OFF,CP1=OFF,CP2=OFF,CP3=OFF,CPB=OFF
#pragma config WRT0=OFF,WRT1=OFF,WRT2=OFF,WRT3=OFF,WRTB=OFF,WRTC=OFF
#pragma config EBTR0=OFF,EBTR1=OFF,EBTR2=OFF,EBTR3=OFF,EBTRB=OFF

unsigned char Data,Var;

void byte_write(void);

void main(void)
{
ADCON1=15;
    OpenUART(); //Habilita los puerto de comunicación serial por software

Delay_ms(500);
WriteUART(0xFE);
WriteUART(0x01);
WriteLCD(" Prueba a Memoria",17);

byte_write();
Delay1KTCYx(5);

Delay_ms(500);
WriteUART(0xFE);
WriteUART(0x01);
WriteLCD(" Prueba a Memoria 1",19);

}

void byte_write(void)
{
SWStartI2C();
SWWriteI2C(0xA0);
SWAckI2C();
SWWriteI2C(0x00);
SWAckI2C();
SWWriteI2C(0x00);
SWAckI2C();
SWWriteI2C(0x66);
SWAckI2C();
SWStopI2C();
}

De la librería sw_i2c.h modifique los pines que venian por default y puse los siguientes:

Código: [Seleccionar]
#if defined(SW_I2C_IO_V1)

#define  DATA_LOW   TRISEbits.TRISE2 = 0; // define macro for data pin output
#define  DATA_HI    TRISEbits.TRISE2 = 1; // define macro for data pin input
#define  DATA_LAT   LATEbits.LATE2        // define macro for data pin latch
#define  DATA_PIN   PORTEbits.RE2         // define macro for data pin

#define  CLOCK_LOW  TRISEbits.TRISE1 = 0; // define macro for clock pin output
#define  CLOCK_HI   TRISEbits.TRISE1 = 1; // define macro for clock pin input
#define  SCLK_LAT   LATEbits.LATE1        // define macro for clock pin latch
#define  SCLK_PIN   PORTEbits.RE1         // define macro for clock pin

No se porque no me funciona esto....
Lo que no me destruye, me fortalece

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Problema con I2C en C18
« Respuesta #20 en: 19 de Octubre de 2010, 20:55:20 »
Realice los siguientes pasos pero aun asi no me funciona....

http://www.todopic.com.ar/foros/index.php?topic=12407.0
Lo que no me destruye, me fortalece

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Problema con I2C en C18
« Respuesta #21 en: 19 de Octubre de 2010, 21:30:58 »
No me fuunciona y no se porque..... me comienzo a frustar... no hay mucha ayuda respecto a este tema...
Lo que no me destruye, me fortalece

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Problema con I2C en C18
« Respuesta #22 en: 20 de Octubre de 2010, 12:59:26 »
Alguien de por aquí ya ha podido echar a andar el protocolo i2c por software? Por que yo aun realmente no he podido hecharlo a andar.... he estado buscando información en Internet y no me ha ayudado de mucho... :(
Lo que no me destruye, me fortalece

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Problema con I2C en C18
« Respuesta #23 en: 21 de Octubre de 2010, 16:05:37 »
Estaba viendo las funciones del protocolo de comunicación i2c por software y casi la mayoría de las funciones hace referencia a "i2c_data.h"

i2c_data.h:
Código: [Seleccionar]
#ifndef __SWI2C16D_H
#define __SWI2C16D_H

#include <sw_i2c.h>


/*****   VARIABLES DECLARED FOR PIC18CXXX   *****/

extern far unsigned char I2C_BUFFER;    // temp buffer for R/W operations
extern far unsigned char BIT_COUNTER;   // temp buffer for bit counting

/*  end  swi2c16d.h file */

#endif

y del cual estoy viendo que ponen 2 funciones como extern far estas tengo que declararlas en algún lugar? que valores tomarían? y este .h lo tengo que poner en algun lado o por default lo jala hacia mi proyecto? puede ser ese el origen de mi falla y por tal que no me realice el protocolo i2c por software?

sw_i2c.h:
Código: [Seleccionar]
#ifndef __SWI2C16_H
#define __SWI2C16_H

#include <pconfig.h>

#include "p18cxxx.h"
/* PIC18 software I2C interface header */

/*****   COMMON FUNCTION PROTOTYPES   *****/

void SWStopI2C ( void );                // Generate bus stop condition
void SWStartI2C ( void );               // Generate bus start condition
void SWRestartI2C ( void );             // Generate bus restart condition
void SWStopI2C ( void );                // Generate bus stop condition

// USER NEEDS TO DEFINE DATA AND CLOCK PINS. RESISTORS ARE REQUIRED ON
// DATA AND CLOCK PINS.

#if defined(SW_I2C_IO_V1)

#define  DATA_LOW   TRISEbits.TRISE2 = 0; // define macro for data pin output
#define  DATA_HI    TRISEbits.TRISE2 = 1; // define macro for data pin input
#define  DATA_LAT   LATEbits.LATE2        // define macro for data pin latch
#define  DATA_PIN   PORTEbits.RE2         // define macro for data pin

#define  CLOCK_LOW  TRISEbits.TRISE1 = 0; // define macro for clock pin output
#define  CLOCK_HI   TRISEbits.TRISE1 = 1; // define macro for clock pin input
#define  SCLK_LAT   LATEbits.LATE1        // define macro for clock pin latch
#define  SCLK_PIN   PORTEbits.RE1         // define macro for clock pin

#elif defined(SW_I2C_IO_V2)

#define  DATA_LOW   TRISBbits.TRISB0 = 0; // define macro for data pin output
#define  DATA_HI    TRISBbits.TRISB0 = 1; // define macro for data pin input
#define  DATA_LAT   LATBbits.LATB0        // define macro for data pin latch
#define  DATA_PIN   PORTBbits.RB0         // define macro for data pin

#define  CLOCK_LOW  TRISBbits.TRISB1 = 0; // define macro for clock pin output
#define  CLOCK_HI   TRISBbits.TRISB1 = 1; // define macro for clock pin input
#define  SCLK_LAT   LATBbits.LATB1        // define macro for clock pin latch
#define  SCLK_PIN   PORTBbits.RB1         // define macro for clock pin

#elif defined(SW_I2C_IO_V3)
#define  DATA_LOW   TRISBbits.TRISB5 = 0; // define macro for data pin output
#define  DATA_HI    TRISBbits.TRISB5 = 1; // define macro for data pin input
#define  DATA_LAT   LATBbits.LATB5        // define macro for data pin latch
#define  DATA_PIN   PORTBbits.RB5         // define macro for data pin

#define  CLOCK_LOW  TRISBbits.TRISB4 = 0; // define macro for clock pin output
#define  CLOCK_HI   TRISBbits.TRISB4 = 1; // define macro for clock pin input
#define  SCLK_LAT   LATBbits.LATB4        // define macro for clock pin latch
#define  SCLK_PIN   PORTBbits.RB4         // define macro for clock pin  

#else

#define  DATA_LOW   TRISCbits.TRISC4 = 0; // define macro for data pin output
#define  DATA_HI    TRISCbits.TRISC4 = 1; // define macro for data pin input
#define  DATA_LAT   LATCbits.LATC4        // define macro for data pin latch
#define  DATA_PIN   PORTCbits.RC4         // define macro for data pin

#define  CLOCK_LOW  TRISCbits.TRISC3 = 0; // define macro for clock pin output
#define  CLOCK_HI   TRISCbits.TRISC3 = 1; // define macro for clock pin input
#define  SCLK_LAT   LATCbits.LATC3        // define macro for clock pin latch
#define  SCLK_PIN   PORTCbits.RC3         // define macro for clock pin
#endif

/*****   FUNCTION PROTOTYPES FOR PIC18CXXX   *****/
signed char SWAckI2C( void );             // Read bus ACK condition
signed char Clock_test( void );
unsigned int SWReadI2C( void );          // Read in single byte
signed char SWWriteI2C( auto unsigned char data_out ); // Write out single byte
signed char SWGetsI2C( auto unsigned char *rdptr, auto unsigned char length );   // Read in string from I2C module
signed char SWPutsI2C( auto unsigned char *wrptr );    // Write string to I2C module

#define  SWPutcI2C    SWWriteI2C
#define  SWGetcI2C    SWReadI2C
#define  SWNotAckI2C  SWAckI2C

#endif

y las funciones .c:

Código: [Seleccionar]
#include <p18cxxx.h>
#include <delays.h>
#include "i2c_data.h"

/********************************************************************
*     Function Name:    signed char SWAckI2C(void)                  *
*     Return Value:     error condition status                      *
*     Parameters:       void                                        *
*     Description:      This function generates a bus acknowledge   *
*                       sequence.                                   *
********************************************************************/
signed char SWAckI2C( void )
{
  SCLK_LAT = 0;                   // set clock pin latch to 0 
  CLOCK_LOW;                      // set clock pin to output to drive low
  DATA_HI;                        // release data line to float high
  Delay10TCY();                   // user may need to modify based on Fosc
  CLOCK_HI;                       // release clock line to float high
  Delay1TCY();                    // 1 cycle delay
  Delay1TCY();                    // 1 cycle delay

  if ( DATA_PIN )                 // error if ack = 1, slave did not ack
  {
    return ( -1 );                // return with acknowledge error
  }
  else
  {
    return ( 0 );                 // return with no error
  }
}


Código: [Seleccionar]
#include <p18cxxx.h>
#include <delays.h>
#include "i2c_data.h"

/********************************************************************
*   Function Name:      signed char Clock_test(void)                *
*   Return Value:       error condition status                      *
*   Parameters:         void                                        *
*   Description:        This function allows for a slave I2C device *
*                       to stretch the clock low. The time period to*
*                       wait may need to be adjusted.               *
********************************************************************/
signed char Clock_test( void )
{
  Delay10TCYx(3);                 // user may need to adjust timeout period

  if ( !SCLK_PIN )                // if clock is still low after wait
  {
    return ( -2 );                // return with clock error
  }
  else
  {
    return ( 0 );                 // return with no error
  }
}


Código: [Seleccionar]
#include <p18cxxx.h>
#include <delays.h>
#include <sw_i2c.h>

far unsigned char I2C_BUFFER;    // temp buffer for R/W operations
far unsigned char BIT_COUNTER;   // temp bufffer for bit counting

/********************************************************************
*     Function Name:    unsigned int SWReadI2C(void)                *
*     Return Value:     data byte or error condition                *
*     Parameters:       void                                        *
*     Description:      Read single byte from I2C bus.              *
********************************************************************/
unsigned int SWReadI2C( void )
{
  BIT_COUNTER = 8;                // set bit count for byte
  SCLK_LAT = 0;                   // set clock pin latch to 0

  do
  {
    CLOCK_LOW;                    // set clock pin output to drive low
    DATA_HI;                      // release data line to float high
    Delay10TCY();                 // user may need to modify based on Fosc
    CLOCK_HI;                     // release clock line to float high
    Delay1TCY();                  // user may need to modify based on Fosc
    Delay1TCY();

    if ( !SCLK_PIN )              // test for clock low
    {
      if ( Clock_test( ) )        // clock wait routine
      {
        return ( -2 );            // return with error condition       
      }
    }

    I2C_BUFFER <<= 1;             // shift composed byte by 1
    I2C_BUFFER &= 0xFE;           // clear bit 0

    if ( DATA_PIN )               // is data line high
     I2C_BUFFER |= 0x01;          // set bit 0 to logic 1
   
  } while ( --BIT_COUNTER );      // stay until 8 bits have been acquired

  return ( (unsigned int) I2C_BUFFER ); // return with data
}


Código: [Seleccionar]
#include <p18cxxx.h>
#include <delays.h>
#include "i2c_data.h"


/********************************************************************
*     Function Name:    signed char SWGetsI2C(unsigned char *rdptr, *
*                                             unsigned char length) *
*     Return Value:     return with error condition                 *
*     Parameters:       address of read string storage location and *
*                       length of string bytes to read              *
*     Description:      This routine reads a string from the I2C    *
*                       bus.                                        *
********************************************************************/
signed char SWGetsI2C( unsigned char *rdptr,  unsigned char length )
{
  unsigned int thold;             // define auto variable

  while ( length --)              // stay in loop until byte count is zero
  {
    thold = SWGetcI2C();          // read and save 1 byte
    if ( thold & 0xFF00 )
    {
      return ( -1 );              // return with error condition
    }
    else
    {
      *rdptr++ = thold;           // save off byte read
    }

    if ( !length )                // initiate NOT ACK
    {
      CLOCK_LOW;                  // make clock pin output to drive low
      DATA_HI;                    // release data line to float high
      Delay10TCY();               // user may need to modify based on Fosc
      CLOCK_HI;                   // release clock line to float high
      Delay10TCY();               // user may need to modify based on Fosc
    }
    else                          // else initiate ACK condition
    {
      CLOCK_LOW;                  // make clock pin output to drive low
      DATA_LAT = 0;               // set data pin latch to 0
      DATA_LOW;                   // make data pin output to drive low
      Delay10TCY();               // user may need to modify based on Fosc
      CLOCK_HI;                   // release clock line to float high
      Delay10TCY();               // user may need to modify based on Fosc
    }
  }   
  return( 0 );                    // return with no error
}



Código: [Seleccionar]
#include <p18cxxx.h>
#include <delays.h>
#include "i2c_data.h"

/**********************************************************************
*     Function Name:    signed char SWWriteI2C(unsigned char data_out)*
*     Return Value:     error condition if bus error occurred         *
*     Parameters:       Single data byte for I2C bus.                 *
*     Description:      This routine writes a single byte to the      *
*                       I2C bus.                                      *
**********************************************************************/
signed char SWWriteI2C( unsigned char data_out )
{
  BIT_COUNTER = 8;                // initialize bit counter
  I2C_BUFFER = data_out;          // data to send out
  SCLK_LAT = 0;                   // set latch to 0
                                 
  do
  {
    if ( !SCLK_PIN )              // test if clock is low
    {                             // if it is then ..
      if ( Clock_test( ) )        // wait on clock for a short time
      {
        return ( -1 );            // return with error condition     
      }
    }

    else
    {
     I2C_BUFFER &= 0xFF;          // generate movlb instruction
      _asm
      rlcf I2C_BUFFER,1,1         // rotate into carry and test 
      _endasm

      if ( STATUS & 0x01 )        // if carry set, transmit out logic 1
      {
       CLOCK_LOW;                 // set clock pin output to drive low
       DATA_HI;                   // release data line to float high
       Delay10TCY();              // user may need to modify based on Fosc
       CLOCK_HI;                  // release clock line to float high
       Delay10TCY();              // user may need to modify based on Fosc
      }
      else                        // transmit out logic 0
      {
        CLOCK_LOW;                // set clock pin output to drive low
        DATA_LAT = 0;             // set data pin latch to 0
        DATA_LOW;                 // set data pin output to drive low
        Delay10TCY();             // user may need to modify based on Fosc
        CLOCK_HI;                 // release clock line to float high
        Delay10TCY();             // user may need to modify based on Fosc
      }

     BIT_COUNTER --;              // reduce bit counter by 1
    }
  } while ( BIT_COUNTER );        // stay in transmit loop until byte sent

  return ( 0 );                   // return with no error
}


Código: [Seleccionar]
#include <p18cxxx.h>
#include "i2c_data.h"

/********************************************************************
*     Function Name:    signed char SWPutsI2C(unsigned char *wrptr) *
*     Return Value:     end of string indicator or bus error        *
*     Parameters:       address of write string storage location    *
*     Description:      This routine writes a string to the I2C bus.*
********************************************************************/
signed char SWPutsI2C( unsigned char *wrptr )
{
  while ( *wrptr )
  {               
    if ( SWPutcI2C( *wrptr++) )   // write out data string to I2C receiver
    {
      return( -1 );               // return if there was an error in Putc()
    }
    else
    {
      if ( SWAckI2C( ) )          // go read bus ack status
      {
        return( -1 );             // return with possible error condition
      }
    }
  }                             
  return ( 0 );                   // return with no error
}



Código: [Seleccionar]
#include <p18cxxx.h>
#include <delays.h>
#include "i2c_data.h"

/********************************************************************
*     Function Name:    void SWRestartI2C(void)                     *
*     Return Value:     void                                        *
*     Parameters:       void                                        *
*     Description:      Send I2C bus restart condition.             *
********************************************************************/
void SWRestartI2C( void )
{
  SCLK_LAT = 0;                   // set clock pin latch to 0
  CLOCK_LOW;                      // set clock pin to output to drive low
  DATA_HI;                        // release data pin to float high
  Delay10TCY();                   // user may need to modify based on Fosc
  CLOCK_HI;                       // release clock pin to float high
  Delay10TCY();                   // user may need to modify based on Fosc
  DATA_LAT = 0;                   // set data pin latch to 0
  DATA_LOW;                       // set data pin output to drive low
  Delay10TCY();                   // user may need to modify based on Fosc
}

Código: [Seleccionar]
#include <p18cxxx.h>
#include <delays.h>
#include "i2c_data.h"

/********************************************************************
*     Function Name:    void SWStopI2C(void)                        *
*     Return Value:     void                                        *
*     Parameters:       void                                        *
*     Description:      Send I2C bus stop condition.                *
********************************************************************/
void SWStopI2C( void )
{
  SCLK_LAT = 0;                   // set clock pin latch to 0
  CLOCK_LOW;                      // set clock pin to output to drive low
  DATA_LAT = 0;                   // set data pin latch to 0
  DATA_LOW;                       // set data pin output to drive low
  Delay10TCY();                   // user may need to modify based on Fosc
  CLOCK_HI;                       // release clock pin to float high
  Delay10TCY();                   // user may need to modify based on Fosc
  DATA_HI;                        // release data pin to float high
  Delay1TCY();                    // user may need to modify based on Fosc
  Delay1TCY();
}

Código: [Seleccionar]
#include <p18cxxx.h>
#include <delays.h>
#include "i2c_data.h"

/********************************************************************
*     Function Name:    void SWStartI2C(void)                       *
*     Return Value:     void                                        *
*     Parameters:       void                                        *
*     Description:      Send I2C bus start condition.               *
********************************************************************/
void SWStartI2C( void )
{
  DATA_LAT = 0;                   // set data pin latch to 0
  DATA_LOW;                       // set pin to output to drive low
  Delay10TCY();                   // user may need to modify based on Fosc
}


Quiero pensar que algo estoy haciendo mal o me falta configurar.... :?

Lo que no me destruye, me fortalece

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Problema con I2C en C18
« Respuesta #24 en: 21 de Octubre de 2010, 16:36:36 »
Lo que deseo es emular la comunicación i2c ya que los pines que vienen por hardware los tengo ocupados en otra aplicación... En Pic Basic he logrado realizarlo, pero en C18 se me ha dificultado hacerlo.... :(
Lo que no me destruye, me fortalece