Autor Tema: Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)  (Leído 4390 veces)

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

Desconectado wallen74

  • PIC10
  • *
  • Mensajes: 6
Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)
« en: 11 de Noviembre de 2006, 09:38:26 »
Mensaje dirigido a Artifox o cualquiera que pueda y quiera ayudarme...


Hola Artifox,

he encontrado este mensaje tuyo en el foro...llevo buscando semanas en varios foros a alguien que domine realmente el I2C
para que pueda resolverme un problema que tengo a la hora comunicar tres micro pic 16f876 vía I2C.


Tu emensaje:

"Hola, yo he hecho lo que necesitas conectar un pic maestro y varios pic's esclavos. El codigo lo hice en PBP utlilizando las interrupciones por assembler. Dejame buscarlas y en la noche te las pongo, pues ahorita estoy en el trabajo.

Un abrazo.

Por cierto use un 16F877 y dos 16F876"

Si realmente has conseguido lo que escribes, te agradecería mucho que me ayudaras. Te explico;

Las rutinas de lectura y escritura que utilizo son correctas dado que he conseguido establecer comunicacion entre un Master pic 16f876 y un Slave pic16f876, tanto transmision como recepción. También he conseguido comunicar un Master pic 16f876 con dos expansores PCF8574 y un Master pic 16f876 con una EEPROM 24LC256 y un PCF8574.


Mi problema se presenta cuando quiero establecer comunicacion entre tres microcontroladores pic 16f876, un Master y dos Slaves pic 16f876.

Después de la primera rutina de lectura, es decir el Master lee el byte del Slave1, pasamos a la rutina de escritura donde el Master transmite el byte recibido por la línea del bus al Slave2, con diferente Address.
El Master lee correctamente del primer Slave el byte pero en cuanto cambia de dirección para transmitir el byte al segundo Slave pierde automáticamente el control del bus para siempre. El problema puede estar en el protocolo utilizado; bit de START, 1º ADRESS, ACK , DATO, ACK, RESTART, 2º ADDRESS, ACK, DATO, ....

La verdad ya no se que hacer....

te adjunto los programas en ensamblador (.asm) del Master y los 2 Slaves

Gracias de antemano,
Master:

;Definición de constantes

#define ClockValue d'9' ;(100khz) valor para cálculo de vel. I2C que pasará a SSPADD

;Definición de variables

cblock 0x20
MensajeIn ;Contendrá el dato recibido por I2C del slave
MensajeOut ;Contendrá el dato a enviar por I2C al slave
DirSlave ;Dirección del Slave
BkStatus ;Backup del registro STATUS
BkW ;Backup W
BDel0 ;Usada en retardos. Usada por subr "HacerTiempo"
BDel1 ;Usada en retardos. Usada por subr "HacerTiempo"
BDel2 ;Usada en retardos. Usada por subr "HacerTiempo"
Pausa ;Pausa en centesima de sg. Usada por subr "HacerTiempo"
PDel0
PDel1
PDel2
Dato

endc ;Fin de definiciones


org 0
goto INICIO
org 4

;-------------------------------------------------------------------------------


INICIO ;Inicio del cuerpo del programa

banksel TRISD ;Apunta a banco 1
movlw b'00000000' ;Salida (Leds)
movwf TRISD ;
MOVLW b'11101111'
MOVWF OPTION_REG
MOVLW b'00000110'
MOVWF ADCON1

banksel PORTD ;Apunta a banco 0
clrf PORTD
call init_i2c_Master ;Configuración para uso de i2c

clrf MensajeIn
clrf MensajeOut

movlw d'10' ;Pausa de 10 centésimas de segundo para que en...
movwf Pausa ;...el arranque de tiempo a los slaves a quedar...
call HacerTiempo ;..configurados adecuadamente.


MLoop

;PETICION DE UN BYTE DE DATOS AL SLAVE
;Se ha de la dirección del Slave en "DirSlave". Tras esto solo hay que llamar
;a la subrutina "Recibir" y se obtendrá el dato en "MensajeIn"
movlw b'01111000' ;Establece dirección de solicitud..
movwf DirSlave ;..es decir, dirección del slave
call Recibir ;Toma dato del Slave...
movf MensajeIn,W ;... a través de "MensajeIn"...
movwf PORTD ;...y lo muestra por PORTB (Leds)

CALL PDelay

MOVLW b'11111111' ; encendemos todos los bombillos
MOVWF Dato
MOVLW b'01111100'
MOVWF DirSlave
CALL Enviar

CALL PDelay

MOVLW b'10101010' ; alternamos el encendido
MOVWF Dato
MOVLW b'01111100'
MOVWF DirSlave
CALL Enviar

CALL PDelay

goto MLoop

;---------------------------------------------------------------------------------
;SUBRUTINA PARA RETARDO DE 4 SEGUNDO

PDelay movlw .62 ; 1 set number of repetitions (C)
movwf PDel0 ; 1 |
PLoop0 movlw .63 ; 1 set number of repetitions (B)
movwf PDel1 ; 1 |
PLoop1 movlw .255 ; 1 set number of repetitions (A)
movwf PDel2 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
decfsz PDel2, 1 ; 1 + (1) is the time over? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) is the time over? (B)
goto PLoop1 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) is the time over? (C)
goto PLoop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 cycles delay
PDelL2 clrwdt ; 1 cycle delay
return ; 2+2 Done



;-------------------------------------------------------------------------------
init_i2c_Master ;Inicializa valores para uso de I2C en Master
;Ha de ser llamado tras definir TRISC y un valor para
;ClockValue. Para frecuencia SCL=Fosc/(4x(ClockValue+1))
;-------------------------------------------------------------------------------

;Guardamos copia de algunos registros
movwf BkW ;Hace copia de W
movf STATUS,W ;Hace copia de registro de estado
banksel PORTA
movwf BkStatus

;Configuramos I2C
banksel TRISC ; Pasamos a direccionar Banco 1
movlw b'00011000' ; Establece líneas SDA y SCL como entradas...
iorwf TRISC,f ;..respetando los valores para otras líneas.
movlw ClockValue ; Establece velocidad I2C segun...
movwf SSPADD ; ...valor de ClockValue
bcf SSPSTAT,6 ; Establece I2C input levels
bcf SSPSTAT,7 ; Habilita slew rate
banksel SSPCON ; Pasamos a direccionar Banco 0
movlw b'00111000' ; Master mode, SSP enable, velocidad segun...
movwf SSPCON ; ... Fosc/(4x(SSPADD+1))
bcf PIR1,SSPIF ; Limpia flag de eventos SSP
bcf PIR1,7 ; Limpia bit. Mandatorio por Datasheet

;Restauramos las copias de los registros
movf BkStatus,W ;Restaura las copias de registros
movwf STATUS ;registro de estado
movf BkW,W ;registro W

return


;---------------------------------------------------------------------------------------
HacerTiempo ;realiza una pausa del numero de centesimas de segundo especificadas en "Pausa"
;---------------------------------------------------------------------------------------

movf Pausa,W ;Coloca el valor de pausa en BDel2...
movwf BDel2 ;...para no alterar su contenido

;............................................................
; Generado con PDEL ver SP r 1.0 el 24/02/03 Hs 18:31:22
; Descripcion: Delay 10000 ciclos (1 centésima de segundo)
;............................................................
BCiclo movlw .8 ; 1 set numero de repeticion (B)
movwf BDel0 ; 1 |
BLoop1 movlw .249 ; 1 set numero de repeticion (A)
movwf BDel1 ; 1 |
BLoop2 nop ; 1 nop
nop ; 1 ciclo delay
decfsz BDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto BLoop2 ; 2 no, loop
decfsz BDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto BLoop1 ; 2 no, loop
BDelL1 goto BDelL2 ; 2 ciclos delay
BDelL2 nop ; 1 ciclo delay
;............................................................
decfsz BDel2,F ;Repite tantas veces el ciclo de una decima de segundo...
goto BCiclo ;..como se lo indique ADel2
return ; 2+2 Fin.

;**********************************************************************
;SUBRUTINA PARA TRANSMITIR DATOS1 EN MODO MASTER DEL I2C
;**********************************************************************

Enviar

MOVF DirSlave,W ;...............................DIE ADRESSE SENDEN
MOVWF SSPBUF ; carga direccion
BTFSS PIR1,SSPIF ; ACK recibido?
GOTO $-1 ; no, espera
BCF PIR1,SSPIF ; Clear the interrupt flag before RX

MOVF Dato,W ; carga dato....................DIE DATEN SENDEN
MOVWF SSPBUF
BTFSS PIR1,SSPIF ; ACK recibido?
GOTO $-1 ; no espera
BCF PIR1,SSPIF

banksel SSPCON2
bsf SSPCON2,RSEN
I2C.Restart.Wait
btfsc SSPCON2,RSEN
GOTO I2C.Restart.Wait
BCF STATUS,RP0

RETURN

;************************************************************************
;SUBRUTINA PARA RECIBIR DATOS1 EN MODO MASTER DEL I2C
;************************************************************************

Recibir

BCF STATUS,RP0 ; Restore Bank0......... DEN BUS ÜBERNEHMEN
BCF PIR1,SSPIF
BSF STATUS,RP0 ; Restore Bank1
BCF STATUS,RP1

BSF SSPCON2,SEN ; envia bit START
BCF STATUS,RP0 ; Restore Bank0
BTFSS PIR1,SSPIF ; START finalizado?
GOTO $-1 ; no, espera
BCF PIR1,SSPIF

movf DirSlave,W ;Dirección esclavo
iorlw b'00000001' ;con orden de lectura

; MOVF DIREC,W ; ........................DIE ADRESSE SENDEN
MOVWF SSPBUF ; carga direccion
BTFSS PIR1,SSPIF ; ACK recibido?
GOTO $-1 ; no, espera
BCF PIR1,SSPIF

BSF STATUS,RP0 ; Restore Bank1
BCF STATUS,RP1

BSF SSPCON2,RCEN ; activa modo receptor....DATEN EMPFANG EINSCHALTEN
BCF STATUS,RP0 ; Restore Bank0

BTFSS PIR1,SSPIF ; ACK recibido?
GOTO $-1 ; no, espera
BCF PIR1,SSPIF
MOVF SSPBUF,W ; carga dato
MOVWF MensajeIn

; BSF STATUS,RP0 ; Restore Bank1...........EIN ANDERES BYTE SOLL GELESEN WERDEN
; BCF STATUS,RP1
; BSF SSPCON2,ACKEN ; Genera ACK
; BCF STATUS,RP0 ; Restore Bank0

banksel SSPCON2
bsf SSPCON2,RSEN
I2C.Restart.Wait
btfsc SSPCON2,RSEN
GOTO I2C.Restart.Wait
BCF STATUS,RP0

RETURN

END


Slave1 - TRANSMITE EL BYTE AL MASTER

;Definición de constantes

#define DirNodo b'01111000' ;Dirección I2C de este nodo

;Definición de variables

cblock 0x20
MensajeIn ;Contendrá el dato recibido por I2C del master
MensajeOut ;Contendrá el dato a enviar por I2C al master
BkStatus ;Backup del registro STATUS
BkW ;Backup W
Temp ;Variable Temporal usada para evaluación de eventos I2C
endc ;Fin de definiciones


org 0
goto INICIO
org 4

;-------------------------------------------------------------------------------
Interrupcion ;RUTINA DE INTERRUPCIÓN. Se ocupa de los eventos I2C
;-------------------------------------------------------------------------------

;Guardamos copia de algunos registros
movwf BkW ;Hace copia de W
movf STATUS,W ;Hace copia de registro de estado
banksel PORTA
movwf BkStatus


;Chequeamos si la interrupción es por evento I2C. En caso positivo llamamos
;a la rutina de proceso del evento
banksel PIR1
btfss PIR1,SSPIF ;Ha ocurrido un evento SSP? (I2C)
goto IntNoSSP ;No. entonces será por otra cosa. Saltamos.
call SSP_Handler ;Si. Procesamos el evento. Si se reciben ordenes, quedarán
;registradas en "MensajeIn". Se enviarán las ordenes
;guardadas en "MensajeOut".
banksel PIR1
bcf PIR1,SSPIF ;Limpiamos el flag
goto Rest

IntNoSSP ;Aquí se gestionan interrupciones que no son por SSP

;..........
; En caso de necesitarse, poner aquí la rutina de gestión de interrupciones
; que no sean por bus I2C
;..........


Rest ;Restauramos las copias de los registros
movf BkStatus,W ;Restaura las copias de registros
movwf STATUS ;registro de estado
movf BkW,W ;registro W

retfie


;-------------------------------------------------------------------------------




INICIO ;Inicio del cuerpo del programa

banksel TRISB ;Apunta a banco 1
movlw b'11111111' ;Salida (Leds)
movwf TRISB ;
banksel PORTB ;Apunta a banco 0
clrf PORTB ;Limpia puerto B

call init_i2c_Slave ;Configuración para uso de i2c
banksel INTCON
bsf INTCON,GIE ;Activamos las interrupciones

banksel MensajeIn
clrf MensajeIn
clrf MensajeOut


MLoop
movf PORTB,W ;dato cualquiera por I2C que metemos en
movwf MensajeOut ;"MensajeOut" para cuando el Master se lo pida
goto MLoop




;*********************************************************************************
; SUBRUTINAS
;*********************************************************************************

;-------------------------------------------------------------------------------
init_i2c_Slave ;Inicializa valores para uso de I2C en Slave
;Ha de ser llamado tras definir TRISC y un valor para
;ClockValue. Para frecuencia SCL=Fosc/(4x(ClockValue+1))
;-------------------------------------------------------------------------------

;Guardamos copia de algunos registros
movwf BkW ;Hace copia de W
movf STATUS,W ;Hace copia de registro de estado
banksel PORTA
movwf BkStatus

;Configuramos I2C
banksel TRISC ; Pasamos a direccionar Banco 1
movlw b'00011000' ; Establece líneas SDA y SCL como entradas...
iorwf TRISC,f ;..respetando los valores para otras líneas.
bcf SSPSTAT,CKE ; Establece I2C input levels
bcf SSPSTAT,SMP ; Habilita slew rate
bsf SSPCON2,GCEN ; Habilita direccionamiento global
movlw DirNodo ; Dirección esclavo
movwf SSPADD ;
banksel SSPCON ; Pasamos a direccionar Banco 0
movlw b'00110110' ; Slave mode, SSP enable, velocidad segun...
movwf SSPCON ; ... Fosc/(4x(SSPADD+1))
bcf PIR1,SSPIF ; Limpia flag de eventos SSP
bcf PIR1,7 ; Limpia bit. Mandatorio por Datasheet

;Configuración para interrupciones por evento I2C
banksel PIE1
bsf PIE1,SSPIE
bsf INTCON,PEIE

;Restauramos las copias de los registros
movf BkStatus,W ;Restaura las copias de registros
movwf STATUS ;registro de estado
movf BkW,W ;registro W

return


; --------------------------------------------------------------------------------------
SSP_Handler ; Este manejador controla cada evento SSP (I2C) acontecido.
; El código que se muestra abajo chequea 5 posibles estados.
; Cada uno de los 5 estados SSP son identificados haciendo
; XOR de los bits del registro SSPSTAT con mascaras de bits
; predeterminadas. Una vez que el estado ha sido identificado
; se llevan a cabo las acciones pertinentes. Los estados
; indefinidos son considerados como estados de error.

; State 1: Operación de escritura I2C, ultimo byte era de dirección.
; SSPSTAT bits: S = 1, D_A = 0, R_W = 0, BF = 1

; State 2: Operación de escritura I2C, ultimo byte era de datos.
; SSPSTAT bits: S = 1, D_A = 1, R_W = 0, BF = 1

; State 3: Operación de lectura I2C, ultimo byte era de dirección.
; SSPSTAT bits: S = 1, D_A = 0, R_W = 1, BF = 0

; State 4: Operación de lectura I2C, ultimo byte era de datos.
; SSPSTAT bits: S = 1, D_A = 1, R_W = 1, BF = 0

; State 5: Reset lógico del Slave I2C por NACK del master.
; SSPSTAT bits: S = 1, D_A = 1, R_W = 0, BF = 0

; --------------------------------------------------------------------------------------

banksel SSPSTAT
movf SSPSTAT,W ; Obtiene el valor de SSPSTAT
andlw b'00101101' ; elimina los bits no importantes SSPSTAT.
banksel Temp
movwf Temp ; para chequeo posterior.

State1: ; Operación de escritura, ultimo byte ha sido
movlw b'00001001' ; de dirección, el buffer está lleno.
banksel Temp
xorwf Temp,W ;
btfss STATUS,Z ; Estamos en el primer estado?
goto State2 ; No, checkeamos siguiente estado
call ReadI2C ; SI. Hacemos un read SSPBUF (para vaciar buffer).
; El Hardware se ocupa de mandar Ack
return

State2: ; Operación de escritura, ultimo byte ha sido
movlw b'00101001' ; de datos, el buffer está lleno.
banksel Temp
xorwf Temp,W
btfss STATUS,Z ; Estamos en el segundo estado?
goto State3 ; NO, checkeamos siguiente estado
call ReadI2C ; SI, Tomamos el byte del SSP.

;Aquí tenemos en W el valor del dato recibido
movwf MensajeIn
return

State3: ; Operación de lectura, ultimo byte ha sido
movlw b'00001100' ; de dirección, el buffer está vacío
banksel Temp
xorwf Temp,W
btfss STATUS,Z ; Estamos en el tercer estado?
goto State4 ; NO, checkeamos siguiente estado

;Aquí debemos poner en W el valor del dato a enviar (solicitado por el master)
movf MensajeOut,W

call WriteI2C ; SI, escribimos el byte en SSPBUF
return

State4: ; Operación de lectura, ultimo byte ha sido
movlw b'00101100' ; de datos, el buffer está vacío
banksel Temp
xorwf Temp,W
btfss STATUS,Z ; Estamos en el cuarto estado?
goto State5 ; NO, checkeamos siguiente estado

;Aquí debemos poner en W el valor del dato a enviar (solicitado por el master)

movf MensajeOut,W

call WriteI2C ; SI, escribimos el byte en SSPBUF
return

State5:
movlw b'00101000' ; Se ha recibido un NACK mientras se transmitían...
banksel Temp
xorwf Temp,W ; ..datos al master. Lo lógica del Slave..
btfss STATUS,Z ; ..se resetea en este caso. R_W = 0, D_A = 1
goto I2CErr ; y BF = 0
return ; Si no estamos en State5, entonces es
; que algo fue mal

I2CErr nop ; Algo fue mal
return


;---------------------------------------------------------------------
WriteI2C ;Usada por SSP_Handler para escribir datos en bus I2C
;---------------------------------------------------------------------

banksel SSPCON
movwf SSPBUF ; Escribe el dato en W
bsf SSPCON,CKP ; Libera el reloj
return

;---------------------------------------------------------------------
ReadI2C ;Usada por SSP_Handler para escribir datos en bus I2C
;---------------------------------------------------------------------

banksel SSPBUF
movf SSPBUF,W ; Toma el byte y lo guarda en W
return



END

Falta el programa del Slave 2, pero el mensaje excede de la longitud máxima permitida. Si te hace falta te lo envio...

Espero que puedas ayudarme....







 


Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)
« Respuesta #1 en: 11 de Noviembre de 2006, 18:16:46 »
m..... q raro q falle, podrias adjuntarlos como archivos zip o rar los 3 programas separados?
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado wallen74

  • PIC10
  • *
  • Mensajes: 6
Re: Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)
« Respuesta #2 en: 12 de Noviembre de 2006, 15:18:35 »
hola,

pienso lo mismo pero no se donde falla....

Para simplificar el problema te adjunto un proyecto de un Master que intenta leer de dos Slaves con direcciones distintas el puerto B. Inicialmente lee del primer Slave1 con direccion X llamando a la rutina call recibir. El dato lo recibe correctamente.

A continuación llamamos a la rutina call recibir2 para el segundo Slave e intenta leer el puerto B del segundo slave, es aqui donde el Master no recibe la confirmacion del slave ACK, despues de enviarle la direccion, y cancela la transferencia perdiendo el control del bus.


En este programa si solamente el Master lee cada Slave por separado (en programas independientes del Master), recibe el byte correctamente, luego las direcciones son correctas la rutina call recibe, el setup I2C ...son correctos.

Te envio en el .rar un pantallaso del Proteus para que lo veas mejor junto con los tres programas Master y dos Slaves...

Gracias de antemano,

Salu2






Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)
« Respuesta #3 en: 13 de Noviembre de 2006, 01:59:15 »
tio lo voy a leer, ya lo baje, har elo posible por ayudarte, pero tb ve bsucando mas alternativas, chau exitos!!! :-/
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado wallen74

  • PIC10
  • *
  • Mensajes: 6
Re: Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)
« Respuesta #4 en: 15 de Noviembre de 2006, 16:44:04 »
hola,


Supongo que estarás líado o simplemente está complicado el problema. Estoy bastante desmoralizado con este tema, tengo que entregar este proyecto y ya he consultado en 5 foros...pero nadie sabe responderme.

Si me aconsejas algún foro más experto o me recomiendas alguien que pueda ayudarme te lo agradecería

gracias,

Un saludo!

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)
« Respuesta #5 en: 15 de Noviembre de 2006, 16:48:42 »
hola wallen jejeje, estaba ocupado con mis prioridaes aca por peru, pero bueno estoy leyendo tu info, q raro q nadie mas haya posteado, bueno ten paciencia.  :mrgreen:
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado wallen74

  • PIC10
  • *
  • Mensajes: 6
Re: Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)
« Respuesta #6 en: 19 de Noviembre de 2006, 19:46:06 »
hola,

he conseguido acotar el problema. El problema se presenta cuando interviene algún Slave pic16f87x, es decir el mismo

proyecto utilizando dos PCF8574 (uno como entrada y otro como salida) funciona perfectamente. Pero en cuanto sustituyo

uno de los Slave PCF8574 por un pic16f876, el Master después de la primera rutina pierde el control del bus,


Seguro que tiene que ver con el Slave, estará atendiendo a la interrupción y se queda colgado y no envia el ACK....

bueno, te doy más pistas,

saludos

wallen74

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)
« Respuesta #7 en: 20 de Noviembre de 2006, 01:11:00 »
chevere tio, el programa lo estoy haciendo por partes, y me parece medio complejo, son bastantes detalle slo del I2c, saludos! :-/
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado wallen74

  • PIC10
  • *
  • Mensajes: 6
Re: Comunicacion I2C entre 1 Master (pic16f876) y 2 Slaves (pic16f876)
« Respuesta #8 en: 20 de Noviembre de 2006, 19:04:23 »
Gracias, espero que entre los dos podamos resolver el problema.

aqui estoy dandole vuelta después del curro-

He encontrado este texto: (puede estar en la direccion correcta)

Un caso un poco más complicado

Esto es todo cuando se trata de comunicaciones simples, pero debemos considerar una posible complicación: Cuando el dispositivo maestro está leyendo desde el esclavo, quien pone los datos en la línea SDA del bus es el dispositivo esclavo, y el maestro es el que controla el pulso de reloj. ¿Qué pasa si el esclavo no está listo para enviar un dato? Con dispositivos como una EEPROMs esto no sería problema, pero si el dispositivo esclavo es un microprocesador, que tiene otras tareas que realizar, pueden surgir inconvenientes.

Para atender la transacción, el microprocesador debe pasar a una rutina de interrupción, guardar sus registros de trabajo, determinar qué dirección desea leer el dispositivo maestro, obtener el dato y ponerlo en su registro de transmisión. Esto puede llevar varios microsegundos, lo que implica que el dispositivo maestro podría estar enviando pulsos de reloj ciegamente por la línea SCL sin que el dispositivo esclavo pueda responderle. El protocolo I2C ofrece una solución para esto: el esclavo puede mantener la línea SCL en bajo. A esto se le llama estiramiento del reloj. Cuando el esclavo recibe el comando de lectura lo primero que hace es poner la línea de reloj en bajo. Entonces sí, obtiene el dato solicitado, lo pone en el registro de transmisión, y recién entonces libera la línea de reloj, que pasará de inmediato a alto debido al nivel que aporta el resistor de polarización.

Desde el punto de vista del dispositivo maestro, éste tratará de enviar el primer pulso de reloj para la lectura de datos liberando la línea SCL para que pase a alto, pero antes de continuar comprobará que ésta realmente haya ido al nivel lógico 1. Si la línea SCL permanece en bajo, el dispositivo maestro interpreta que el esclavo la mantiene así y espera a que SCL vaya a alto antes de continuar. Por suerte, la mayoría de los puertos I2C de los microprocesadores manejan esto de manera automática.

Sin embargo, a veces el manejo de I2C en el dispositivo maestro no está implementado por circuito, sino que es un juego de subrutinas que maneja dos líneas de un puerto. Algunas implementaciones ignoran este estiramiento del reloj. Estas soluciones trabajarán bien con dispositivos tales como las EEPROM, pero no podrán intercambiar datos correctamente con microprocesadores esclavos que utilizan el estiramiento del pulso de reloj. Como resultado, se obtendrán datos erróneos.


gracias...



Salu2


 

anything