Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.62/78: Рейтинг темы: голосов - 78, средняя оценка - 4.62
OBB
0 / 0 / 0
Регистрация: 25.03.2016
Сообщений: 4
1

Вызов подпрограммы из обработчика события

28.03.2016, 15:01. Просмотров 14137. Ответов 53
Метки нет (Все метки)

Добрый день!

Пишу простенькую программу "мигающий светодиод".

Реализовал с использованием таймера 0.

Код
.def temp = r16 ;рабочая переменная
.def counter = r17 ;счетчик
.def max_counter_value = r18 ;счетчик
.def currentValue = r19 ;результат
;============ прерывания ============
rjmp RESIT ;RESIT External Pin, Power-on Riset, Brown-out Riset, Watchdog Riset
reti ;INT0 External Ymtirrupt Request 0
reti ;PCINT0 Pin Change Ymtirrupt Request 0
reti ;TIMER1_COMPA Timer/Counter1 Compare Match A
reti ;TIMER1_OVF Timer/Counter1 Overflow
rjmp TIMER0_OVF;TIMER0_OVF Timer/Counter0 Overflow
reti ;EE_RDY EEPROM Ready
reti ;ANA_COMP Analog Comparator
reti ;ADC ADC Conversion Complete
reti ;TIMER1_COMPB Timer/Counter1 Compare Match B
reti ;TIMER0_COMPA Timer/Counter0 Compare Match A
reti ;TIMER0_COMPB Timer/Counter0 Compare Match B
reti ;WDT Watchdog Time-out
reti ;USI_START USI START
reti ;USI_OVF USI Overflow

RESIT: ;начальная инициализация
ldi temp,low(ROMEND) ;загрузка указателя стека
out SPL,temp

LDI currentValue, $00

ldi temp, $05
out TCCR0B,temp

ldi max_counter_value, $33

CLR temp
OUT SREG, temp

LDI temp, $FF
OUT DDRB, temp

clr counter ;очищаем счетчик
clr temp
ldi temp,(1<<TOIE0) ;разр. прерывания Timer0
out TIMSK,temp

sei ;разрешаем прерывания

Gcykle: ;основной пустой цикл
rjmp Gcykle

TIMER0_OVF:;обработчик прерывания Timer0
yms counter ;в каждом прерывании увеличиваем на 1
CP counter, max_counter_value
BRSH ChangeState
;некий код который надо выполнить даже в случае перехода на ChangeState
reti ;конец обработки прерывания таймера

ChangeState:
LDI counter, $00
COM currentValue
OUT PORTB, currentValue
reti
Собственно все работает, но возник вопрос с ветвлением. После выполнения ChangeState программа возвращается в пустой цикл. А если требуется возврат в обработчик прерывания в то же место откуда произошел вызов, то как это реализовать?
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.03.2016, 15:01
Ответы с готовыми решениями:

Вызов обработчика события
есть два обработчика события button1.Click и button2.Click . Как из button1.Click вызвать...

Вызов обработчика события.
Можно ли из одного обработчика события, например: void __fastcall TForm1::Button1Click(TObject...

Ручной вызов обработчика события
Здравствуйте, никак не могу разобраться с вызовом метода. void Grid_ManipulationStarting(object...

Косвенный вызов DoEvents() из обработчика события?
В одном приложении столкнулся со следующим явлением : программа сработала так, как если бы событие...

Вызов единственного обработчика события при переопределении
Все привет! Вопрос по теории. Можно ли как-то сделать так, чтобы при перекрытии обработчика события...

53
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
05.04.2016, 11:07 41
[QUOTE="dymyurk1978"][QUOTE="YTYOUT"]
Просто какая то зашоренность.
Вашем случае использовать прерывание , вообще нонсенс. Тем более что времени на всё хватает
Не факт. Не каждая итерация основного цикла выполняется строго определенное время. Сложились условия, выполнили быстро. Сложились другие условия, выполнились долгие задачи.
А так да, анализируем выполнение каждой функции. Если времени вагон, от прерываний можно отказаться.
Чего ради мне городить огород с флагами, когда я определенно знаю что интервала между импульсами мне за глаза хватит оттарабанить весь алгоритм обсчёта этого самого интервала и и "перевести" его в формат ЖК.
Факт
На то он и ассемблер, что бы не зажиматься в рамках постулатов, а использовать гибкость языка.
0
Пагранист
0 / 0 / 0
Регистрация: 09.08.2014
Сообщений: 96
05.04.2016, 21:07 42
[QUOTE="YTYOUT"][QUOTE="Цитата:[/QUOTE]
Просто какая то зашоренность.
Вашем случае использовать прерывание , вообще нонсенс. Тем более что времени на всё хватает
Вы считаете в моём случае надо порт бомбить бесконечным циклом. Только бы в прерывания не лезть?
В моём случае я его и за прерывание не держу. Есть в контроллере удобная фишка - реакция на фронт сигнала. А то что к нему прерывание прикручено болтами не моя прихоть. Но уж прикручено так чего не пользовать. Это как пепельница в машине у некурящего. Она есть, он в ней жвачку держит. Но чисто концептуально, жвачка в пепельнице - фу, да как можно!
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
05.04.2016, 22:08 43
А зачем лезть , только потому, что случайно под руку подвернулась фишка.
Чем по Вашему отличается rjmp PC от sbis Port,Pin rjmp pc-1
0
dimyurk1978
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 3,047
05.04.2016, 22:19 44
Цитата Сообщение от Пагранист
Вы считаете в моём случае надо порт бомбить бесконечным циклом. Только бы в прерывания не лезть?
Не обязательно бомбить вход. Если вы говорите что времени навалом, то вход можно проверять на каждой итерации основного цикла. Опять же тут все зависит от времянок.
Но долго сидеть в прерывании не принято. Выставил флаг, в основном цикле проверяем флаг.
0
05.04.2016, 22:19
Пагранист
0 / 0 / 0
Регистрация: 09.08.2014
Сообщений: 96
06.04.2016, 01:02 45
Цитата Сообщение от dymyurk1978
Не обязательно бомбить вход. Если вы говорите что времени навалом, то вход можно проверять на каждой итерации основного цикла. Опять же тут все зависит от времянок.
Но долго сидеть в прерывании не принято. Выставил флаг, в основном цикле проверяем флаг.
Мы друг с другом совершенно о разном. Вы пытаетесь мне доказать что на всё нужно смотреть через призму многозадачности. Я пытаюсь вам сказать что в любом правиле есть исключения. Думаю каждый останется при своём мнении. Поэтому со своей стороны заканчиваю спор.
0
Otixomdr_1
0 / 0 / 0
Регистрация: 28.06.2010
Сообщений: 211
08.04.2016, 02:07 46
Цитата Сообщение от dymyurk1978
Цитата Сообщение от Otixomdr_1
Это все для начинающих.
У имеющих некоторый опыт - никакой лапши и путаницы, никакой «игры с кубиками», никаких сносов всей конструкции, никаких «тщательных отслеживаний срыва стека» и т.д.
Все проще. Надо только соблюдать некоторые правила написания программы.
Вы либо вообще на асме не пишете, либо небольшой опыт, либо маленькие проектики.
На обычном асме писать трудно и нудно, думаю, это анахронизм, пишу на макроассемблере.
Тут у людей уровень разный и понятие маленький проект тоже разное.

Цитата Сообщение от Пагранист
Думаю не стоит так категорично. Подходы могут быть разные. На то он и ассемблер, что бы не зажиматься в рамках постулатов, а использовать гибкость языка. Простой пример. Тахометр с выводом на ЖК. Импульс с движка - прерывание. Чего ради мне городить огород с флагами, когда я определенно знаю что интервала между импульсами мне за глаза хватит оттарабанить весь алгоритм обсчёта этого самого интервала и и "перевести" его в формат ЖК. А потом уже вылезти из прерывания и оставшееся время отдать ЖК, кнопкам и т.п.
Конечно, подходы могут быть разные и гибкость и простота ассемблера – большое дело.
Поэтому пишу на асме.
На мой взгляд, делать что-то серьезное в прерывании чревато. В простых проектах, может, и сойдет, а в серьезных можно получить проблемы.
Можно испортить переменную случайным и трудно определяемым образом.
Или при какой-нибудь очередной модернизации (увеличили скорость движка, увеличили число импульсов на оборот движка, ввели дополнительную обработку сигнала) может не хватить времени на обработку. Зачем закладывать такую мину.
Так что сейчас в прерывании только ставлю флаг или минимально необходимые действия.
Может быть, и есть случаи, когда в прерывании необходини сложная обработка, но пока не сталкивался.
0
инкер
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
08.04.2016, 06:39 47
Цитата Сообщение от Otixomdr_1
На мой взгляд, делать что-то серьезное в прерывании чревато. В простых проектах, может, и сойдет, а в серьезных можно получить проблемы.
Можно испортить переменную случайным и трудно определяемым образом.
Или при какой-нибудь очередной модернизации (увеличили скорость движка, увеличили число импульсов на оборот движка, ввели дополнительную обработку сигнала) может не хватить времени на обработку. Зачем закладывать такую мину.
Так что сейчас в прерывании только ставлю флаг или минимально необходимые действия.
Может быть, и есть случаи, когда в прерывании необходини сложная обработка, но пока не сталкивался.
КМК опасения при работе с прерываниями слишком преувеличены, особенно в контроллерах, где есть аппаратная защита от вложенности, как в АВР. Как при выполнении обычного кода нужно следить, чтобы не испртить данные, так и при выполнении подпрограмм, включая обработчик прерывания. Во втором случае в определенной степени даже проще - все, чем намерен пользоваться (регистры) - сохрани, не задумываясь "а оно еще нужно, или можно затереть", а потом верни на место.

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

Правда есть еще один универсальный и волшебный способ - применить СТМ и забыть о проблемах.
0
Otixomdr_1
0 / 0 / 0
Регистрация: 28.06.2010
Сообщений: 211
12.04.2016, 21:45 48
Цитата Сообщение от инкер
КМК опасения при работе с прерываниями слишком преувеличены, особенно в контроллерах, где есть аппаратная защита от вложенности, как в АВР. Как при выполнении обычного кода нужно следить, чтобы не испртить данные, так и при выполнении подпрограмм, включая обработчик прерывания. Во втором случае в определенной степени даже проще - все, чем намерен пользоваться (регистры) - сохрани, не задумываясь "а оно еще нужно, или можно затереть", а потом верни на место.
С этим все понятно.
Я писал про «порчу» переменных, вызванных спецификой работы прерывания.
Скажем, в указанной программе тахометра основная программа начала работу с 2-х байтной переменной V – скорость движка (например, для расчета следящей системы). Скажем, V в шестнадцатеричном виде равно 01 00. Пусть программа считала старший байт 01, и в это время произошло прерывание.
Пусть в прерывании было рассчитано новое значение V, равное 00 FF.
Затем основная программа возьмет младший байт и получит значение V, равное 01 FF.
Получается ошибка. Вероятность такого попадания прерывания может быть очень мала, поэтому очень редко система будет дергаться. В сложных системах отыскать такую ошибку бывает непросто.
При простой установке флага в прерывании такой проблемы практически нет.
Цитата Сообщение от инкер
Особенности начинают проявляться при дефиците времени, когда возникает необходимость обработки события, когда еще не завершена обработка предыдущего. Но к программированию это имеет мало отношения, а больше к физическому смыслу - допустимо ли отбросить недоделанную обработку и начать новую, или наоборот, обязательно завершить, или организовать подсчет вызовов (а тут однобитовым флагом не обойтись) и потом обработать все, опять же если это имеет физический смысл.
Это интересный вопрос. Ситуации бывают разные, наверно, общего решения нет.
Поскольку прерывания несколько проблематичны, стараюсь, по возможности от них уходить. Либо МК сам проводит опрос, либо, в сложных случаях, удобней установить отдельный МК, выполняющий отдельную функцию.
В этом плане у меня, в основном, реализуется вариант «отбросить недоделанную обработку», называю это - отрезать ветку. Тут все просто. По установленному в прерывании флагу происходит возврат на самый верхний уровень (в элиту), где и производится обработка прерывания. Тут никаких проблем со стеком и прочим. Только надо разделить переменные элиты и ветки и передачу переменных из ветки в элиту проводить в подпрограмме ниже элиты.
Цитата Сообщение от инкер
Правда есть еще один универсальный и волшебный способ - применить СТМ и забыть о проблемах.
Можно сказать, я и на AVR «забыл» о таких проблемах.
0
инкер
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
13.04.2016, 13:21 49
Цитата Сообщение от Otixomdr_1
Я писал про «порчу» переменных, вызванных спецификой работы прерывания.
Скажем, в указанной программе тахометра основная программа начала работу с 2-х байтной переменной V ...
Проблема с вмешательством прерывания не ограничена только ситуацией с двушаговым чтением переменной, здесь просто на момент чтения ставится общий запрет прерываний или на конкретное, связанное с данной переменной. Бывает программа обработки достаточно длинная с несколькими обращениями к одной и то же переменной, длительный запрет прерываний может повредить корректности работы программы в целом и приходится работать через регистр-посредник, куда читается состояние таймера один раз на весь цикл обработки. Да, результат получается немного устаревшим, но без безобразий.

Упоминание СТМ было пародией на излюбленный прием решения всех проблем, которые только появляются у микроконтоллерщиков - забыть навсегда свой и применить СТМ. ))
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
13.04.2016, 23:04 50
Я уже не первый раз вижу призывы на форуме AVR перейти на STM . Создается впечатление , что у STM так плохи дела , что они вынуждены прибегать к помощи зазывал.
0
Bytt
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
14.04.2016, 07:43 51
Цитата Сообщение от YTYOUT
Я уже не первый раз вижу призывы на форуме AVR перейти на STM . Создается впечатление , что у STM так плохи дела , что они вынуждены прибегать к помощи зазывал.
Я не призываю никого переходить на STM8, но сам я на него как-бы уже перешел. Все свои будущие разработки я буду именно на нем. Потому, как для себя я увидел в нем определенные плюсы. Но, опять же, это для себя лично.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
14.04.2016, 08:57 52
Я с удовольствием осваиваю ARM на STM Dyscovery , но при этом не бросаюсь фразами
Правда есть еще один универсальный и волшебный способ - применить СТМ и забыть о проблемах.
0
Otixomdr_1
0 / 0 / 0
Регистрация: 28.06.2010
Сообщений: 211
19.04.2016, 18:21 53
Цитата Сообщение от инкер
Проблема с вмешательством прерывания не ограничена только ситуацией с двушаговым чтением переменной, здесь просто на момент чтения ставится общий запрет прерываний или на конкретное, связанное с данной переменной. Бывает программа обработки достаточно длинная с несколькими обращениями к одной и то же переменной, длительный запрет прерываний может повредить корректности работы программы в целом и приходится работать через регистр-посредник, куда читается состояние таймера один раз на весь цикл обработки. Да, результат получается немного устаревшим, но без безобразий.
Упоминание СТМ было пародией на излюбленный прием решения всех проблем, которые только появляются у микроконтоллерщиков - забыть навсегда свой и применить СТМ.
Конечно, проблема с вмешательством прерывания не ограничена только ситуацией с двушаговым чтением.
Аналогичная проблема может возникнуть для двух и более зависимых переменных, которые должны относится к одному сеансу измерений.
В прерывании могут использоваться общие с основной программой ресурсы (тот же АЦП, таймер и т.д.).
Да и спустя несколько лет при доработке программы вспоминать о проблемах большого прерывания неудобно.
Думаю, сложная работа в прерывании, «боковые» выходы из подпрограммы и т.д. – это делают начинающие.
При серьезной работе надо от этого уходить.

STM, говорят, подорожали.
0
инкер
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
19.04.2016, 23:40 54
Цитата Сообщение от Otixomdr_1
Цитата Сообщение от инкер
STM, говорят, подорожали.
Программировать можно так, как этот перец водит


<Изображение удалено>

СТМ --- Как подсадят достаточное количество, так цены и поднимут.
0
19.04.2016, 23:40
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.04.2016, 23:40

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

Создание объекта-события и обработчика события
Допустим у меня есть следующий класс: public class Example { private boolean bool; public...

Выход из обработчика события
Подскажите пожалуйста как в С++ (Visual Studio 2008) выйти из обработчика событий. Конкретно:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
54
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.