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

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


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

По приходящему на ножку 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
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

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

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

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

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

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

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

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

UPD:

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

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

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

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

TIM2_ClearFlag(TIM2_FLAG_UPDATE);

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

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

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

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

TIM2_ClearFlag(TIM2_FLAG_UPDATE);

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

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

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

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

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 пользователей онлайн

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

    • У меня больше всего вопросов вызвала необычная схема обеспечения отрицательного питания. Автор этой обстоятельной заметки пишет: For this supply to work correctly, the transformer must have a secondary voltage of at least 18V RMS.  Почему? Что будет не так с отрицательным питанием, если напряжение на трансформаторе будет меньше 18В?   https://tinyurl.com/23mlwxtt - я в простейшей эмуляции ставлю 12В пикового напряжения для трансформатора и на стабилитроне все как положено: -5.6В.
    • Согласен, очень криво объяснил. Это работа трёх вольтовой линии, просто на диод шотки сдвоенный, на один анод приходит сигнал напрямую с трансформатора, а на второй через дроссель. Вольт/деление 5 вольт в клетке, тайминг по моему 10 МС. Третья фотография это сигнал на катодах уровень земли ровно по центру экрана. Но все линии по итогу в порядке 3.3 в, 5, в, 12 в и -12 в. Нагрузить все линии не могу сразу ,так как тут же выгорают транзисторы (имеется нагрузка 250 ватт по 10 ампер на каждую линию за исключением-12в), поэтому нагружаю 3.3 вольтовую линию на 10 ампер,  подключаю переменный резистор 50 ватт на 15 ом на 5 вольтовую линию и постепенно довожу до той той картины с перекосом (это гдето  50 ватт общее). По поводу микросхемы, вверху имеется скрин где между импульсами проскакивает мини импульс, если так можно сказать, он проскакивает и на одной  и на второй ноге (7,8). Микросхема не tl 494, а lw4933/abx942.1/c9421646. Далее они приходят на базы транзисторов 945g  коллекторы этих транзисторов соединены с  выводами трансформатора. Просто схема типовая, легче мне кажется просто привести фото самого блока, для тех кто разбирается будет гораздо информативне.  Диод шотки по 12 вольтовой линии был подгоревший, заменил на донора. Приводить скрины не буду что бы не захламлять тему. В итоге, пока все так же, при достижении определенной нагрузки суммарно где-то 50 ватт, появляется этот "выброс и перекос". По этому имеются мысли на два варианта, это микросхема , этот мини импульс между периодами, на низкой нагрузке особо не влияет, но при достижении определенной приводит с самовозбуждению входной цепи и непроизвольному открытию транзистора нижнего плеча. Либо дело в "горячей части", плавающий дефект в обвязке силовых ключей.  Спасибо за ответ.
    • @Gomerchik а вы контролировали как меняется уровень сигнала на А1 ардуины?
    • Спасибо за совет. Автором данного проекта я не являюсь, мне нужно было воссоздать уличный датчик для метеостанции взамен пропавшего(( Из разного найденного в интернете этот проект работает с моей станцией Орегон (спасибо автору). В понедельник попробую последовать Вашему совету. Но все равно куча непоняток  как блин это работает)) Если дело в неправильной отправки команды, то как на это влияет подключение датчика температуры? Если совсем не подключать таймер, то передача идет один раз (как и прописано в программе), станция принимает и отображает, но минут через сколько-то естественно станция уже ни чего не показывает, но с таймером питание полностью не пропадает с ардуинки, но передача сигнала каким-то образом работает по таймеру.  В моем понимании данная команда подается один раз потому, что таймер должен отключать питание МК после передачи сигнала и каждые 43 сек снова подавать питание (так того требует станция).  Ардуино передает показания температуры отключается полностью и 43 секунды мк не работает.  Сейчас у меня питание пока сделано на подпитке от солнечной батареи, но пару пасмурных дней и аккумулятор съедается до отключения(
    • thickman Так и сделаю. Вытащу из бу БП.  Буду знать, как отличить. Благодарю. Заменил транзисторы на IRFB20N50K. Картина стала, совсем другой.  Похоже трудность не в драйвере, на момент подвозбуда, переходные процессы, в нем, завершены. Увеличил затворные резисторы до 50ом, стало немного лучше.  Не понятно, почему верхний ключ греется несколько сильнее. Возможно, стоит посмотреть ток в коллекторе.  Снабберные емкости временно удалил, изменений не произошло.  Замена ТГР на другой, на кольце MSTN-16A-TH, так же, результата не принесла.   irfb20n50k.pdf
    • А что нить из ассортимента активных щупов производства СССР..))
  • Похожий контент

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