TODOPIC
Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado 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
-
Estimado colega puedes mostrar el esquematico que estas usando para ver si tienes algo malo en particular y asi ayudarte entrre todos.
Saludos.
-
Gracias Astrocar.
Os adjunto el esquema.
Un saludo.
-
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
-
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:
-
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