Ir ao conteúdo
  • Cadastre-se
test man*~

I2C Multimaster I2C_Write() colisão

Recommended Posts

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?

Compartilhar este post


Link para o post
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;}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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

×