Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
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. 😆
Hola Mosvack
Aquí te anexos las rutinas de programa del Pic Esclavo y el Maestro
///////////////////////////////////////////////////////////////////////////////
// Rutina de Envío de Datos al PIC16F877 configurado como Maestro
///////////////////////////////////////////////////////////////////////////////
else{ // Envía el dato del registro valor al PIC Maestro
#asm
movf captura,0
movwf sspbuf
#endasm
while(!bit_test(sspstat,0)); // Así esperamos a que se haya enviado...
bit_clear(pir1,3); // para mandar el siguiente byte.
#asm // Rutina de prueba
movf Prueba,0 // Rutina de prueba
movwf sspbuf // Rutina de prueba
#endasm // Rutina de prueba
delay_us(10);
bit_set(sspcon1,4); // Desbloqueo de reloj... Bit CKP activa el reloj
while(!bit_test(pir1,3));
bit_clear(pir1,3);
output_bit(PIN_E2,1); // se utilizaba el pin A5
}
bit_set(sspcon1,4); // <-No funciona con la transferencia.sí con la recepción
if(bit_test(sspcon1,4)) output_bit(PIN_C0,1);
while(!bit_test(sspstat,4)); // En transmisión al maestro..bloquea al esclavo
}
///////////////////////////////////////////////////////////////////////////////
// Rutina de petición de Dato vía I2C del PIC Esclavo
///////////////////////////////////////////////////////////////////////////////
i2c_start();
i2c_write(DIREC + 1); // Dirección con bit de lectura (1)
valor = i2c_read(0); // 1er Dato recibido del esclavo
Canal0 = i2c_read(0); // 2do Dato recibido del esclavo (ojo)
i2c_stop();
delay_ms(1); // Retardo para no enviar varias peticiones 1ms
output_b(valor); // Se envía el dato recibido del esclavo al PuertoB
Hola Rick_rs
Ya lo has probado?. ¿Sigue igual?... Voy a hacerte una serie de observaciones sobre el programa:
*) La dirección de memoria creo que la fijé en 0xA0. En realidad, tal y como está montado el programa, esta dirección no es tan arbitraria como parece. Tiene que cumplir una condición, y es que el último bit de la misma sea cero, para que al sumarle un 1 no cambien los 7 bits superiores... de esa forma con una simple suma a la dirección, se puede establecer la lectura (+1) o la escritura (+0).
*) Los retardos que coloqué en el programa (creo que del maestro), los puse para impedir que al pulsar el botón que activaba el pin, se mandasen varias peticiones I2C y se produjese algún error de desbordamiento. Por eso puse unos retardos grandes de 1 segundo o así, superiores al tiempo que tardo en pulsar el botón.
*) En teoría, BF debería pasar a cero cuando el SSPBUF está vacío. Por tanto, es el mejor momento para cargar el SSPBUF con otro dato( "Prueba" en tu programa). ¿Sigue pasando lo mismo? ¿Se sigue quedando a la espera?. Debes eliminar el signo "!" de: while(!bit_test(sspstat,0)); para que espere mientras sea "1" y no mientras sea "0"... ya que este bit (BF) está a 1 indicando Buffer Full, y nos interesa esperar hasta que se ponga a cero, momento en el que cargaremos el SSPBUF con el siguiente dato.
Ya me contarás qué tal te ha ido...
Saludos
Hola Mosvack
Logre leer 5 bytes del PIC esclavo en la comunicación I2C, pero lo realice utilizando un contador en la rutina del PIC esclavo, y en el pic Maestro tuve que mandar a leer el esclavo cinco veces, esa fue la manera que encontre para obtener lo que necesitaba...
El programa del esclavo quedo de la manera siguiente:
///////////////////////////////////////////////////////////////////////////////
// Rutina de Envío de Datos al PIC16F877 configurado como Maestro
///////////////////////////////////////////////////////////////////////////////
else{
contador++; // Se incrementa el contador
if (contador == 1)
{
i2c_write(captura);
}
else if (contador == 2)
{
i2c_write(Canal_0);
}
else if (contador == 3)
{
i2c_write(Canal_1);
}
else if (contador == 4)
{
i2c_write(Canal_2);
}
else if (contador == 5)
{
i2c_write(Canal_3);
contador = 0;
}
y en el Maestro:
///////////////////////////////////////////////////////////////////////////////
// Rutina de petición de Dato vía I2C del PIC Esclavo
///////////////////////////////////////////////////////////////////////////////
i2c_start();
i2c_write(DIREC + 1); // Dirección con bit de lectura (1)
valor = i2c_read(0); // 1er Dato recibido del esclavo
i2c_stop();
i2c_start();
i2c_write(DIREC + 1);
Canal0 = i2c_read(0); // 2do Dato recibido del esclavo
i2c_stop();
i2c_start();
i2c_write(DIREC + 1);
Canal1 = i2c_read(0); // 3er Dato recibido del esclavo
i2c_stop();
i2c_start();
i2c_write(DIREC + 1);
Canal2 = i2c_read(0); // 4to Dato recibido del esclavo
i2c_stop();
i2c_start();
i2c_write(DIREC + 1);
Canal3 = i2c_read(0); // 5to Dato recibido del esclavo
i2c_stop();
delay_ms(1); // Retardo para no enviar varias peticiones 1ms
output_b(valor); // Se envía el dato recibido del esclavo al PuertoB
Así fue que logre cuadrar la rutina, no encontre de otra manera... Gracias por la ayuda suministada Mosvack!!! estamos en contacto... Saludos desde venezuela!!! 😛
Es una buena opción. Has dividido la transferencia en pequeñas transferencias de 1 byte 🙂
Si así es Mosvack, no me quedo de otra... 😀