6 years, 5 months ago.

i2c communication failure

My master keeps asking for reading data, but the slave takes some time to fill his buf and respond, after that I can not get the ack.

#include "stm32f103c8t6.h"
#include "mbed.h"
#define address ((uint8_t) 0xA0)
DigitalOut myled(PA_1);
InterruptIn  chave(PA_0);
Serial  S(PA_9, PA_10); 
void bat(void);
void status(void);
void start(void);
void date(void);
//PROGRAMA PRINCIPAL
int main(){
Serial  S(PA_9, PA_10); 
I2C     mestre(PB_7, PB_6);
confSysClock();
while(1){
    bat();
    status();
  }  
}  
//ESTADO DA BATERIA LED=1=LIGADO/LED=0=DESLIGADO
void bat(void){
int estado;
estado = 0; 
if(chave==1&&estado==0){
myled= !myled;
wait(0.25);
estado= 1;
}
if(chave==0&&estado==1){
estado=0;
} 
}
//STATUS DO LED
void status(void){
    Serial  S(PA_9, PA_10); 
    if(myled==0){
    S.printf("\r\n");
    S.printf("SEM BATERIA\r\n");
    S.printf("\r\n");
    bat();
}
    if(myled==1){
    S.printf("\r\n");
    S.printf("LIGADO");
    S.printf("\r\n");
    start();
  }
}
// start sistema
  void start(void){
  Serial  S(PA_9, PA_10); 
  I2C     mestre(PB_7, PB_6);
  char startcommand[]= "slaveready";
  char tempostart[]= "100917103020";
  char respo1[11],respo2[13],respo3[10],respo4[113];
  char pacote[7]="020030"; 
  int x;
  memset(respo1,'\0',11);
  memset(respo4,'\0',113);
  x = 0;
  // Começo master envia readslave para o escravo
  if(x==0){
  int resposta = mestre.write(address,startcommand,11);    
  S.printf("\r\n");
  S.printf("M.ENVIOU<%s>\r\n ",startcommand); 
  x = 1;
  }
  // Só acontecera se o master ja estiver enviado o read para o escravo
// o master lê o a msg enviada pelo escravo
  if(x==1){
  mestre.read(address,respo1,11);    
  S.printf("\rM.RECEBEU<%s> \r\n ",respo1);    
    x = 2;
          }
//Só acontece se o master ja recebeu mastersalve que enviou
// master escrefvetimerstamp para o escravo 
  if(x==2){
    int resposta1 = mestre.write(address,tempostart,13);         
    S.printf("\r2M.ENVIOU<%s>\r\n",tempostart);        
    x = 3;
}
// Só acontece se o master ja escreveu timerstamp
// master lê o timerstamp que enviou
  if(x==3){
     mestre.read(address,respo2,13);    
     S.printf("\r2M.RECEBEU<%s> \r\n ",respo2);    
     x = 4;
           }
//Só acontece se o mater ja leu o timerstamp
// master ira ler o dados com timerstamp           
  if(x==4){
     wait(5);
     mestre.read(address,respo3,10);    
     S.printf("\r3M.RECEBEU<%s> \r\n ",respo3);    
     x = 5;
          }
  if(x==5){
    mestre.write(address,pacote,7);         
    S.printf("\r3M.ENVIOU<%s>\r\n",pacote);        
    x = 6;
}        
    if(x==6){
    int jk = mestre.read(address,respo4,113);    
    S.printf("\r4M.RECEBEU<%s> \r\n ",respo4);  
    while(jk!=0){
   int jk = mestre.read(address,respo4,113);        
   S.printf("\r4M.RECEBEU<%s> \r\n ",respo4);  
   }
     }                  
}

Slave

#include "stm32f103c8t6.h"
#include "mbed.h"
int main() {
    char buf[11],buf1[13],buf3[7],caf[3],caf1[3],caf2[100],caf3[23];                             // Buffer o qual ira quardar a mensagem do mestre
    char buf2[]="BUFCMP";
    char resul[]= "FFFFFFFFFFFFFFFFFFFFBBBBBBBBVVFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
    confSysClock();                           // Configure system clock (72MHz HSE clock, 48MHz USB clock)
    Serial      S(PA_9, PA_10);               // Definindo portas serial (TX e RX)
    I2CSlave    slave(PB_7, PB_6);            // Definindo portas do I2C(SDA e SCL )
    slave.address(0xA0);                      //atribuindo um valor no escravo
    int aju,j,k;
    aju = 0; 
        while (1){
        int i = slave.receive();                                            // Analisando se o mestre mandou alguma informacao
        switch (i) {
             case I2CSlave::WriteAddressed:                             // O escravo percebeu seu address especifico
             if(aju==0){
             //memset(buf1,'\0',113);  
             slave.read(buf,11);                                  
             S.printf("S.RECEBEU<%s>\r\n",buf); 
             aju = 1;
             }
             if(aju==2){
                 slave.read(buf1,13);                                  
                 S.printf("2S.RECEBEU<%s>\r\n",buf1);
                 aju = 3;
                    } 
             if(aju==5){
                 memset(caf3,'\0',23);
                 slave.read(buf3,7);                                  
                 S.printf("3S.RECEBEU<%s>\r\n",buf3);
                 strncpy(caf,buf3,3);
                 int pca = atoi(caf); /* num recebe 20 */
                 strncpy(caf1, buf3+3 ,3);             
                 int pca1 = atoi(caf1); /* num recebe 30 */
                 j= pca1-pca;
                 k=13+j;        //12 char no timerstamp
                 strncpy(caf2, resul+pca ,j); 
                 strcat(caf3,buf1);
                 strcat(caf3,caf2);
                 aju = 6;
                 }       
             break;
             case I2CSlave::ReadAddressed:
             if(aju==1){
             int j = slave.write(buf,11);        
             S.printf("S.ENVIOU<%s>\r\n",buf);   
             aju = 2;
             }
             if(aju==3){
             int k = slave.write(buf1,13);        
             S.printf("2S.ENVIOU<%s>\r\n",buf1);   
             aju = 4;
             }             
             if(aju==4){   
             wait(5);
             int l = slave.write(buf2,10);        
             S.printf("3S.ENVIOU<%s>\r\n",buf2);
             aju = 5;
             }   
             if(aju==6){
             int jk = slave.write(caf3,k); 
             S.printf("< %s >\r\n",caf3);
             while(jk != 0){             
             int jk = slave.write(caf3,k); 
             S.printf("< %s >\r\n",caf3);
             }             
             aju = 0;
                               }         
             break;             
                   } 
                  }
      }

Please edit this and use

<<code>>
Your code
<</code>>

So that the code is readable.

posted by Andy A 30 Nov 2017

Thank you for your help

posted by Alan Silva 30 Nov 2017
Be the first to answer this question.