Ir ao conteúdo
  • Cadastre-se

I2C Multimaster I2C_Write() colisão


Posts recomendados

Estou desenvolvendo um barramento I2C com três mestres (multimestre) e encontrei algo interessante. Segundo help o CCS:

 

"i2c_write()

Returns:
This function returns the ACK Bit. 
0 means ACK, 1 means NO ACK, 2 means there was a collision if in Multi_Master Mode.
 
Porém, caso ocorra uma colisão e perda de arbitrariedade essa função não retorna o 2... Ela não indica uma verdadeira colisão. O que ela faz é retornar 2 caso o mestre tente iniciar uma transmissão sendo que a ultima condição detectada no barramento foi START (SSPSTAT bits STOP e START), ou seja, há alguém transmitindo. A descrição da função diz uma coisa e ela faz outra...
 
Fiz tudo na simulação pois estava usando o debugger do código e o i2c debugger do proteus.
Estou montando apenas por hobby não é nada profissional.
 
Alguém já reparou isso? 
Isso seria o funcionamento normal da função?
Link para o comentário
Compartilhar em outros sites

Para concluir. Eu estava usando I2C por hardware e a função i2c_write() não retorna 2 em caso de colisão mas a interrupção BUSCOL é ativada (o que gerou outro problema falo abaixo), usando o i2c por software a funçao i2c_write() realmente retorna 2 caso ocorra uma colisão mas ai não dá para usar os dados dos registradores do MSSP além da função i2c_start() funcionar de forma estranha em caso de colisão durante o start...

 

Usando o i2c por hardware a interrupção BUSCOL é ativada sempre que uma colisão ocorre. Porém, se o START não for dado dentro dela na próxima colisão o PIC trava.

#int_BUSCOLvoid  BUSCOL_isr(void) {    do{}while(stop_bit==0);//espera a transmissão terminar}
 
Dando o START dentro da colisão o PIC aceita infinitas colisões mas trava (na segunda colisão) se outro mestre der o START antes dele.
#int_BUSCOLvoid  BUSCOL_isr(void) {    do{}while(stop_bit==0);   /**********/ // <--- START de outro mestre faz o PIC travar   i2c_start();}
 
Consegui resolver dando o START pelo registrador, agora colisões podem ocorrer em qualquer lugar...
#int_BUSCOLvoid  BUSCOL_isr(void) {      buscol:   BCLIF=0;                //#bit BCLIF=PIR2.3    do{}while(stop_bit==0); //Espera a liberação do barramento    SEN=1;                  //inicia o START pelo SSPCON2 #bit SEN=SSPCON2.0   do{}while(SEN==1);      //espera o término do START      if(BCLIF==1)          goto buscol;         //Se durante o start ocorreu colisão espera novamente a liberação do barramento      flag_colisao=1;}

 

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...