Problem with i2c master slave communication

Post your requests and ideas on the future development of mikroPascal.
Post Reply
Author
Message
garpo
Posts: 2
Joined: 15 Mar 2013 19:40

Problem with i2c master slave communication

#1 Post by garpo » 15 Mar 2013 20:45

good afternoon I have a problem with i2c communication I have a master and two slaves 16F876A, the problem is that if you can send data to one of the two slaves but when I switched to another slave sends no data, I've noticed that when data is sent to the first slave ack pulse never returns high, someone could help me with this problem

master code:

Code: Select all

void send(unsigned short send_data, int dir)   // function to send data
{
  I2C1_Init(100000);
  I2C1_Start();
  I2C1_Wr(dir);
  I2C1_Wr(send_data);
  I2C1_Stop();
}


unsigned int band =0;
unsigned short  cont =0;
unsigned short  cont2 =0;
  
void main()
{
  while(1)
  {
   if((portb.b0==1) && (band == 1))  // condition to send data to slave 1
   {
    send(100+cont, 0xa0);
    cont++;
    band=0;
   }
   if((portb.b2==1) && (band== 1))   //condition to send data to slave 2
   {
    send(10+cont2, 0xaa);
    cont2++;
    band=0;
   }
   if(portb.b1==1)  // condition that enables sending data
   {
    band=1;
   }
  }
}

slave 1 code:

Code: Select all

sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D4 at RB0_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB0_bit;

const Addy = 0xa0;      // Slave address 1

unsigned short j;       // just dummy for buffer read
unsigned short rxbuffer;
char text[20];

void Init()
{
  ADCON1 = 0;   // All ports set to digital
  trisc.b3=1;   // set as input
  trisc.b4=1;   // set as input
  SSPADD =  Addy;  // Get address (7bit). Lsb is read/write flag
  SSPCON = 0x3e;   // Set to I2C slave with 7-bit address
  PIE1.SSPIE = 1;   // enable SSP interrupts
  INTCON = 0xC0;       // enable INTCON.GIE
}

void interrupt()  // I2C slave interrupt handler
{
  if (PIR1.SSPIF == 1)  // I2C Interrupt
  {
    if (SSPSTAT.BF == 0) // Transmission completed
    {
      if(sspcon.sspov == 0)      //   without overflow
      {
         if(sspstat.d_a == 1)  // Data [not address]
         {
          rxbuffer = sspbuf;    // get data
          PIR1.SSPIF = 0;      // reset SSP interrupt flag
         }
      }
    }
  }
  j = SSPBUF;   // read buffer to clear flag [address]
  return;
}

void main()
{
  Init();
  
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  lcd_out(1,1,"Esclavo 1");

  delay_ms(250);

  while(1)
  {
    shorttostr(rxbuffer,text);
    lcd_out(2,1,text);
    Delay_ms(250);
  }
}

slave 2 code:

Code: Select all

sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D4 at RB0_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB0_bit;

const Addy = 0xaa;      // Slave address 2

unsigned short j;       // just dummy for buffer read
unsigned short rxbuffer;
char text[20];

void Init()
{
  ADCON1 = 0;   // All ports set to digital
  trisc.b3=1;   // set as input
  trisc.b4=1;   // set as input
  SSPADD =  Addy;  // Get address (7bit). Lsb is read/write flag
  SSPCON = 0x3e;   // Set to I2C slave with 7-bit address
  PIE1.SSPIE = 1;   // enable SSP interrupts
  INTCON = 0xC0;       // enable INTCON.GIE
}

void interrupt()  // I2C slave interrupt handler
{
  if (PIR1.SSPIF == 1)  // I2C Interrupt
  {
    if (SSPSTAT.BF == 0) // Transmission completed
    {
      if(sspcon.sspov == 0)      //   without overflow
      {
         if(sspstat.d_a == 1)  // Data [not address]
         {
          rxbuffer = sspbuf;    // get data
          PIR1.SSPIF = 0;      // reset SSP interrupt flag
         }
      }
    }
  }
  j = SSPBUF;   // read buffer to clear flag [address]
  return;
}

void main()
{
  Init();
  
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  lcd_out(1,1,"Esclavo 1");

  delay_ms(250);

  while(1)
  {
    shorttostr(rxbuffer,text);
    lcd_out(2,1,text);
    Delay_ms(250);
  }
}
Deputy circuit in Proteus and some images

Infinitely thanking .... :D
Attachments
I2C.rar
diagram and image
(201.73 KiB) Downloaded 254 times

User avatar
dejan.odabasic
mikroElektronika team
Posts: 2649
Joined: 30 Apr 2012 14:20

Re: Problem with i2c master slave communication

#2 Post by dejan.odabasic » 18 Mar 2013 19:06

Hello,

Have you tested your code on actual hardware or only in Proteus?
Proteus is not certified simulations environment for code generated by mikroE compilers.

I suggest that you test your code on real hardware.

Best regards.

garpo
Posts: 2
Joined: 15 Mar 2013 19:40

Re: Problem with i2c master slave communication

#3 Post by garpo » 18 Mar 2013 20:10

Thank you very much Porla answer but depues analyzing the situation I realized it was a flag that was raised, and the clean and worked, I leave the code so I can help someone ... : D

Code: Select all

sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at Rb7_bit;
sbit LCD_D4 at Rb6_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISb7_bit;
sbit LCD_D4_Direction at TRISb6_bit;

const Addy = 0xa0;

unsigned short j;
unsigned short rxbuffer;
char text[20];

void Init()
{
  ADCON1 = 0;
  trisb.b1=1;
  trisb.b0=1;
  SSPADD =  Addy;
  SSPCON1 = 0x3e;
  PIE1.SSPIE = 1;
  INTCON = 0xC0;
}

void interrupt()
{
  if (PIR1.SSPIF == 1){
    PIR1.SSPIF = 0;
    if (SSPSTAT.BF == 0){
      if(sspcon1.sspov == 0){
        if(sspstat.d_a == 1){
          rxbuffer = sspbuf;
        }
      }
      else sspcon1.sspov=0;  // clears the flag
    }
  }
  j = SSPBUF;
  return;
}

void main()
{
  Init();

  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  lcd_out(1,1,"Esclavo 1");

  delay_ms(250);

  while(1)
  {
    shorttostr(rxbuffer,text);
    lcd_out(2,1,text);
    Delay_ms(250);
  }
}

Post Reply

Return to “mikroPascal Wish List”