hola,
Si hay algún genio del I2C al otro lado del foro espero que me ayude:
Estoy realizando un proyecto con el I2C y he conseguido comunicar perfectamente un master y un slave. Es decir, el Master TRANSMITE y el Slave RECIBE.......o bien el Master RECIBE y el Slave TRANSMITE. Tambien un Master con dos expansores PCF8574, y también un Master y una EEPROM 24LC256 y un PCF8574. Los micros utilizados son pic16f876
De momento los programas están en ensamblador (.asm). Aqui os dejo las rutinas de enviar_I2C y recibir_I2C (funcionan a la perfección)
Mi problema se presenta cuando quiero establecer comunicacion entre tres microcontroladores pic 16f876, un Master y dos Slaves.
El programa es muy simple, el Master lee de un Slave1 (SLAVE TRANSMITE) su puerto B y el byte obtenido lo manda por el BUS al Slave2 (SLAVE RECIBE el byte del BUS) y escribe el resultado en el puerto B.
Después de la primera rutina de lectura (que funciona correctamente mas que probada) el Master al pasar por la rutina de escritura pierde definitivamente el control del BUS. El problema debe estar en la trama serie START, 1º ADDRESS, ACK, DATA, ACK, RESTART, 2º ADDRESS, ACK, DATA, ACK, ......en el cambio a la 2º ADDRESS se produce el error y el Master pierde definitivamente el control del BUS.
Aqui adjunto las rutinas que funcionan,
;**********************************************************************
;***SUBRUTINA PARA TRANSMITIR DATOS1 EN MODO MASTER DEL I2C
Envia_i2c
BCF STATUS,RP0 ; Restore Bank0 ................DEN BUS ÜBERNEHMEN
BCF PIR1,SSPIF ; Clear the interrupt flag before RX
BSF STATUS,RP0 ; SSPCON2: is in 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 ; Clear the interrupt flag before RX
MOVF DIREC,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
BSF STATUS,RP0 ; Restore Bank1................DEN BUS WIEDER FREIGEBEN
BCF STATUS,RP1
BSF SSPCON2,PEN ; Envia bit de stop
BCF STATUS,RP0 ; Restore Bank0
BTFSS PIR1,SSPIF ; STOP finalizado?
GOTO $-1 ; no espera
BCF PIR1,SSPIF
RETURN
;************************************************************************
;SUBRUTINA PARA RECIBIR DATOS1 EN MODO MASTER DEL I2C
;************************************************************************
Recibe_i2c
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
BSF STATUS,RP0 ; Restore Bank1...........DEN BUS WIEDER FREIGEBEN
BCF STATUS,RP1
BSF SSPCON2,PEN ; Envia bit de stop
BCF STATUS,RP0 ; Restore Bank0
BTFSS PIR1,SSPIF ; STOP finalizado?
GOTO $-1 ; no espera
BCF PIR1,SSPIF
RETURN
Las direcciones empleadas para ambos Slaves son:
Slave ESCRITURA: b'01111000'
Slave LECTURA: b'01111100'
Espero que alguien me pueda ayudar,
saludos...