Проблема с циклом while

Я пытаюсь прочитать значения внешнего АЦП AD7798 , используя контроллер ATmega32-A. В таблице данных бит 7 регистра состояния ( SR7) указывает, завершено преобразование или нет:

Готов бит. Очищается, когда данные записываются в регистр данных. Устанавливается после считывания регистра данных или по прошествии периода времени до того, как регистр данных будет обновлен новым результатом преобразования, чтобы указать пользователю не читать данные преобразования. Он также устанавливается, когда деталь находится в режиме пониженного энергопотребления. Окончание преобразования обозначается выводом DOUT/RDY. Этот контакт можно использовать в качестве альтернативы регистру состояния для контроля АЦП для данных преобразования.

Теперь я хочу написать код, чтобы проверить, является ли MSB регистра состояния (Bit7) 0или нет. Поэтому, когда это так 0, только тогда я могу выполнить команду чтения.

Я написал такой код:

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

Но это не работает.

Мое объяснение кода:

  1. Выдача команды чтения для чтения регистра состояния АЦП.
  2. Чтение значения регистра состояния АЦП и сохранение в adcStatusпеременной.
  3. Проверка бита MSB не равна 1. (Я не уверен, что этот whileцикл правильный или нет.)

Я хочу проверить, не равен ли MSB регистра состояния, 1чтобы я мог выполнить команду чтения ( 0x58) для чтения значений ADC. Если регистр состояния MSB равен, 1то я не могу прочитать значения ADC.

Что я делаю не так?

Ответы (1)

Вам нужно перечитать регистр состояния АЦП внутри цикла; в противном случае вы просто повторно тестируете то, что прочитали в первый раз. Кроме того, вам нужно изменить смысл теста — вы хотите повторить тест, если бит равен «1», и выйти из цикла, как только он переключится на «0». Также может потребоваться переключить выбор микросхемы на АЦП при каждом чтении, как показано в комментариях ниже.

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;
}
Я запутался с циклом while, потому что (adcStatus & 0x80) в результате будет = 0x80. значит 0x80==0x80? Можете ли вы дать небольшое пояснение по этому поводу.
Выражение (adcStatus & 0x80)может иметь только два разных значения: 0x00 или 0x80, в зависимости от состояния бита 7 в adcStatus.
Если предположить, что (adcStatus & 0x80) даст результат 0x80, тогда он сравнит 0x80==0x80 с тем, что он вернет. Я предполагаю, что он будет выполняться последовательно до тех пор, пока бит 7 не станет равным 0 и не будет возвращено значение adcStatus. потому что, когда Bit7 = 0, тогда (adcStatus и 0x80) будет результат 0x00, который не равен 0x80, поэтому цикл завершается. Я прав.
Нет, как объяснил Дейв, ваш код будет считывать значение состояния ОДИН РАЗ, а затем зацикливаться до тех пор, пока 7-й бит этого значения состояния (сохраненного в локальной переменной adcStatus) волшебным образом не изменится на 1. Или, может быть, даже это не завершит цикл. : adcStatus не объявлен volatile, поэтому компилятор может проверить бит только один раз, а затем войти в бесконечный цикл. Но это НЕ ваша проблема. Ваша проблема (как сказал Дэйв!), что вы должны перечитать значение состояния ВНУТРИ ЦИКЛА.