Comunicación I2C con PIC18f4550 como esclavo

#1
Hola gente del foro! ojala me puedan ayudar.
Necesito comunicar dos pic por I2C y problema es que necesito que el esclavo sea un 18f4550 que no tiene modulo ssp, por lo tanto la funcion I2C_poll() no funciona. como puedo hacer entonces para establecer la comunicación? o de ultima si alguien me pasa un codigo en SPI que funcione y me explica un poco sobre este otro tipo de comunicacion.

Muchas Gracias!
 
#2
Hola gente del foro! ojala me puedan ayudar.
Necesito comunicar dos pic por I2C y problema es que necesito que el esclavo sea un 18f4550 que no tiene modulo ssp, por lo tanto la funcion I2C_poll() no funciona. como puedo hacer entonces para establecer la comunicación? o de ultima si alguien me pasa un codigo en SPI que funcione y me explica un poco sobre este otro tipo de comunicacion.

Muchas Gracias!
como que el 4550 no tiene ssp, claro que lo tiene!

Compadre mejor lee este documento ahí encontraras lo que nececitas para comunicacion SPI. :apreton:

si tienes alguna duda después de leerlo, no dudes en preguntar!!!(y)
 

Adjuntos

Última edición:
#3
Gracias por responder. en realidad me equivoque, si tiene modulo ssp pero la funcion i2c_poll no funciona, hay que verificar la presencia de un nuevo dato en el bus por medio de una interrupcion . por suerte pude hacer funcionar perfectamente el i2c. el documento sobre spi que me pasaste esta muy bueno, muchas gracias por ayuda.
 
#4
Buen día.
Aprovecho para pedirles una disculpa a los lectores, así como a los administradores del foro, dado a que anteriormente cometí el error de duplicar temas por desesperación, pero de todas maneras disculpas.

Quiero solicitarles su apoyo con la comunicación entre 2 PIC18F4550 por I2C.
Al parecer quiero creer que es la frecuencia el problema, dado que este proyecto ya lo había probado con 2 PIC16F877A y no había tendido problema.

Les anexo los códigos por si alguien puede echarme la mano.

MAESTRO:
PHP:
//codigo by Christian N.H
#include <18F4550.h>
#device adc=10
#FUSES INTRC_IO,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN
#use delay(clock=4000000)
       #include <math.h>
       
       #use i2c(master, sda=PIN_B0, scl=PIN_B1,slow)
       //#use i2c(MASTER, SDA=PIN_B0, FAST, SCL=PIN_B1, FORCE_HW)//NOFORCE_SW)
       #include <C:\Users\JUAN\Desktop\alarma_pic18\MODIFICACION\LCD4x20.c> ///////// CAMBIAR POR LAS 
       #use standard_io(C)
       #use fast_io(a)
       #use fast_io(d)
   
       int a,b,c,d;
       void main(){
      
      while(TRUE)
      {   
        lcd_init();
        i2c_start();       //condicion de inicio 
        i2c_write(0x0A);   //direccion del esclavo con el que haremos la comunicacion 1011101
        delay_ms(10);
        i2c_write('t');    //seleccion de canal analogo(t-canal 0,k-canal 1,h-canal 2,y-canal 3)
        i2c_stop();        //finalizacion de la comunicacion 
        delay_ms(100);     //introducimos retardo para que no este constantemte escribiendo
        i2c_start();
        i2c_write(0x0b);
        delay_ms(10);
        a=i2c_read(0);
        i2c_stop(); 
        
        i2c_start();       //condicion de inicio 
        i2c_write(0x0A);   //direccion del esclavo con el que haremos la comunicacion 1011101
        delay_ms(10);
        i2c_write('k');    //seleccion de canal analogo(t-canal 0,k-canal 1,h-canal 2,y-canal 3)
        i2c_stop();        //finalizacion de la comunicacion 
        delay_ms(100);     //introducimos retardo para que no este constantemte escribiendo
        i2c_start();
        i2c_write(0x0b);
        delay_ms(10);
        b=i2c_read(0);
        i2c_stop(); 
        
        i2c_start();       //condicion de inicio 
        i2c_write(0x0A);   //direccion del esclavo con el que haremos la comunicacion 1011101
        delay_ms(10);
        i2c_write('h');    //seleccion de canal analogo(t-canal 0,k-canal 1,h-canal 2,y-canal 3)
        i2c_stop();        //finalizacion de la comunicacion 
        delay_ms(100);     //introducimos retardo para que no este constantemte escribiendo
        i2c_start();
        i2c_write(0x0b);
        delay_ms(10);
        c=i2c_read(0);
        i2c_stop(); 
        
        
        i2c_start();       //condicion de inicio 
        i2c_write(0x0A);   //direccion del esclavo con el que haremos la comunicacion 1011101
        delay_ms(10);
        i2c_write('y');    //seleccion de canal analogo(t-canal 0,k-canal 1,h-canal 2,y-canal 3)
        i2c_stop();        //finalizacion de la comunicacion 
        delay_ms(100);     //introducimos retardo para que no este constantemte escribiendo
        i2c_start();
        i2c_write(0x0b);
        delay_ms(10);
        d=i2c_read(0);
        i2c_stop(); 
        
        
        lcd_gotoxy(2,1);
        printf(lcd_putc,"\btemp=%01.1u",a);
        delay_ms(50);
        
        lcd_gotoxy(10,1);
        printf(lcd_putc,"\btemp=%01.1u",b);
        delay_ms(50);
        
        lcd_gotoxy(2,2);
        printf(lcd_putc,"\btemp=%01.1u",c);
        delay_ms(50);
        
        lcd_gotoxy(10,2);
        printf(lcd_putc,"\btemp=%01.1u",d);
        delay_ms(1000);
      }
      
  }
ESCLAVO:
PHP:
//codigo by Christian N.H
#include <18F4550.h>
#device adc=10
#FUSES INTRC_IO,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN
#use delay(clock=4000000)

      #use i2c(slave, sda=PIN_B0, scl=PIN_B1,slow,ADDRESS=0x0A)
      //#use     i2c(SLAVE,SCL=PIN_B1,SDA=PIN_B0,FAST,FORCE_HW,ADDRESS=0x0A)
      #use     fast_io(A)
      #use     fast_io(B)
      #define  PORTB 0X06

      int dato,p,q;
      BYTE incoming, state;         // I2C variables
      byte address, buffer[0x01];   // Address and Array of Bytes

#INT_SSP
void ssp_interupt ()
{
  state = i2c_isr_state();
  if(state < 0x80)                  //Master enviando dato
  {
    if(state == 0)
    {
    
    }
    if(state == 1)                  //Primer dato es la direccion
    {
      incoming = i2c_read();
      address = incoming;
    }
    if(state == 2)                  //segundo es el dato
    {
      incoming = i2c_read();
      buffer[address] = incoming;
    }
  }
  if(state == 0x80)                 //Master requiere dato
  {
    i2c_write (buffer[0X00]);
  }
}


 void main(){
               set_tris_A(0xff);
               setup_adc_ports(ALL_ANALOG);
               setup_vref(FALSE); 
               setup_adc(ADC_CLOCK_INTERNAL);
               enable_interrupts(GLOBAL);
               enable_interrupts(INT_SSP);
               set_tris_B(0x00);
  
   #asm
      clrf PORTB;
   #endasm
      
 
   while (TRUE){

      dato=i2c_read();
        
               if (dato=='t'){
               set_adc_channel(0); 
               delay_us(20);
               q = read_adc();                  //Lectura canal0
               p = 10;                    //(q*(0.48875));               //Conversión a tens;
               buffer[0x00]=p;}              
               else 
               { output_high(PIN_B0);}
                                          
               if (dato=='k'){
               set_adc_channel(1); 
               delay_us(20);
               q = read_adc();                  //Lectura canal0
               p =  (q*(0.48875));               //Conversión a tens;
               buffer[0x00]=p;}              
              else
              { output_high(PIN_B1);}
              
              if (dato=='h'){
               set_adc_channel(2); 
               delay_us(20);
               q = read_adc();                  //Lectura canal0
               p = 30;                    //(q*(0.48875));               //Conversión a tens;
               buffer[0x00]=p;}              
               else
              { output_high(PIN_B2);}
              
              if (dato=='y'){
               set_adc_channel(3); 
               delay_us(20);
               q = read_adc();                  //Lectura canal0
               p = 40;                    //(q*(0.48875));               //Conversión a tens;
               buffer[0x00]=p;}              
               else
              { output_high(PIN_B3);}                       
         }
 }
 
Última edición por un moderador:
Arriba