почему прерывание работает 1 раз?
- Войдите на сайт для отправки комментариев
Пнд, 18/04/2016 - 13:28
почему прерывание работает 1 раз? повторный вызов прерывания не получается
void setup() { attachInterrupt(0, blink, RISING); pinMode(11, OUTPUT); pinMode(12, OUTPUT); pinMode(2, INPUT); } void loop() { digitalWrite(11, HIGH); delay (250); digitalWrite(11, LOW); delay (250); } void blink() { wq: if (digitalRead(2)==HIGH) { digitalWrite(11, HIGH); digitalWrite(12, HIGH); goto wq; } else{ digitalWrite(11, LOW); digitalWrite(12, LOW); detachInterrupt(0); } }
почему прерывание работает 1 раз? повторный вызов прерывания не получается
оно у тебя работает только при переходе из "0" в "1"
а в 32 строке ты его вообще выключил, вот оно и работает 1 раз
да да, уже осознал )
А что это за "бесконечный" цикл внутри прерывания через goto?
во первых прерывание должно отрабатывать насколько возможно быстро, в вас же здесь зависимость от внешних условий и вполне вероятна ситуация когда не выйдем из прерывания никогда
во вторых использование goto плохая практика даже для Си, а уж для Си++ это совсем не айс
Goto пришла в Си из ассемблера и рассчитана на тех кто знает сто делать, но и то, везде рекомендуется избегать использование goto там где это врзможно. У вас это возможно на 300%
Это не вопрос моды, это вопрос правильного подхода, неловкое применение goto легко может нарушить целостность программы (например выскочив из подпрограммы без восстановления стека)
а зачем 23 строка?)))
хм, если это не секретная разработка, можете объяснить, что вы хотите сделать, для чего это прерывание? в общих чертах, логика
Тогда, наверное так надо было, хотя тоже непонятно зачем цикл внутри обработчика:
а зачем вторая нога в блинке ? получается помимо самого прервания на 0 ноге еще чтото должно/может сработать на 2.
так вторую мы можем в обычный луп вынести. вроде. вообщем пока не до конца ясна картина :)
Это уже к автору. Я только подправил его код согласно ДРАКОНу. :)
ну так это же внешнее прерывание, от туда и зависимость ) и цикл совсем не бесконечный если обратить внимание на ELSE )
И хочу заметить все работает именно так как я хочу )
Это может быть АВАРИЙНАЯ КНОПКА да?
Может. Но ТАК не пишут. Если сигнал на ножку 2 не придет долгое время ваш обработчик завесит всю систему .. гарантировано. Поскольку он работает с закрытыми прерываниями в таком режиме подключения. Вам правильно сказали, что эту проверку 2 ноги надо выносить в loop(), а обработчик должен быть как можно короче и никаких "установок" и тем более ожиданий в нем быть не должно "по определению". Получил сигнал - свистнул в loop() и отвалился. А loop() пусть сам разбирается тогда, когда ему удобно "хто пришел, что за штоматолог".. :)
а если сигнал не придет долгое время в этом случае ? что будет?
digitalWrite(11, HIGH);
20
digitalWrite(12, HIGH);
21
22
while
( digitalRead(2)==HIGH )
continue
;
23
24
digitalWrite(11, LOW);
25
digitalWrite(12, LOW);
и на сколько это долгий сигнал что то я не могу понять, работает это все одинаково!
И каким образом мне в loop от сюда обращаться? тоже через goto? )
Из асинхронно выполняемых ветвей графа исполнения в главную ветвь обычно обращаются через установку и проверку семафоров или организацией рандеву.
По-просту, используют глобал. Обработчик только изменяет состояние глобала и завершается. Основной цикл проверяет изменение глобала (семафора) и если надо, то висит в цикле ожидая изменения глобала(семафора). В качестве семафора может указываться и адрес перехода в ожидающей задаче и/или место куда надо сообщить ожидающей задаче результат обработки (механизм рандеву языка АДА). Возможна также организация очередей из семафоров или у входов Рандеву (очередь slave задач, ожидающих данных от master).
В целом, советую найти и почитать книжки по программированию распределенных, параллельных систем и особенно систем реального времени. Ну и заодно найти хотя бы краткое описание языка АДА. В нем собрано наибольшее количество примитивов межзадачного взаимодействия. Ваш обработчик прерывания - по сути "асинхронно испольняемый процесс". И только.