TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Palomino86 en 18 de Octubre de 2010, 13:11:42

Título: Problema con I2C en C18
Publicado por: Palomino86 en 18 de Octubre de 2010, 13:11:42
Hola que tal;

Estoy usando el protocolo de comunicación i2c para hechar andar una memoria eeprom externa (24lc256) de microchip apartir del ejemplo que viene en el tutorial de C18 de Suky, hasta ahorita solamente para realizar pruebas y estoy usando un microcontrolador PIC18F4610 el cual actua como maestro. Pero tengo un problema al momento de cambiar los pines. En teoría este microcontrolador usa la version I2C_V1 y en la libreria trae por default estos pines:

Pines libreria
Código: [Seleccionar]
#if defined (I2C_IO_V1 )
#define I2C_SCL TRISCbits.TRISC3
#define I2C_SDA TRISCbits.TRISC4
#endif

y yo lo que hice fue solamente modificar de i2c.h lo siguiente:
Código: [Seleccionar]
#if defined (I2C_IO_V1 )
#define I2C_SCL TRISEbits.TRISE1
#define I2C_SDA TRISEbits.TRISE2
#endif

Según yo es lo unico que ocupo modificar... ya que al momento de simularlo en proteus me esta tomando los pines PORTD0 Y PORTD1 para tal comunicacion.....

Hay algo adicional que deba de modificar en esto?

Gracias

Saludos
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 18 de Octubre de 2010, 13:15:17
Por cierto este es el codigo del microcontrolador

Código: [Seleccionar]
//SSPADD= (Fosc/(4*Clock))-1

#include <p18f4610.h>

#include <delays.h> //Libreria para los retardos
#include <stdlib.h> //Libreria para conversiones a string
#include <stdio.h>
#include <sw_uart.h>
#include <string.h>
#include <math.h>
#include <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

void ByteWriteI2C(unsigned char ByteControl,unsigned char HighDireccion,unsigned char LowDireccion,unsigned char DataI2C);
unsigned char ByteReadI2C(unsigned char ByteControl,unsigned char HighDireccion,unsigned char LowDireccion);

void main(void)
{
ADCON1=15;
    OpenUART(); //Habilita los puerto de comunicación serial por software
ds1302_init(); //Inicializa el reloj ds1302 para su funcionamiento
OpenI2C(MASTER,SLEW_OFF);
SSPADD=49;
}

void ByteWriteI2C(unsigned char ByteControl,unsigned char HighDireccion,unsigned char LowDireccion,unsigned char DataI2C)
{
IdleI2C();
StartI2C();
while(SSPCON2bits.SEN);
WriteI2C(ByteControl);
WriteI2C(HighDireccion);
WriteI2C(LowDireccion);
WriteI2C(DataI2C);
StopI2C();
while(SSPCON2bits.PEN);
while(EEAckPolling(ByteControl));
}

unsigned char ByteReadI2C(unsigned char ByteControl,unsigned char HighDireccion,unsigned char LowDireccion)
{
unsigned char Valor;

IdleI2C();
StartI2C();
while(SSPCON2bits.SEN);
WriteI2C(ByteControl);
WriteI2C(HighDireccion);
WriteI2C(LowDireccion);
RestartI2C();
while(SSPCON2bits.RSEN);
WriteI2C(ByteControl | 0x01);
Valor=ReadI2C();
NotAckI2C();
while(SSPCON2bits.ACKEN);
StopI2C();
while(SSPCON2bits.PEN);
return (Valor);
}
Título: Re: Problema con I2C en C18
Publicado por: migsantiago en 18 de Octubre de 2010, 13:16:33
Palomino, procura publicar mensajes en hilos que ya tengas abiertos. No abras hilos nuevos a menos que traten de un tema diferente.

Por ahora sigue tu tema en este mismo hilo. El otro quedará cerrado.

Gracias y suerte con tu I2C.
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 18 de Octubre de 2010, 13:19:47
Ok disculpa
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 18 de Octubre de 2010, 14:31:33
Se me traba al momento de entrar a la funcion ByteWriteI2C


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

#include <delays.h> //Libreria para los retardos
#include <stdlib.h> //Libreria para conversiones a string
#include <stdio.h>
#include <sw_uart.h>
#include <string.h>
#include <math.h>
#include <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;

void ByteWriteI2C(unsigned char ByteControl,unsigned char HighDireccion,unsigned char LowDireccion,unsigned char DataI2C);
unsigned char ByteReadI2C(unsigned char ByteControl,unsigned char HighDireccion,unsigned char LowDireccion);

void main(void)
{
ADCON1=15;
    OpenUART(); //Habilita los puerto de comunicación serial por software
// ds1302_init(); //Inicializa el reloj ds1302 para su funcionamiento
OpenI2C(MASTER,SLEW_OFF);
SSPADD=49;

Data=1;

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

ByteWriteI2C(0xA0,0x00,0x00,Data);
Delay1KTCYx(5);
//ByteReadI2C(0xA0,0x00,0x00);
Delay_ms(500);
WriteUART(0xFE);
WriteUART(0x01);
WriteLCD(" Prueba a Memoria 1",19);
}

void ByteWriteI2C(unsigned char ByteControl,unsigned char HighDireccion,unsigned char LowDireccion,unsigned char DataI2C)
{
IdleI2C();
StartI2C();
while(SSPCON2bits.SEN);
WriteI2C(ByteControl);
WriteI2C(HighDireccion);
WriteI2C(LowDireccion);
WriteI2C(DataI2C);
StopI2C();
while(SSPCON2bits.PEN);
while(EEAckPolling(ByteControl));
}

unsigned char ByteReadI2C(unsigned char ByteControl,unsigned char HighDireccion,unsigned char LowDireccion)
{
unsigned char Valor;

IdleI2C();
StartI2C();
while(SSPCON2bits.SEN);
WriteI2C(ByteControl);
WriteI2C(HighDireccion);
WriteI2C(LowDireccion);
RestartI2C();
while(SSPCON2bits.RSEN);
WriteI2C(ByteControl | 0x01);
Valor=ReadI2C();
NotAckI2C();
while(SSPCON2bits.ACKEN);
StopI2C();
while(SSPCON2bits.PEN);
return (Valor);
}
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 18 de Octubre de 2010, 16:27:12
Estoy haciendo algo mal?  :shock:
Título: Re: Problema con I2C en C18
Publicado por: gary_servin en 18 de Octubre de 2010, 21:04:57
y yo lo que hice fue solamente modificar de i2c.h lo siguiente:
Código: [Seleccionar]
#if defined (I2C_IO_V1 )
#define I2C_SCL TRISEbits.TRISE1
#define I2C_SDA TRISEbits.TRISE2
#endif

Según yo es lo unico que ocupo modificar... ya que al momento de simularlo en proteus me esta tomando los pines PORTD0 Y PORTD1 para tal comunicacion.....

No me queda muy claro para que quieres modificar los pines, y creo que es algo que no puedes hacer, ya que esos pines están asignados al modulo spi/i2c por hardware que posee el microcontrolador. Según tengo entendido a partir desde los pic24 recién se pueden cambiar las funciones de los pines así.
Saludos
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 18 de Octubre de 2010, 21:40:59
Según yo se..... los pines que vienen en las librerías de c18 son modificables....
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 18 de Octubre de 2010, 21:43:11
Aunque tambien he estado realizando la simulacion con los pines especificos para la comunicacion i2c y ni asi me funciona en proteus...

Saludos
Título: Re: Problema con I2C en C18
Publicado por: migsantiago en 18 de Octubre de 2010, 22:48:46
Según yo se..... los pines que vienen en las librerías de c18 son modificables....

Los pines I2C por hardware no son modificables. Sólo los pines I2C por software son modificables.

Leyendo rápido veo que usas I2C por hardware, por lo que lo que comenta Gary_servin puede ser la raíz del problema.

Cuando los pines son remapeables, en el dibujo del PIC aparece RPn en negritas.
Título: Re: Problema con I2C en C18
Publicado por: gary_servin en 18 de Octubre de 2010, 22:50:57
Claro, los pines los puedes "modificar" en la librería, pero no les puedes asignar a estos las funciones que no figuren en el datasheet, a no ser que emules una comunicación i2c por software.

Si te fijas en los archivos que trae el c18 para manejar el modulo i2c, como por ejemplo el i2c_read.c, el compilador no trabaja con los pines en casi ningún momento, sino con los registros asociados al modulo, y por ende con los pines asignados al modulo i2c que en tu caso son TRISCbits.TRISC3 TRISCbits.TRISC4.
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 19 de Octubre de 2010, 12:46:33
Ok, bueno debido a las necesidades que tengo voy a tener que realizarlo por software... Gracias por sacarme de dudas a ambos; voy a tratar de realizarlo pero me seria de utilidad si alguien por aquí tuviera algún ejemplo del protocolo i2c por software.

Saludos
Título: Re: Problema con I2C en C18
Publicado por: migsantiago en 19 de Octubre de 2010, 14:45:06
Ok, bueno debido a las necesidades que tengo voy a tener que realizarlo por software... Gracias por sacarme de dudas a ambos; voy a tratar de realizarlo pero me seria de utilidad si alguien por aquí tuviera algún ejemplo del protocolo i2c por software.

Saludos

En este mismo subforo Suky ha hablado del I2C por software en C18. Dale una buscada.
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 19 de Octubre de 2010, 14:52:17
Ok. Gracias. Lo busco de inmediato

Saludos
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 19 de Octubre de 2010, 16:04:12
No logro encontrar el hilo, seguiré buscando si alguien se sabe el nombre le agradecería que me lo dijera por aquí

Saludos  :mrgreen:
Título: Re: Problema con I2C en C18
Publicado por: migsantiago 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.
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 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
Título: Re: Problema con I2C en C18
Publicado por: Suky 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!
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 en 19 de Octubre de 2010, 19:47:21
Jajajajaja :D :D  Ojala permitieran bebidas alcoholicas en el trabajo jejeje... seria la onda 8)
Título: Problema con I2C en C18
Publicado por: Palomino86 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....
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 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
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 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...
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 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... :(
Título: Re: Problema con I2C en C18
Publicado por: Palomino86 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.... :?

Título: Re: Problema con I2C en C18
Publicado por: Palomino86 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.... :(