Перейти к содержанию
    

st32f401. Поподаю в прерывание EXTI3_IRQHandler(). Флаги прерывания нулю равны, но прерывание срабатывает. Не могу понять почему. Вот обработчик дебажный

Quote
extern "C" void EXTI3_IRQHandler()

{

static uint32_t a;

a = EXTI->PR;

EXTI_ClearFlag(EXTI_Line3);

}

EXTI->PR равно нулю. а всегда равна нулю. Почему попадаю в прерывание. Как это отловить?

Изменено пользователем haker_fox
Уточнил название темы, добавил теги, переместил в нужный раздел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему попадаю в прерывание. Как это отловить?

Видимо, вы его разрешили и сконфигурировали - вот и попадаете.

Вопрос не понятный: вас смущает, что вообще прерывание возникает? или что оно и должно возникать, но PR при этом нулевой?

 

Есть у Cortex такая штука как повторный вход в прерывание по уму обработчик должен проверять условие.

Например,

void EXTI0_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line0) != RESET)
  {
    /* Toggle LED3 */
    STM_EVAL_LEDToggle(LED3);
    
    /* Clear the EXTI line 0 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line0);
  }

}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Остановиться в обработчике прерывания, посмотреть регистры NVIC.

А какие регистры?

 

Вопрос не понятный: вас смущает, что вообще прерывание возникает? или что оно и должно возникать, но PR при этом нулевой?
Смущяет то, то оно не должно возникать, PR равен нулю, как и положенно, а вызов обработчика есть.

 

 

Суть в следующем: я настраиваю прерывание EXTI3 как переход из "1" в "0" на ноге РА3 и ухожу в стоп режим (PWR_STOPEntry_WFI). на ноге РА3 стоит "1"... ни каких дерганий и помаргиваний.... процессор выходит из стоп режима. Почему? Единственное разрешенное прерывание для выхода из стопа это переход на ноге РА3 из 1 в 0. Может вовсе не по EXTI3 выхожу из стопа.... поставил ловушку в обработчике прерывания EXTI3_IRQHandler(). Попадаю после стопа сразу в этот обработчик..... значит просыпаюсь по ексти3 всётаки.....

далее... сразу после пробуждения, ещё до входа в прерывание читаю EXTI->PR, там ноль. после настройки HSE разрешаю прерывания и тут же попадаю в обработчик EXTI3_IRQHandler(). Опять проверяю EXTI->PR. Там НОЛЬ!!! черт с ним, со стопом... потом разберусь.... вопрос в следующем - почему я попадаю в обработчик прерывания, когда флаг прерывания равен нулю? Если EXTI->PR == 0, то не было событий ни каких в эксти. Раз не было событий, какого лешего идет вызов обработчика?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А какие регистры?

Очевидно же: те, которые могут представлять интерес. Можно все. Не стесняйтесь, открывайте мануал и читайте про то, что такое NVIC, зачём он нужен, и как он работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очевидно же: те, которые могут представлять интерес. Можно все. Не стесняйтесь, открывайте мануал и читайте про то, что такое NVIC, зачём он нужен, и как он работает.
...ять.... знал бы прикуп, жилбы в рио как решить проблему и какие регистры помогут, сюда бы не обращался. Какой конкретно регистр в NVIC может сказать чем было вызвано прерывание? Их там не так много.

Interrupt set-enable registers (NVIC_ISERx) - этот? наврятли.

может это Interrupt clear-enable registers (NVIC_ICERx)? Из названия видно что не этот.

может быть вот этот "The IABR0-IABR2 registers indicate which interrupts are active.".... 512 в нем. это вроде как 9-ый бит в "1", т.е. 9-ое прерывание активно. 9-е прерывание это как раз EXTI Line3 interrupt. Но ПОЧЕМУ оно активно? В каком NVIC регистре конкретно посмотреть ПОЧЕМУ ПРЕРЫВАНИЕ СРАБОТАЛО?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ПОЧЕМУ ПРЕРЫВАНИЕ СРАБОТАЛО?

Похоже на чудеса. Попробуйте запретить прерывание для EXTI3 (точнее не разрешайте его в NVIC).

Может, у вас где-то в другом месте бага и управление как-то попадает в функцию EXTI3_IRQHandler().

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

может быть вот этот "The IABR0-IABR2 registers indicate which interrupts are active.".... 512 в нем. это вроде как 9-ый бит в "1", т.е. 9-ое прерывание активно. 9-е прерывание это как раз EXTI Line3 interrupt. Но ПОЧЕМУ оно активно? В каком NVIC регистре конкретно посмотреть ПОЧЕМУ ПРЕРЫВАНИЕ СРАБОТАЛО?

На самом деле я имел в виду исключить вариант, когда другое прерывание вызывает этот обработчик (кривая таблица векторов, например). Исключили.

Про EXTI и выход из Stop mode, увы, ничего не могу сказать, ибо не доводилось использовать. В мануале оно всё как-то хитровывернуто описано, разбираться лень.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте запретить прерывание для EXTI3 (точнее не разрешайте его в NVIC).

Может, у вас где-то в другом месте бага и управление как-то попадает в функцию EXTI3_IRQHandler().

Да я тоже думал что где-то НЕ из-за эксти падает в EXTI3_IRQHandler(). Но NVIC всётаки говорит что активное прерывание EXTI3 (спс scifi ;) ). Есть ещё мысль, что к EXTI3 подключено какоенить другое событие не только порт РА3? например RTC или какая нить другая периферия.... лан... буду разбираться...

 

Похоже на чудеса.
Согласен.... хоть проц перепаивай...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласен.... хоть проц перепаивай...

Может, оптимизация как-то мудрит и выкидывает переменную "a".

Как вы установили, что PR == 0 ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как вы установили, что PR == 0 ?

в статическую переменную записал EXTI->PR после выхода из стопа и после входа в прерывание.

 

ПОБЕДИЛ ЧУДО!!! Заработало!!! В 2-х словах - обработчик может быть вызван без флага прерывания, или это можно назвать отложенное прерывание. Если интересно... распишу...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ПОБЕДИЛ ЧУДО!!! Заработало!!! В 2-х словах - обработчик может быть вызван без флага прерывания, или это можно назвать отложенное прерывание. Если интересно... распишу...

Как правило есть два бита: периферийный и NVIC-овский.

Когда периферийный срабатывает, он устанавливает NVIC-овский.

Когда дело доходит до обработчика, NVIC-овский аппаратно сбрасывается (при выходе?),

а в обработчике нужно сбросить периферийный. Если делать это в самом конце, то

будет повторное вхождение в обработчик, но уже со сброшенным периферийным битом.

Поэтому всегда нужно проверять установку периферийного бита. И сбрасывать его как можно раньше,

а если сбрасываешь в конце обработчика, то перед выходом добавить NOP, а еще правильнее барьер (DSB?).

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2adnega, это всё известно и периферийный сбрасывается сразу же при входе в прерывание. подвох в другом месте был. в NVIC. вобщем при входе в стоп готовлю эксти3 для пробуждения, разрешаю прерывание от ексти3 и ухожу в стоп. после пробуждения сбрасываю флаг эксти3 и запрещаю прерывания от эксти3. Вот тут и грабля....

 

после выхода из стопа всего лиш запрещал прерывания, т.е. думал что строчки NVIC_DisableIRQ(EXTI3_IRQn); для запрета прерывания достаточно. Так то да, NVIC больше не вызывал обработчик, но нога РА3 дергалась и EXTI3_IRQn срабатывало и взводило флаг прерывания в EXTI, и флаг NVIC-овский, так называемый IRQn pending.

 

перед очередным стопом я сбрасывал флаг в EXTI (PR) и разрешал NVIC-ку прерывание. А у NVIC взведён и ждет IRQn pending. Он принудительно вызывал обработчик прерывания, не смотря на то, что у EXTI прерывания нет.

 

ps а сбросить IRQn pending в NVIC не получилось. Вроде NVIC_ClearPendingIRQ(EXTI3_IRQn) должен сбросить.... но он не сбрасывает. только вызов обработчика сбрасывает этот пендинг.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

после пробуждения сбрасываю флаг эксти3 и запрещаю прерывания от эксти3. Вот тут и грабля....

Может, NVIC-регистры не трогать, а запрет обработки делать на уровне EXTI ?

 

ps а сбросить IRQn pending в NVIC не получилось. Вроде NVIC_ClearPendingIRQ(EXTI3_IRQn) должен сбросить.... но он не сбрасывает. только вызов обработчика сбрасывает этот пендинг.

Я обычно делаю так: настраиваю периферию, но не разрешаю прерывание; настраиваю и разрешаю NVIC предварительно сбросив флаг от периферии;

разрешаю прерывание в периферии.

 

Запрещаю прерывания только на уровне периферии (например, при передаче по UART).

Запрещать/разрешать в NVIC давным-давно решил для себя считать источником потенциальных проблем (приоритеты, многопоточность,

правильные последовательности разрешения/запрещения).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может, NVIC-регистры не трогать, а запрет обработки делать на уровне EXTI ?
да кстати.... может вы правы... я тоже делаю все запреты/разрешения прерывания на уровне перефирии, например

 

USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART2, USART_IT_TC, DISABLE);

Но с EXTI первый раз свезался, нужен был стоп режим.... почему-то на уровень NVIC ушел. Спс за совет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...