Подвисание при использовании прерываний.
- Войдите на сайт для отправки комментариев
Чт, 25/12/2014 - 00:45
#define encoder0PinA 2 #define encoder0PinB 4 #define encoder0PinSW 3 #define LED 13 volatile long encoder0Pos = 0; void setup() { pinMode(encoder0PinA, INPUT); digitalWrite(encoder0PinA, HIGH); // turn on pullup resistor pinMode(encoder0PinB, INPUT); digitalWrite(encoder0PinB, HIGH); // turn on pullup resistor pinMode(encoder0PinSW, INPUT); digitalWrite(encoder0PinSW, HIGH); // turn on pullup resistor attachInterrupt(0, doEncoder, CHANGE); attachInterrupt(1, doEncoderSW, CHANGE); pinMode(LED, OUTPUT); Serial.begin (9600); // Serial.println("start"); // a personal quirk } void loop() { digitalWrite(LED, HIGH); delay(1000); digitalWrite(LED, LOW); delay(1000); Serial.println ("LED1"); } void doEncoder() { if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) { encoder0Pos--; } else { encoder0Pos++; } Serial.println (encoder0Pos); } void doEncoderSW(){ if (digitalRead(encoder0PinSW) == LOW){ Serial.println ("SW"); } else { } }
В какой то момент времени SerialPrintLn подвисает, но, самое противное, что LED = 13 тоже перестает мигать.
Вызов Serial.print из прерывания - уже жесть, из основного цикла и из прерывания - гарантирован плавающий глюк. Код Serial.print не потокобезопасен. Вызывать тока из основного цикла. А вылетает когда в основном цикле начали делать Serial.print, произошло прерывание и тоже вызвало Serial.print.
На какой плате тестируете? Я на Меге для отладки постоянно Serial.print из прерывания вызываю. Уже даже переживать по этому поводу перестал - ни разу глюка не было...
когда в основном цикле начали делать Serial.print, произошло прерывание и тоже вызвало Serial.print.
Можно на время выполнения print основного цикла вырубать прерывания, правда тогда можно что-то важное пропустить
На какой плате тестируете? Я на Меге для отладки постоянно Serial.print из прерывания вызываю. Уже даже переживать по этому поводу перестал - ни разу глюка не было...
дык у него же два прерывания одновременно кативированы, плюс еще delay() который тоже рекомендуют избегать.
чего гадать, нужно убрать обращения serial и посмотреть чо получится.
На какой плате тестируете? Я на Меге для отладки постоянно Serial.print из прерывания вызываю. Уже даже переживать по этому поводу перестал - ни разу глюка не было...
дык у него же два прерывания одновременно кативированы, плюс еще delay() который тоже рекомендуют избегать.
чего гадать, нужно убрать обращения serial и посмотреть чо получится.
Согласен
От делеев в основном цикле тоже бы избавиться, я тут недавно наступил на эти грабли UART тормозил, а задержка было всего 200мс, а у тебя целых две секунды т.е прога тупо эти 2 секунды висит нихрена не делая и прерывания не отлавливая.
От делеев в основном цикле тоже бы избавиться, я тут недавно наступил на эти грабли UART тормозил, а задержка было всего 200мс, а у тебя целых две секунды т.е прога тупо эти 2 секунды висит нихрена не делая и прерывания не отлавливая.
С чего бы это? В delay прерывания не маскируются:
Скорее всего проблема в том, что два прерывания могут наступить одновременно.
Я думаю следует попробовать в обработчике энкодера запрещать прерывания от кнопки (все равно одновременно не бывает).
Не могут прервания наступить одновременно. В первую очередь выполняется прерывание имеющее более высокий приоритет. Самый высокий приоритет у Reset.
Возможно прерывания вызываются на столько часто, что основная программа не выполняется:
Во время выполнения прерывания1 возникает этоже прерывание 1а, 1а ставится в очередь, по завершении 1-го выполняется 1а и снова возникает прерывание.