3
\$\begingroup\$

I am trying to read external ADC AD7798 values using ATmega32-A controller. In the datasheet, Status register Bit 7 (SR7) indicates the conversion is finished or not:

Ready Bit. Cleared when data is written to the data register. Set after the data register is read or after a period of time before the data register is updated with a new conversion result to indicate to the user not to read the conversion data. It is also set when the part is placed in power-down mode. The end of a conversion is indicated by the DOUT/RDY pin. This pin can be used as an alternative to the status register for monitoring the ADC for conversion data.

Now I want to write code to check if the Status register MSB (Bit7) is 0 or not. So when it is 0, only then can I issue a read command.

I have written code like this:

unsigned char CheckStatus(void)
{
            char adcStatus; 
            spi(0x40);
            adcStatus = spi(0xFF);
            while((adcStatus & 0x80)!=0x80);                         
            return adcStatus;
}

But it is not working.

My code explanation:

  1. Issuing the read command to read ADC status register.
  2. Reading ADC status register value and stored in adcStatus variable.
  3. Checking the MSB bit is not equal to 1. (I am not sure if this while loop is correct or not.)

I want to check if the Status register MSB is not equal to 1 so that I can issue the read command (0x58) to read in the ADC values. If the status register MSB is equal to 1 then I can't read ADC values.

What am I doing wrong?

\$\endgroup\$

1 Answer 1

9
\$\begingroup\$

You need to re-read the ADC status register inside the loop; otherwise, you're just re-testing the bit you read the first time. Also, you need to reverse the sense of the test — you want to repeat the test if the bit is "1" and drop out of the loop once it switches to "0". It may also be necessary to toggle chip select to the ADC on each read, as shown in the comments below.

unsigned char CheckStatus(void)
{
  unsigned char adcStatus;
  do {
    /* TBD: assert chip select here? */
    spi(0x40);
    adcStatus = spi(0xFF);
    /* TBD: negate chip select here? */
  } while ((adcStatus & 0x80) == 0x80);                         
  return adcStatus;
}
\$\endgroup\$
4
  • \$\begingroup\$ I am confusing with the while loop, because (adcStatus & 0x80) will result=0x80. then 0x80==0x80 means? Can you give little bit clarification on this. \$\endgroup\$
    – verendra
    Commented Oct 16, 2012 at 11:57
  • \$\begingroup\$ The expression (adcStatus & 0x80) can only have two different values: 0x00 or 0x80, depending on the state of bit 7 in adcStatus. \$\endgroup\$
    – Dave Tweed
    Commented Oct 16, 2012 at 12:02
  • \$\begingroup\$ If suppose (adcStatus & 0x80) will result 0x80 then it will compare 0x80==0x80 then what will it returns. My guess it will execute contiguously until Bit7=0 and the return adcStatus value. because when Bit7=0 then (adcStatus & 0x80) will result 0x00, which not equal to 0x80 so loop terminates.Am I correct. \$\endgroup\$
    – verendra
    Commented Oct 16, 2012 at 12:29
  • 1
    \$\begingroup\$ No, as Dave explained your code will read the status value ONCE and then loop until the 7'th bit of that status value (saved in the local variable adcStatus) magically flips to a 1. Or maybe even that won't terminate the loop: adcStatus is not declared volatile, so the compiler is free to check the bit just once and then enter an infinite loop. But that is NOT your problem. Your problem is (as Dave said!) that you must re-read the status value INSIDE THE LOOP. \$\endgroup\$ Commented Oct 16, 2012 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.