TODOPIC

Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: guancho2002 en 28 de Mayo de 2008, 11:38:27

Título: Comunicación con el I2C entre micros.
Publicado por: guancho2002 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
Título: Re: Comunicación con el I2C entre micros.
Publicado por: ASTROCAR 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.
Título: Re: Comunicación con el I2C entre micros.
Publicado por: guancho2002 en 30 de Mayo de 2008, 11:53:11
Gracias Astrocar.
Os adjunto el esquema.
Un saludo.
Título: Re: Comunicación con el I2C entre micros.
Publicado por: navaismo 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
Título: Re: Comunicación con el I2C entre micros.
Publicado por: RedPic 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:
Título: Re: Comunicación con el I2C entre micros.
Publicado por: guancho2002 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