У меня есть следующие определения:
#define DEVICE_ID ((uint8_t)0x3f)
и у меня есть следующая функция:
void LIS3DSH_Init(LIS3DSH_InitTypeDef* LIS3DSH_InitStruct)
{
// uint8_t ctrl=0x00;
uint8_t ident=0x00;
LIS3DSH_LowLevel_Init();
LIS3DSH_Read(&ident,
LIS3DSH_WHOAMI_REG_ADDR,
1);
if(DEVICE_ID==ident)
{
// LIS3DSH detected
}
else
{
// LIS3DSH not detected
failureHandler();
}
} // LIS3DSH_Init
Теперь, если я пошагово расскажу об этой функции, переменная ident получает значение 0x3f после вызова функции LIS3DSH_Read, что нормально. Мой вопрос, почему, черт возьми, если предложение переходит к failHandler? Значения DEVICE_ID и ident одинаковы — оба равны 0x3f, если не следует переходить к failHanlder (). Я работаю над библиотекой ускорителя LIS3DSH, используя IAR C / C ++ и STM32F4 Discovery Board. Вот скриншот ситуации:
Вы должны набрать if(DEVICE_ID==ident)
быть if( (uint8_t)DEVICE_ID == (uint8_t)ident)
Это было проблемой для меня в прошлом.
И да, объявляйте id как volatile, и в целях отладки попробуйте добавить задержку перед сравнением через цикл for с __no_operation();
внутри него. Обратите внимание, что перед ним стоит 2 подчеркивания, а не 1 (внутренняя инструкция NOP), и что для одной NOP на плате 168 МГц требуется примерно ~ 29 нс, измеренная с помощью области видимости.
Кроме того, поскольку у вас есть IAR, вы также можете открыть представление «сборка» и посмотреть, какие регистры и / или константы на самом деле сравниваются. Также откройте представление «регистр», чтобы вы могли видеть сами значения регистров.
Является ли функция
failureHandler()
обработанный?
Если нет, то представление отладчика просто сбивает с толку из-за оптимизации компилятора.
Вполне вероятно, что оптимизированный код использует общий код возврата для обоих
хороший случай и случай неудачи. Отладчик останавливается на «выходе» пути отказа даже
в хорошем случае.