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

Прерывание отрабатывает два раза вместо одного


Рекомендуемые сообщения

По приходящему на ножку A1 импульсу настроено прерывание. Прерывание должно отработать один раз и должно делать следующее: пауза 7 секунд, потом на 1,5 секунды открыть реле. Во время прерывания светодиод на плате гаснет и загорается в такт секундам. Код отрабатывает верно за исключением того, что прерывание отрабатывает 2 раза. Т.е. подали импульс, заморгал светодиод в течении 7ми секунд, потом щёлкнуло реле (открылось), затем опять щёлкнуло (закрылось), потом всё повторяется еще раз (7+1,5). В режиме дебага работает нормально. Пробовал отключать реагирование на прерывания во время его отработки:

disableInterruupts();
...
enableInterruupts(); 

но не помогает.

STM8S103F3P6

Код прерывания

Скрытый текст

INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3)
{
  disableInterrupts();
  int i = 0;
  TIM2_TimeBaseInit(TIM2_PRESCALER_32768, 61); // 1 second
  TIM2_Cmd(ENABLE);
  while(i<8){
    if (TIM2_GetFlagStatus(TIM2_FLAG_UPDATE) == SET) {
          TIM2_ClearFlag(TIM2_FLAG_UPDATE);
          GPIO_WriteReverse(GPIOB, GPIO_PIN_5);
          i++;
    }
  }
  TIM2_Cmd(DISABLE);
  i = 0;
  TIM2_TimeBaseInit(TIM2_PRESCALER_32768, 30); // 0,5 second
  TIM2_Cmd(ENABLE);
  GPIO_WriteHigh(GPIOC, GPIO_PIN_6);
  while(i<4){
    if (TIM2_GetFlagStatus(TIM2_FLAG_UPDATE) == SET) {
          TIM2_ClearFlag(TIM2_FLAG_UPDATE);
          GPIO_WriteReverse(GPIOB, GPIO_PIN_5);
          i++;
    }
  }
  TIM2_Cmd(DISABLE);
  GPIO_WriteLow(GPIOC, GPIO_PIN_6);
  enableInterrupts();
}

 

Код в main.c

Скрытый текст

#include "stm8s.h"

int main( void )
{
  GPIO_Init(GPIOA, GPIO_PIN_1, GPIO_MODE_IN_FL_IT);
  GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_OD_HIZ_SLOW);
  GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_SLOW);
  CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV128);
  CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV8);

  EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOA, EXTI_SENSITIVITY_FALL_ONLY);
  enableInterrupts();
 
   /* Infinite loop */
  while (1)
  {

  }
}

 

 

Изменено пользователем n_angelo
Ссылка на комментарий
Поделиться на другие сайты

Сброс флага прерывания по таймеру вижу, а по входу EXTI не заметил. В обработчике не делают такой большой код 8.5 сек. Лучше в обработчике по EXTI устанавливать флажок, а в основном цикле все действия.

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

14 минут назад, snn_krs сказал:

Сброс флага прерывания по таймеру вижу, а по входу EXTI не заметил. В обработчике не делают такой большой код 8.5 сек. Лучше в обработчике по EXTI устанавливать флажок, а в основном цикле все действия.

В stm8s нет флага выхода из прерывания. Я сам удивился, когда пытался долго его найти. В коде я сбрасываю флаг переполнения таймера для подсчёта секунд.

Контроллер больше не будет ничего делать — это законченная программа, поэтому я пренебрёг правилу быстрой отработки прерывания.

Кстати, нет мыслей почему два раза входит в прерывание?

UPD:

Проверил весь порт A осциллографом. Повторных импульсов нет. Значит проблема в коде.

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Есть флаг входа в прерывание по EXTI это в регистре EXTI_SR1. Его надо сбросить в прерывании командой типа

TIM2_ClearFlag(TIM2_FLAG_UPDATE);

Только для EXTI. Я пишу для STM32 в Кейле поэтому точно сказать не могу. Если этот флаг не сбросить прерывание будет вызываться постоянно. Почему у вас только два раза не знаю.

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

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

9 часов назад, snn_krs сказал:

Есть флаг входа в прерывание по EXTI это в регистре EXTI_SR1. Его надо сбросить в прерывании командой типа

TIM2_ClearFlag(TIM2_FLAG_UPDATE);

Только для EXTI. Я пишу для STM32 в Кейле поэтому точно сказать не могу. Если этот флаг не сбросить прерывание будет вызываться постоянно. Почему у вас только два раза не знаю.

Поверьте, этого регистра в STM8S просто нет. Я по привычке хотел обнулить флаг, но статус-регистра там нет.

Не знаю как в STM32, а в STM8L, прерывание отработает и зависнет в конце прерывания, до тех пор пока не сбросить флаг, т.е. повторяться оно не будет.

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

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

55 минут назад, Vitemk сказал:

Дребезг?

я сначала тоже подумал, что дребезг, но для этого у прерывания должно быть что-то вроде стека, который складывает дребезг в очередь, пока текущее прерывание отрабатывает. Но такого стека нет – в течении одного прерывания, другое такое же прийти не может, если ты этого явно не запрограммировал.

В общем, перенёс я код в основной цикл, а в прерывании просто включаю таймер. Теперь всё работает как надо. Может быть какой-то механизм смотрит за длительностью прерывания, ну или просто гон контроллера.

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

У Вас странное представление о прерываниях. Дело не в том, что возникло новое прерывание во время обработчика, а в том, когда гасится флаг. Если в начале, то новое прерывание будет исполнено немедленно после выхода из обработчика, а если в конце, то флаг будет сброшен и никакого нового вызова ISR не будет.

Все это так, если нет разрешенных вложенных прерываний. Но это совсем другая история.

ЗЫ. А что там у Вас за бред с запретом-разрешением прерываний в обработчике? Это зачем? Это кто Вас этому научил?

Изменено пользователем my504

戦う前に相手のベルトの色に注目

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

6 часов назад, my504 сказал:

У Вас странное представление о прерываниях. Дело не в том, что возникло новое прерывание во время обработчика, а в том, когда гасится флаг. Если в начале, то новое прерывание будет исполнено немедленно после выхода из обработчика, а если в конце, то флаг будет сброшен и никакого нового вызова ISR не будет.

Все это так, если нет разрешенных вложенных прерываний. Но это совсем другая история.

ЗЫ. А что там у Вас за бред с запретом-разрешением прерываний в обработчике? Это зачем? Это кто Вас этому научил?

Я всегда думал, что очистка Pending Bit инициирует выход из прерывания. Сегодня проверю. Получается, если этого статус-регистра не существует, то любое прерывание может прервать текущее? (Если не настраивать специально приоритеты).


На два раза перечитал свои сообщения. Где я говорил о запрете/разрешении прерывании? Процитируйте.

 

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

INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3)
{
  disableInterrupts();
....................
  enableInterrupts();
}

Это Ваш код? 

Вложенные прерывания невозможно запретить таким методом. Входные скобки обработчиков генерируют сохранение контекста, а выходные восстановление контекста и специальную команду выхода из прерывания IRET. Если вложенные прерывания разрешены, то между  входом в ISR и строкой  disableInterrupts(), а также между строкой enableInterrupts() и выходом более чем достаточно времени для повторного входа в прерывание. А если вложенные прерывания запрещены, то переход по вектору ISR АВТОМАТИЧЕСКИ гасит  глобальное разрешение прерываний, а команда выхода из ISR  - IRET (закрывающая скобка) так же автоматически его разрешает. В ОДНОМ МАШИННОМ ЦИКЛЕ. То есть повторный вход полностью исключен.

Компилятор вместе с линкером обеспечивают автоматическую генерацию специфического кода обработчиков прерываний и не требуют ничего кроме гашения флагов периферийных прерываний, которые собственно и генерируют само прерывание. Хотя некоторые периферийные модули сбрасывают флаги автоматически и даже этим можно не заморачиваться.

А вообще, ознакомьтесь с мануалом по программированию выбранного Вами МК:

https://www.st.com/content/ccc/resource/technical/document/programming_manual/43/24/13/9a/89/df/45/ed/CD00161709.pdf/files/CD00161709.pdf/jcr:content/translations/en.CD00161709.pdf

ЗЫ. Я сходу не нашел инструмента запрета вложенности прерываний в STM8. Не исключено, что его нет вообще, ну кроме приоритетов. То есть эти две Ваших строки вообще бессмысленны.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

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

1 час назад, my504 сказал:

INTERRUPT_HANDLER(EXTI_PORTA_IRQHandler, 3)
{
  disableInterrupts();
....................
  enableInterrupts();
}

Это Ваш код? 

Вложенные прерывания невозможно запретить таким методом. Входные скобки обработчиков генерируют сохранение контекста, а выходные восстановление контекста и специальную команду выхода из прерывания IRET. Если вложенные прерывания разрешены, то между  входом в ISR и строкой  disableInterrupts(), а также между строкой enableInterrupts() и выходом более чем достаточно времени для повторного входа в прерывание. А если вложенные прерывания запрещены, то переход по вектору ISR АВТОМАТИЧЕСКИ гасит  глобальное разрешение прерываний, а команда выхода из ISR  - IRET (закрывающая скобка) так же автоматически его разрешает. В ОДНОМ МАШИННОМ ЦИКЛЕ. То есть повторный вход полностью исключен.

Компилятор вместе с линкером обеспечивают автоматическую генерацию специфического кода обработчиков прерываний и не требуют ничего кроме гашения флагов периферийных прерываний, которые собственно и генерируют само прерывание. Хотя некоторые периферийные модули сбрасывают флаги автоматически и даже этим можно не заморачиваться.

А вообще, ознакомьтесь с мануалом по программированию выбранного Вами МК:

https://www.st.com/content/ccc/resource/technical/document/programming_manual/43/24/13/9a/89/df/45/ed/CD00161709.pdf/files/CD00161709.pdf/jcr:content/translations/en.CD00161709.pdf

ЗЫ. Я сходу не нашел инструмента запрета вложенности прерываний в STM8. Не исключено, что его нет вообще, ну кроме приоритетов. То есть эти две Ваших строки вообще бессмысленны.

Да, простите, уже и забыл про этот код. В текущей версии удалил его. Я его взял из SPL-библиотеки от STM для STM8S в дефайнах для IAR.

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

Не цитируйте предыдущее сообщение, милейший, а то Вы быстро утратите право писать свои на некоторый предусмотренный Правилами срок. Это иногда неприятно... )))

По делу. Вы в крайних своих сообщениях как то головоломно излагали соображения нащщет прерываний и механизма их функционирования. Мой спич был в основном об этом. Ваши представления  в высшей мере странные...

Изменено пользователем my504

戦う前に相手のベルトの色に注目

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

28.02.2020 в 08:51, n_angelo сказал:

В общем, перенёс я код в основной цикл, а в прерывании просто включаю таймер. Теперь всё работает как надо. Может быть какой-то механизм смотрит за длительностью прерывания, ну или просто гон контроллера.

4 дня назад я делал под заказ одно устройство на Atmega8. Принцип работы схож с Вашим. Посчитал что контроллер больше ничего делать не будет, поэтому запихнул весь код обработки в системное прерывание. Так вот при отладке удивился увидев точно ВАШУ ситуацию. Код отработал два раза. Нажимаешь кнопку и код последовательно проходил цикл , а потом небольшая задержка и повтор. Как-бы код очень простой и я дошел вывода что даже при большой желании и наличии места очень НЕ  правильно засовывать задержки в обработчик прерывания. Изменил три строчки вынеся код в главный цикл, а в обработчике установил флаг - вуаля ! Все работает отлично!!!

"Мы все учились понемногу, чему-нибудь и как-нибудь...")

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

но причина повторного запуска так и не названа ...

Мудрость приходит вместе с импотенцией...

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

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

Код не может зависать в прерывании, только если в обработчике нет бесконечного цикла. Однако код может немедленно СНОВА зайти в прерывание после выхода из него, если флаг прерывания либо остался поднятым, либо был поднят снова за время исполнения обработчика.

戦う前に相手のベルトの色に注目

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

12 часов назад, my504 сказал:

либо был поднят снова за время исполнения обработчика.

Значит вполне может быть дребезг контактов в процессе длительного выполнения обработчика. 

"Мы все учились понемногу, чему-нибудь и как-нибудь...")

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

на сколько я знаю, флаг сбрасывается аппаратно при выходе из обработчика.

поэтому во время работы обработчика поднятый флаг еще раз поднять невозможно.

Мудрость приходит вместе с импотенцией...

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

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

10 часов назад, Starichok сказал:

флаг сбрасывается аппаратно при выходе из обработчика.

те у АВР если произойдет событие в момент работы обработчика , событие будет потеряно?

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

4 минуты назад, IMXO сказал:

у АВР если произойдет событие в момент работы обработчика , событие будет потеряно?

Нет. @Starichok не прав: флаг сбрасывается ПРИ ВХОДЕ в обработчик, точнее, сразу при переходе на соответствующий вектор, в обработчике флаг уже не стоит. Если флаг будет повторно установлен во время работы обработчика, после выхода из него, если нет других более приоритетных запросов, после исполнения 1 команды снова произойдет вызов этого обработчика...

Это одна из причин, по которым с осторожностью надо разрешать прерывания внутри обработчика прерывания.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

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

9 часов назад, ARV сказал:

Нет. @Starichok не прав: флаг сбрасывается ПРИ ВХОДЕ в обработчик

прошу извинить, писал по памяти, но в памяти моей это перепуталось ...

Мудрость приходит вместе с импотенцией...

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

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...