Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
hola a 😮 a todos los interesados del protocolo I2C.
soy nuevo en el foro, mi nick es wallen. No encuentro donde tengo que pinchar para enviar un nuevo mensaje, así que respondo a este en este foro I2C
Si hay algún genio del I2C al otro lado del foro espero que me ayude:
Esoty trabajando mucho sobre 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.
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) y algunas explicaciones al respecto
Mi problema se presenta cuando quiero establecer comunicacion entre tres microcontroladores pic 16f876, un Master y dos Slaves pic 16f876.
El programa es muy simple, el Master lee de un Slave (SLAVE TRANSMITE un byte) su puerto B y el byte obtenido lo manda por el BUS al Slave (SLAVE RECIBE el byte del BUS) y escribe el resultado por 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, ADRESS, ACK , DATO, ACK, ....., pero a la hora de cambiar de direccíon ...puf se jode todo, perdemos el I2C y no se porqué.
Aqui adjunto las rutinas que funcionan, pero de momento solo MASTER y un Slave (usando dos microcontroladores PIC16F876)
;*******************************************************************
;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
hay un link muy bueno en alemán sobre el protocolo I2C:
http://www.sprut.de/electronic/pic/grund/i2c.htm#pic
Las direcciones empleadas para ambos Slaves son:
Slave ESCRITURA: b'01111000'
Slave LECTURA: b'01111100'
Para programar el Slave bajarse el programa del siguiente enlace
Alejandro Alonso Puig - mundobot.com, utliza un interrupt Handler muy bueno para I2C
No se que te puede pasar, consulta la duda en foros de pics, estos dos son bastante buenos.
http://www.demo-1.com.ar/foros/
es un foro dedicados a pics y demas cosas, y suelen responder.. otra opcion son los foros de microchip que los lee bastante gente en ingles
Para dudas sobre pics yo usaria estos foros.
hola soy wallen de nuevo.
Si no quedó claro el problema se presenta a la hora de montar 3 micros pic 16f876. Un Master pic16f876 y dos Slaves pic16f876.
Por definción el Master inicia y finaliza la señal de reloj, direcciona esclavos pero en una rutina puede ser el RECEPTOR o el TRANSMISOR, esto hay que tenerlo muy claro
Para probar las rutinas de escritua y lectura he utlizado el potente simulador Proteus.
suerte a todosss
Hola,
Un MASTER a parte de iniciar la señal de reloj SIEMPRE inicia la transmisión (es decir es el primero en enviar algo), luego dependiendo del protocolo que utilices (el que va por encima del I2C) esperará respuesta o no de los SLAVES.
Un SLAVE nunca inica una comunicación por eso hay que hacer alguna forma que el MASTER se entere que un SLAVE quiere decir algo (generalmente se utiliza la línea de interrupción externa), entonces el MASTER pregunta y el SLAVE responde.
Si tienes varios slaves en una misma línea I2C (normalmente será así), puedes realizar varios métodos:
1.- El MASTER va preguntando uno a uno rotativamente a los SLAVES y estos responden. (Mucho consumo).
2.- Cada uno de los SLAVES tiene una línea de interrupción por lo que el MASTER sabe a quien preguntar (Utiliza muchos pins de entrada).
3.- Todos los SLAVES estan conectados a una misma línea de interrupción con lo cual el MASTER solo preguntará uno a uno a los SLAVES si esta línea esta activada.
S2
Ranganok Schahzaman
Hola,
Lo que has escrito es correcto pero no soluciona mi problema. Esos conceptos los he puesto en práctica con la comunicacion de un microcontrolador pic16f876 y otros dispositivos como eeprom, PCF8574, otro micro 16f876...
El problema aparece cuando el Master intenta comunicarse con el segundo Slave (micro pic16f876). Es decir, esto no me pasa con PCF8574...las rutinas están correctas de lectura y escritura. Pero a la hora de trabajar solamente con pic seguramente hay que tener en cuenta algo especial.
La idea de probar en páginas de microcontroladores es buena idea. Lo seguiremos intentado
saludos,
wallen74, los PCF8574 estan programados para que respondan automáticamente como slaves.
Para los PICs tienes que hacer tu la rutina de respuesta. Como dices que has conseguido comunicar 1 pic con otro, pasanos el código y miramos que puede estar pasando.
S2
Ranganok Schahzaman
Hola,
Vale te paso los códigos de ensamblador de los programas para comunicar
un Master y un Slave (tanto el Master como transmisor o como receptor).
También el código del programa que no me funciona, es decir un Master y
dos Slaves...
No tengo claro como adjuntar cada uno de los .asm, así que dejame tu
dirección de e-mail y luego si quieres los publicas.
saludos,