what is better using while loop or if statement when checking status codes of atmega 32?

305 views Asked by At

i have read in the documentation of a part of a project describing connecting two micro controllers atmega 32 using TWI (i2c) that the better way to check status codes of the TWI after finishing its work , sending data from slave to master , is to use the while loop and not if statement as the CPU clock speed is much higher than TWI hardware clock speed.

For example , if i want to check if a data byte that has been sent from slave to master and acknowledge from master has been received by slave we must use in the slave code

  • while((TWSR & 0xF8) != 0xB8) instead of
  • if ((TWSR & 0xF8) != 0xB8).

also i get bit confused what happens if the TWI process failed , is the slave CPU will not execute other tasks.

Note that , the status code 0xB8 on the data sheet of atmega 32 means that a data byte has been transmitted successfully from slave to master and an acknowledge from master has been received by slave and the status code is loaded by the TWI hardware in the TWI status register.

1

There are 1 answers

0
Damago On

There is no simple answer to the above question. Firstly: yes, you should wait for the device to be ready, so while() is the desired option. Unless your if() has some else {} that makes sense.

But: indeed this will block the device for the time it is waiting for I2C to be ready and can in some not so rare cases lead to complete lock of the device.

Even the built-in twi / wire / i2c libraries from Atmel and Arduino team have a problem with this. They can hang the device if it does not receive correct confirmation. The original twi.h code:

    while ((TWCR & _BV(TWINT)) == 0); /* wait for transmission */

very often hangs forever in this loop.

Google for 'non-blocking i2c Arduino' or 'while TWCR I2C problem' and you will find a lot of discussions about this. Most solutions rely on while() but with some timeout.

    timeout = 123456567;
    while (((TWCR & _BV(TWINT) == 0) & (timeout!=0))
    {
       timeout--;
    }; /* wait for transmission or timeout */
    if(timeout==0)
    {
    //there was timeout
    }
    else
    {
    //process data
    }