Conectar Dos PIC y una memoria I2C

Hola buenas tardes, como el titulo lo dice necesito conectar dos pics entre si, y que el maestro este conectado a una memoria I2C EEPROM, los pics deben ser 16F877. Esto lo debo hacer ya que el proyecto requiere de demasiados puertos, mas de los que dispone el 16F877 (por eso debo conectar los dos pics entre si) y una memoria porqe el programa es muy extenso.
Todo esto lo debo hacer ya que es requisito del proyecto trabajar con el 16F877.
Si alguien me puede dar una mano estare agradecido. ...
 
Es un juego de palabras, seran casi 400 palabras y tendras qe indicar un error en dichas palabras, el programa sera en basic con proton.
ok! si se proton :D,y ya se va entendiendo un poco mas, las palabras estaran en la memoria y el los pic haran el resto...y cual es tu duda?

la conexion puede ser desde usart(mas facil). y la memoria por i2c
 
"Dos Pic's y una memoria porque el programa es muy extenso"... con memorias I2C externas no es posible (teóricamente) incrementar la capacidad del micro.
Quiero creer que usarás dos PIC's como maestros del bus I2C y como esclavo a la memoria I2C, ¿cierto?
y que la memoria I2C sólo tendrá datos de esas palabras que mencionas
 
Cierto la memoria sera usada como esclavo, la parte de como conectar la memoria al pic la se, lo que no se como hacer es conectar los dos pics entre si, para que uno funcione de maestro y el otro realice la tarea (activar actuadores) ya que el segundo pic lo necesito por el hecho de que no me alcanzan los puertos del 16F877 para conectar todos los actuadores.
 
pues como te comento, un pic podrias dejarlo como "cerebro", y el segundo como dices los actuadores, y la comunicacion si no es precaria de forma serial asincrona por software (serin, serout), si es precaria, por hardware utilizando el modulo uart (HSerin, hserout). asi solo utilizas dos puertos del pic para la cominicacion.
 
O bien, aprovechar el mismo bus I2C para transferir comandos de un PIC a otro así no utilizas más pines. No habrá conflicto con la memoria porque ésta tiene una dirección de bus ya definida; al PIC esclavo le puedes asignar otra diferente
 
Allí si no le sé :LOL:, se podría dar la vuelta al problema usando un sólo PIC y algún expansor de puertos serial, sería bueno que el amigo diera más detalles de que tanto es "eso" que quiere controlar y que demanda muchos puertos
 
Es para controlar 1 teclado matrisial de 4x4, un Display LCD, 2 Display de 7 segmentos, y un par de matrises de leds, tengo entendido qe para los Display tanto LCD como de 7 segmentos existen decodificadores que nos permiten utilizar menor cantidad de pines.
 
Bien ya veo, bueno, para el LCD, los displays y el teclado se puede usar un mismo bus de datos de 8 bits (puerto B). Sólo sería jugar con el registro TRISB para configurar PORTB como salida cuando se envían datos y dejarlo como entrada la mayor parte del tiempo para gestionar el teclado. En los displays de 7 segmentos puedes usar registros latch como el 74LS374 para retener su dato enviado.
Por otro puerto como el D gestionas las matrices de leds y algunos pines del C los usas para el bus I2C de la memoria ¿cómo ves?
 
Saludos! Quizás la gente de este foro pueda ayudarme con comunicación i2c.

Resulta que estoy intentando comunicar 2 pics (un maestro y otro esclavo) mediante i2c. Hasta ahora me parece que el problema es el maestro que luego de la sentencia i2c_write(0xa0) (Escribir en el esclavo), este inicia la comunicación y luego se queda colgado. Adjunto los códigos y la simulación en Proteus 7.8 con i2c debugger...

Maestro:
Código:
#include <18F4550.h>
#DEVICE ADC=8
#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL10,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use i2c(master, SDA=pin_b0, SCL=pin_b1,slow)

int valor;
//int esclavo1=0xA0, esclavo2=0xB0, esclavo3=0xC0, esclavo4=0xD0;
float q;
float dato;


int main(void)
{
 setup_adc_ports(ALL_ANALOG);
 setup_adc(ADC_CLOCK_INTERNAL);
 set_adc_channel(0);
 while(1)
 {
  delay_us(10);
  valor=read_adc();
  q=valor;
  dato=valor*5/255;
  if(valor>125)
  {
   i2c_start(); 
   i2c_write(0xa0); 
   delay_ms(2);
   i2c_write(dato);
   delay_ms(2);
   i2c_stop();
  }
 }
}

Esclavo:
Código:
#include <18F2550.h>
#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use i2c(slave, SDA=pin_b0, SCL=pin_b1,slow,address=0xa0)

#INT_SSP
 void ssp_interrupt()
 {
  output_high(PIN_A0);
  output_low(PIN_A1);
  delay_ms(200);
 }


int main(void)
{
 enable_interrupts(global);
 enable_interrupts(int_ssp);
 while(1)
 {
  output_low(PIN_A0);
  output_high(PIN_A1);
 }
}

Si pueden ayudarme o dirigirme a quien pueda ayudar, gracias! :)
 

Adjuntos

  • Simulación.jpg
    Simulación.jpg
    104.8 KB · Visitas: 15
Quizá el Master esté esperando el ACK por parte del esclavo. Tu no lo haces directamente, ¿estás seguro de que lo hacen las rutinas I2C que usas?
 
Tengo entendido que en caso de no recibir el ACK, se interrumpe la comunicación. En todo caso, de ser eso, el problema estaría en el esclavo quien no estaría enviando el ACK en cuestión...
 
No he logrado nada, y me parece que el problema es que no se colocar la rutina del ACK por parte del esclavo. Cuando en el master escribo i2c_write(0xa0); se supone que el slave debería enviar el ACK; ahí es donde comienza mi ignorancia porque no se cómo demonios se hace eso...
 
Atrás
Arriba