|
Прерывание EXTI |
|
|
|
Nov 5 2016, 21:05
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(juvf @ Nov 5 2016, 13:30)  Почему попадаю в прерывание. Как это отловить? Видимо, вы его разрешили и сконфигурировали - вот и попадаете. Вопрос не понятный: вас смущает, что вообще прерывание возникает? или что оно и должно возникать, но 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); } }
|
|
|
|
|
Nov 6 2016, 08:57
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(scifi @ Nov 5 2016, 16:39)  Остановиться в обработчике прерывания, посмотреть регистры 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, то не было событий ни каких в эксти. Раз не было событий, какого лешего идет вызов обработчика?
|
|
|
|
|
Nov 6 2016, 10:06
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(scifi @ Nov 6 2016, 14:18)  Очевидно же: те, которые могут представлять интерес. Можно все. Не стесняйтесь, открывайте мануал и читайте про то, что такое 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 регистре конкретно посмотреть ПОЧЕМУ ПРЕРЫВАНИЕ СРАБОТАЛО?
|
|
|
|
|
Nov 6 2016, 10:51
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(adnega @ Nov 6 2016, 15:37)  Попробуйте запретить прерывание для EXTI3 (точнее не разрешайте его в NVIC). Может, у вас где-то в другом месте бага и управление как-то попадает в функцию EXTI3_IRQHandler(). Да я тоже думал что где-то НЕ из-за эксти падает в EXTI3_IRQHandler(). Но NVIC всётаки говорит что активное прерывание EXTI3 (спс scifi  ). Есть ещё мысль, что к EXTI3 подключено какоенить другое событие не только порт РА3? например RTC или какая нить другая периферия.... лан... буду разбираться... Цитата Похоже на чудеса. Согласен.... хоть проц перепаивай...
|
|
|
|
|
Nov 6 2016, 12:27
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(juvf @ Nov 6 2016, 15:00)  ПОБЕДИЛ ЧУДО!!! Заработало!!! В 2-х словах - обработчик может быть вызван без флага прерывания, или это можно назвать отложенное прерывание. Если интересно... распишу... Как правило есть два бита: периферийный и NVIC-овский. Когда периферийный срабатывает, он устанавливает NVIC-овский. Когда дело доходит до обработчика, NVIC-овский аппаратно сбрасывается (при выходе?), а в обработчике нужно сбросить периферийный. Если делать это в самом конце, то будет повторное вхождение в обработчик, но уже со сброшенным периферийным битом. Поэтому всегда нужно проверять установку периферийного бита. И сбрасывать его как можно раньше, а если сбрасываешь в конце обработчика, то перед выходом добавить NOP, а еще правильнее барьер (DSB?).
|
|
|
|
|
Nov 6 2016, 12:50
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
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) должен сбросить.... но он не сбрасывает. только вызов обработчика сбрасывает этот пендинг.
|
|
|
|
|
Nov 6 2016, 13:59
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(juvf @ Nov 6 2016, 15:50)  после пробуждения сбрасываю флаг эксти3 и запрещаю прерывания от эксти3. Вот тут и грабля.... Может, NVIC-регистры не трогать, а запрет обработки делать на уровне EXTI ? Цитата(juvf @ Nov 6 2016, 15:50)  ps а сбросить IRQn pending в NVIC не получилось. Вроде NVIC_ClearPendingIRQ(EXTI3_IRQn) должен сбросить.... но он не сбрасывает. только вызов обработчика сбрасывает этот пендинг. Я обычно делаю так: настраиваю периферию, но не разрешаю прерывание; настраиваю и разрешаю NVIC предварительно сбросив флаг от периферии; разрешаю прерывание в периферии. Запрещаю прерывания только на уровне периферии (например, при передаче по UART). Запрещать/разрешать в NVIC давным-давно решил для себя считать источником потенциальных проблем (приоритеты, многопоточность, правильные последовательности разрешения/запрещения).
|
|
|
|
|
Nov 6 2016, 14:07
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(adnega @ Nov 6 2016, 18:59)  Может, NVIC-регистры не трогать, а запрет обработки делать на уровне EXTI ? да кстати.... может вы правы... я тоже делаю все запреты/разрешения прерывания на уровне перефирии, например Код USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); USART_ITConfig(USART2, USART_IT_TC, DISABLE); Но с EXTI первый раз свезался, нужен был стоп режим.... почему-то на уровень NVIC ушел. Спс за совет.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|