alexf 0 28 сентября, 2016 Опубликовано 28 сентября, 2016 (изменено) · Жалоба Переношу код с древнего 8051 на STM32F070. Все бы ничего, но есть потенциальная ловушка. Внешнее прерывание от другого чипа. Допустим оно пришло, а пока процессор занят обработкой, пришло второе. STM32 не заметит, поскольку реагирует на edge а не level, kak 8051 в данном приложении. Вероятнось не велика, но все равно стремно. Так вот идея такая. Запускать таймер (их как грязи!), так чтобы он работал только при низком уровне на ножке. Сбрасываем про обработке edge. Если вдруг нога осталась на 0, а фронт не отслежен, таймер бысто досчитает до сколько-то и даст свое прерывание, которое можно обработать тем же кодом что и обычно. Что скажут знатоки? Или просто проверять уровень на ножке перед выходом из обработчика? Можно читать уровень ножки назначенной EINT? Изменено 20 декабря, 2022 пользователем haker_fox Уточнил название темы, добавил теги, переместил в нужный раздел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Почитайте про Pending bit в прерываниях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 208 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Переношу код с древнего 8051 на STM32F070. Все бы ничего, но есть потенциальная ловушка. Внешнее прерывание от другого чипа. Допустим оно пришло, а пока процессор занят обработкой, пришло второе. STM32 не заметит, поскольку реагирует на edge а не level, kak 8051 в данном приложении. Вероятнось не велика, но все равно стремно. А в каком случае "оно" пришло? Это внешнее прерывание. Что Вы при этом должны сделать? У Вас второй импульс по ноге прерывания внешнее устройство может выдать даже когда не обслужено ещё первое прерывание? Или оно держит уровень до тех пор, пока не будет обслужено (устранена причина вызвавшая прерывание)? Если первое - то что в этом случае тогда делает 8051? Ведь он также пропустит второй импульс. Если второе - никаких проблем. Или вам важно само количество импульсов на ноге запроса прерывания? Тогда надо их подавать не на вход внешнего прерывания, а на счётный вход таймера. Почитайте про Pending bit в прерываниях. Товарищу скорее надо читать про конфигурирование внешних прерываний в его МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Или просто проверять уровень на ножке перед выходом из обработчика? Можно читать уровень ножки назначенной EINT? я бы так и делал можно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexf 0 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба А в каком случае "оно" пришло? Это внешнее прерывание. Что Вы при этом должны сделать? У Вас второй импульс по ноге прерывания внешнее устройство может выдать даже когда не обслужено ещё первое прерывание? Или оно держит уровень до тех пор, пока не будет обслужено (устранена причина вызвавшая прерывание)? Если первое - то что в этом случае тогда делает 8051? Ведь он также пропустит второй импульс. Если второе - никаких проблем. Или вам важно само количество импульсов на ноге запроса прерывания? Тогда надо их подавать не на вход внешнего прерывания, а на счётный вход таймера. Конкретный пример. Есть внешний UART ( не в этом проекте, но давным давно наткнулся на такие грабли, поэтому сейчас осторожничаю). Прерывания от приема и передачи асинхронны и ножка одна. Получил прерывание. Прочитал (у UARTa) регистр и понял, что передача. Обслужил. А ножка еще стоит на 0. Если level triggered, я сразу попаду опять в то же прерывание и из регистра прочту, что причина - прием. Тоже обслужу. Тогда нога вернется в 1. А если прерывание только по фронту, он может пропасть, если сигнал придет после того, как я прочитал в регистре, что только один источник. Впрочем я уже узнал, что можно читать состояние порта не переключая ноги с EINT на GPIO_IN. Так что все просто: перед выходом убедиться, что уровень не 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gerber 8 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Впрочем я уже узнал, что можно читать состояние порта не переключая ноги с EINT на GPIO_IN. Так что все просто: перед выходом убедиться, что уровень не 0. При этом не забыть, что очистку бита прерывания надо делать ДО проверки уровня "не 0", а ещё лучше, в самом начале обработчика прерывания, а не перед выходом из него, как многие делают. В последнем случае остается вероятность того, что прерывание возникнет между проверкой уровня "не 0" и сбросом бита прерывания, что чревато тем, что больше в edge-triggered обработчик программа вообще не попадёт никогда. Если же бит прерывания сброшен, и обработчик убедился, что на входе лог. 1, то даже если прерывание произойдет до выхода из обработчика, то просто будет повторный вход в него с нормальной обработкой причины и т. д. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 208 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Получил прерывание. Прочитал (у UARTa) регистр и понял, что передача. Обслужил. А ножка еще стоит на 0. Читать регистр статуса (и обслуживать прерывания) надо пока в нём не останется активных запросов, в цикле все обслужить. Это корректный порядок обработки для UART, не зависящий от того, как фиксируются прерывания - по фронту или уровню. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexf 0 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба При этом не забыть, что очистку бита прерывания надо делать ДО проверки уровня "не 0" Естественно. Чтобы избежать гонки, AKA race condition. Всем спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться