fbpx

Expresate

Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:

I2C para PIC16F877
 
Avisos
Vaciar todo

I2C para PIC16F877

31 Respuestas
8 Usuarios
0 Reactions
22.3 K Visitas
rick_rs
Respuestas: 24
Topic starter
(@rick_rs)
Eminent Member
Registrado: hace 18 años

Estoy tratando de comunicar dos PIC16F877 via I2C, utilizando lenguaje C para PIC (PICC), y hasta ahora no lo he logrado. 😕 no encuentro la manera que el PIC maestro se enlace con el PIC esclavo, necesito algún tipo de información, tutorial o enlace de alguna página que pueda ayudarme por favor. 😆

Responder
30 respuestas
mosvack
Respuestas: 126
(@mosvack)
Estimable Member
Registrado: hace 19 años

Hola Rick_rs

Es posible que se produzca una colisión a la salida del PIC esclavo. Ocurre esto cuando se mandan los bytes al SSPBUF antes de que hayan sido enviados. Quizá deberíamos modificar el programa anterior comprobando que SSPBUF en el esclavo está vacío antes de mandar el siguiente byte y a continuación, liberar la línea de reloj.

Coloca justo después de: // Efectuado primer envío.. del programa anterior una comprobación y espera de puesta a 1 del bit 3 de pir1... algo como esto:

else{

#asm
movf captura,0
movwf sspbuf
#endasm

// Efectuado primer envío..

while(!bit_test(pir1,3)); // Así esperamos a que se haya enviado...
bit_clear(pir1,3); // para mandar el siguiente byte.

#asm
movf dato_2,0
movwf sspbuf
#endasm

//preparado segundo envío

bit_set(sspcon1,4); // Descongelando la línea de reloj

...

___

Espero que sea eso... suerte

Responder
rick_rs
Respuestas: 24
Topic starter
(@rick_rs)
Eminent Member
Registrado: hace 18 años

Hola Mosvack

Acabo de probar la rutina que me sugieres, y la comunicación I2C entre los PIC's se cuelga, no hacen nada... seguire probando y leyendo bien el protocolo I2C para ver si llego a darle en el blanco. Gracias por la colaboración prestada.. 🙂 aaahhh, cualquier idea será bienvenida...

Responder
mosvack
Respuestas: 126
(@mosvack)
Estimable Member
Registrado: hace 19 años

Hola Rick

Lo que suele hacer que se cuelgue la comunicación es la congelación de la señal de reloj. Si el esclavo congela esta señal a la espera de un evento y éste no llega nunca, la comunicación I2C queda bloqueada; el maestro a la espera de que se desbloquee la línea y el esclavo a la espera del evento apropiado q ya depende del programa. La congelación de la línea es necesaria para asegurarte que se sincronicen bien tanto maestro como esclavo... Imagina que el maestro tuviese que leer varios bytes del esclavo. Según el programa que te copié aquí, las lecturas del esclavo se ejecutarían secuencialmente, sin esperar, una tras otra, y es posible que al esclavo no le diese tiempo a mover los bytes nuevos al registro SSPBUF para su transmisión antes de la próxima petición del maestro. Por ello, el esclavo debe congelar la línea y cargar el registro SSPBUF para luego descongelar la línea.

Esto es lo que hemos hecho en el programa del esclavo. Intuyo que lo que ocurre es que el esclavo se queda esperando indefinidamente a que el bit 3 del registro PIR1 se ponga a 1. Puedes comprobar si lo que ha ocurrido es que la línea de reloj está congelada midiendo su estado con un voltímetro. Si da aprox. cero voltios con respecto a masa, es que el esclavo ha congelado la línea. En ese caso, si desconectas la línea de reloj del extremo del esclavo, el maestro debería desbloquearse, al poder generar los pulsos de reloj, (aunque no leería nada), y el esclavo debería seguir bloqueado. Quizá habría que probar con otro bit que fuese más indicativo de que se ha efectuado el envío, como el BF, o una combinación de bits.

Saludos

Responder
mosvack
Respuestas: 126
(@mosvack)
Estimable Member
Registrado: hace 19 años

Para probar con el bit BF sustituye:

#endasm

// Efectuado primer envío..

while(!bit_test(pir1,3)); // Así esperamos a que se haya enviado...
bit_clear(pir1,3); // para mandar el siguiente byte.

______

por:

#endasm

// Efectuado primer envío..

while(bit_test(sspstat,0)); // Así esperamos a que se haya enviado...
bit_clear(pir1,3); // para mandar el siguiente byte.

____

Y recuerda también que cuando envíes el último byte, debes descongelar la línea de reloj (a pesar de que no vayas a enviar más bytes). Si no lo haces el esclavo no podrá recibir el pulso de STOP.

Saludos

Responder
rick_rs
Respuestas: 24
Topic starter
(@rick_rs)
Eminent Member
Registrado: hace 18 años

Hola Mosvack

Efectivamente eso es lo que esta pasando en la rutina de programa del PIC esclavo, realice la prueba sugerida y lo corrobore, ahorita sigo haciendo pruebas a ver que es lo que esta pasando con esa transferencia del PIC esclavo, me estoy guíando por el diagrama de tiempo de la secuencia de transferencia de datos del PIC esclavo en transmisión, la cual te anexo para ver que puedes observar allí... Gracias por la ayuda!!! 🙂

Responder
Página 3 / 7
Compartir: