Autor Tema: Comunicación con el I2C entre micros.  (Leído 3761 veces)

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

Desconectado guancho2002

  • PIC16
  • ***
  • Mensajes: 113
Comunicación con el I2C entre micros.
« en: 28 de Mayo de 2008, 11:38:27 »
Hola de nuevo, recurro a vosotros porque ya no sé por donde tirar con este tema, le he echado un vistazo al datasheet, he buscado en el foro, en internet,... la cosa es que he intentado comunicar dos 16f877 entre ellos y no hay manera. La prueba que he intentado es un 16f877 con un pulsador y otro 16f877 con un led. Cuando le doy al pulsador, el otro micro debe encender el led pero no lo hace, ¿que estoy haciendo mal? Lo estoy haciendo con PBP y las instrucciones que utilizo son las de BUSOUT y BUSIN. :(

MASTER:

   Device 16F877
      XTAL = 4                  ' Set Xtal Frequency
       CONFIG HS_OSC , WDT_OFF , PWRTE_ON , BODEN_OFF , LVP_OFF , WRTE_ON , CP_OFF , DEBUG_OFF   
      DECLARE SDA_PIN=PORTC.4
      DECLARE SCL_PIN=PORTC.3
      DECLARE SLOW_BUS=0
      SYMBOL SW1=PORTA.0
      TRISA=%00000001
      DIM VAR1 as BYTE            
      DIM Address as WORD         
      DIM BUF as BYTE
      PORTA=0
      ALL_DIGITAL=TRUE

PRUEBA:
       DelayMS 25
      Button SW1,0,40,5,BUF,0,PRUEBA
      BSTART
      BUSOUT 0
      BUSOUT 0
      BUSOUT "1"
      BSTOP
   
GOTO PRUEBA      



ESCLAVO:

      Device 16F877
      XTAL = 4                  ' Set Xtal Frequency
       CONFIG HS_OSC , WDT_OFF , PWRTE_ON , BODEN_OFF , LVP_OFF , WRTE_ON , CP_OFF , DEBUG_OFF   
      DECLARE SDA_PIN=PORTC.4
      DECLARE SCL_PIN=PORTC.3
      DECLARE SLOW_BUS=0
      SYMBOL FLAG=PIR1.3
      SYMBOL SW1=PORTA.0
      SYMBOL BUFFER=SSPSTAT.0
      TRISC=%00011000
      TRISB=%00000000
      DIM VAR1 as BYTE            
      DIM Address as WORD         
      DIM BUF as BYTE
      PORTB=0
      ALL_DIGITAL=TRUE
      
      
PRUEBA:
       IF FLAG=1 THEN GOTO PPP
      GOTO PRUEBA
PPP:
      FLAG=0
      VAR1 = BUSIN 0 , 0
      IF VAR1="1" THEN TOGGLE PORTB.0
      GOTO PRUEBA

Desconectado ASTROCAR

  • PIC24F
  • *****
  • Mensajes: 666
Re: Comunicación con el I2C entre micros.
« Respuesta #1 en: 28 de Mayo de 2008, 19:11:55 »
Estimado colega puedes mostrar el esquematico que estas usando para ver si tienes algo malo en particular y asi ayudarte entrre todos.

Saludos.
EL APRENDER ES NADA; MEJOR ES COMPARTIR EL APRENDIZAJE

Desconectado guancho2002

  • PIC16
  • ***
  • Mensajes: 113
Re: Comunicación con el I2C entre micros.
« Respuesta #2 en: 30 de Mayo de 2008, 11:53:11 »
Gracias Astrocar.
Os adjunto el esquema.
Un saludo.

Desconectado navaismo

  • Jubilado Todopic
  • PIC24H
  • ****
  • Mensajes: 1973
Re: Comunicación con el I2C entre micros.
« Respuesta #3 en: 30 de Mayo de 2008, 12:41:25 »
Tiene que ser I2C? no puedes usar comunicacion serie?

Segun entiendo en la comunicacion I2C necesitas configurar los fuses del PIC ademas de usar el Hardware, como lo pretendes hacer es mas sencillo usando comunicacion serie por sotfware
"Mi tercer deseo, que otra cosa podría ser, poner un final a todo el sufrimiento, que sólo con mi propia extinción el planeta podrá ser aliviado. Pobre de mí, Si tuviera tres deseos hoy, la elección no sería dificil para mí, Sólo tres deseos serían suficientes, No tendría uso para más."

"He sido un hombre que busca y aun lo sigo siendo, pero ya no busco en las estrellas y en los libros, sino en las enseñanzas de mi sangre."

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5552
    • Picmania by Redraven
Re: Comunicación con el I2C entre micros.
« Respuesta #4 en: 30 de Mayo de 2008, 13:23:56 »

Os adjunto el esquema.


No se si tendrá que ver pero en tu programa declaras SDA y SCL como C.4 y C.3 y sin embargo en el esquema estas conectando C.5 y C.6. Y así lo veo difícil.  :mrgreen:
« Última modificación: 30 de Mayo de 2008, 13:27:15 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado guancho2002

  • PIC16
  • ***
  • Mensajes: 113
Re: Comunicación con el I2C entre micros.
« Respuesta #5 en: 02 de Junio de 2008, 12:03:50 »
Gracias por vuestra respuesta. Navaismo, lo de comunicarlo por I2C es por empezar a comprenderlo, a parte de que solamente se utiliza dos hilos y hay multitud de componentes que trabajan con este puerto.En cuanto a lo de Redpic, sin comentarios, yo alucino... estaban mal pero sigue sin funcionar.
Me he hecho con un programa en pbp y funciona pero hay algo que no entiendo, por ejemplo:

        I2CWrite SDA,SCL,$02,[127]   ' Write offset to slave

según dice SDA y SCL son los pines asignados para tal fin, $02 es la dirección del esclavo, 127 es el valor enviado, pero he intentado poner dos pic en el bus y cada uno con su asignación de dirección y en cuanto hago una llamada a uno, el bus I2C se queda como colgado y ya no responde el otro. Si lo reinicio y es ahora la llamada para el otro, responde pero ocurre lo mismo para el otro pic.
¿por que a veces se le indica la variable control y dirección y otras solo dirección? ¿el sabe interpretarlo así? He probado a poner la misma dirección a los dos pic y me responden sin problema. ¿que puede estar pasando?
En el esquema que adjunto podéis observar que el debug del I2C indica las dos primeras líneas cuando hacemos la consulta al pic con dirección 2, en el que no hay problema, y las dos últimas líneas que son las que genera cuando se le hace la llamada al pic con dirección 4. A partir de ahí, aunque haga la llamada al pic 2 ya me salen líneas como las últimas y no funciona.

MASTER:

DEFINE  I2C_HOLD        1

SCL     VAR     PORTC.3            ' Clock pin
SDA     VAR     PORTC.4            ' Data pin
SW1     VAR     PORTA.0
SW2     VAR     PORTA.1
SW3     VAR     PORTA.2
BUF     VAR BYTE
a       VAR BYTE

        ADCON1 = 7               ' Set PORTA and PORTE to digital

loop:
        Button SW1,0,40,5,BUF,0,loop1
        I2CWrite SDA,SCL,$02,[127]   ' Write offset to slave
        goto loop3
loop1:
        Button SW2,0,40,5,BUF,0,loop2
        I2CWrite SDA,SCL,$02,[128]   ' Write offset to slave
        goto loop3
loop2:
        Button SW3,0,40,5,BUF,0,loop
        I2CWrite SDA,SCL,$04,[200]   ' Write offset to slave
        PAUSE 500
        I2CREAD SDA,SCL,$02,[a]
loop3:
        Pause 200

        GoTo loop               ' Do it forever



        End

ESCLAVO 1:

' Define used register flags
SSPIF   VAR     PIR1.3          ' SSP (I2C) interrupt flag
BF      VAR     SSPSTAT.0       ' SSP (I2C) Buffer Full
R_W     VAR     SSPSTAT.2       ' SSP (I2C) Read/Write
D_A     VAR     SSPSTAT.5       ' SSP (I2C) Data/Address
CKP     VAR     SSPCON.4        ' SSP (I2C) SCK Release Control
SSPEN   VAR     SSPCON.5        ' SSP (I2C) Enable
SSPOV   VAR     SSPCON.6        ' SSP (I2C) Receive Overflow Indicator
WCOL    VAR     SSPCON.7        ' SSP (I2C) Write Collision Detect


' Define constants
I2Caddress CON   2            ' Make our address 2


' Allocate RAM
datain    VAR     BYTE         ' Data in
 

TRISB=%00000000

' Initialize ports and directions
        ADCON1 = $0e         ' PORTA.0 analog, rest PORTA and PORTE pins to digital

' Initialize I2C slave mode
        SSPADD = I2Caddress      ' Set our address
        SSPCON2 = 0          ' General call address disabled
        SSPCON = $36          ' Set to I2C slave with 7-bit address

        PORTB=0
        GoTo mainloop          ' Skip over subroutines



i2cslave:                  ' I2C slave subroutine
       
      SSPIF = 0            ' Clear interrupt flag
        IF R_W = 1 Then RETURN   ' Read data from us
        IF BF = 0 Then RETURN  ' Nothing in buffer so exit
        IF D_A = 1 Then i2cwr   ' Data for us (not address)
        IF SSPBUF != I2Caddress Then Salir   ' Clear the address from the buffer
   
        return


i2cwr:                     ' I2C write data to us
        datain = SSPBUF         ' Put data into array
        if DATAIN=127 then TOGGLE PORTB.0
        if DATAIN=128 then TOGGLE PORTB.3

        return

Salir       

        return       
       
mainloop:                  ' Main program loop
       
        IF SSPIF Then         ' Check for I2C interrupt flag
                GoSub i2cslave
        EndIF

        GoTo mainloop           ' Do it all forever


ESCLAVO 2:

' Alias pins
scl     VAR     PORTC.3         ' I2C clock input
sda     VAR     PORTC.4         ' I2C data input


' Define used register flags
SSPIF   VAR     PIR1.3          ' SSP (I2C) interrupt flag
BF      VAR     SSPSTAT.0       ' SSP (I2C) Buffer Full
R_W     VAR     SSPSTAT.2       ' SSP (I2C) Read/Write
D_A     VAR     SSPSTAT.5       ' SSP (I2C) Data/Address
CKP     VAR     SSPCON.4        ' SSP (I2C) SCK Release Control
SSPEN   VAR     SSPCON.5        ' SSP (I2C) Enable
SSPOV   VAR     SSPCON.6        ' SSP (I2C) Receive Overflow Indicator
WCOL    VAR     SSPCON.7        ' SSP (I2C) Write Collision Detect


' Define constants
I2Caddress CON   4            ' Make our address 4


' Allocate RAM
datain    VAR     BYTE         ' Data in
result  VAR     BYTE


TRISB=%00000000

' Initialize ports and directions
        ADCON1 = $0e         ' PORTA.0 analog, rest PORTA and PORTE pins to digital

' Initialize I2C slave mode
        SSPADD = I2Caddress      ' Set our address
        SSPCON2 = 0          ' General call address disabled
        SSPCON = $36          ' Set to I2C slave with 7-bit address

        PORTB=0
        GoTo mainloop          ' Skip over subroutines



i2cslave:                  ' I2C slave subroutine
      SSPIF = 0            ' Clear interrupt flag
        IF R_W = 1 Then return   ' Read data from us
        IF BF = 0 Then return  ' Nothing in buffer so exit
        IF D_A = 1 Then i2cwr   ' Data for us (not address)
        IF SSPBUF != I2Caddress Then return   ' Clear the address from the buffer   
        return


i2cwr:                     ' I2C write data to us
       
        datain = SSPBUF         ' Put data into array
        if DATAIN=200 then TOGGLE PORTB.0
             
        return

       
mainloop:                  ' Main program loop
       
        IF SSPIF Then gosub i2cslave
               
        GoTo mainloop           ' Do it all forever



 

anything