Сколько всего можно запихать в прерывания?

kentik
Offline
Зарегистрирован: 28.03.2013

Здравствуйте, уважаемые форумчане.

Есть программа. уже накопилось в ней куча всего. текст реально большой. и все в ней нужно.

Появилась задача выполнять определенные действия гораздо быстрее (через определенный промежуток времени), нежели они дождутся своей очереди в loop().
На помощь приходят прерывания. А так как таймер1 уже занят для внешнего прерывания и таймер 0 занят для всяких там delay(), которые я тоже использую, то остается на камне atmega328p только таймер2.

что бы с самого начала освоения таймеров голова не пухла от обьема информации, принято решение использовать библиотеку MsTimer2
http://playground.arduino.cc/Main/MsTimer2

Используя код из примера библиотеки, под свои нужды, получаю:

01void flash() {
02                for(int i = 0; i < 10; i++) {
03                   average=average+analogRead(A4);
04                   delay(1);
05                }
06  average=average/10;
07  corrector=a/2+15; 
08   
09             if ((a<109)&&(a>47)){
10                     if(average<(nullsensorI-corrector)){
11                         aa = (nullsensorI - average)/6;
12                    if (aa>90) aa=90;
13                       }
14              }
15   pwmWrite(enAB,a+aa);
16}
17 
18void setup() {
19  MsTimer2::set(100, flash); // 100ms period
20  MsTimer2::start();
21}
22 
23void loop() {
24}

Но вот чувствую я, что плохо тут что-то. долго слишком в прерывание работать будет?
или для 100 милисекунд это в принципе нормальный код?
 

kentik
Offline
Зарегистрирован: 28.03.2013

я так понимаю, что первая моя ошибка - это использование delay(1); в функции 

X-Dron
Offline
Зарегистрирован: 24.01.2015

Откуда Вы взяли, что прерывания будет выполняться 100мс?
Я вижу 10 -12мс (в10-ти кратном цикле delay по миллисекунде).
100мс это период вызова.
В приципе здесь все нормально

 

kentik
Offline
Зарегистрирован: 28.03.2013

X-Dron пишет:

Откуда Вы взяли, что прерывания будет выполняться 100мс?
Я вижу 10 -12мс (в10-ти кратном цикле delay по секунде).
100мс это период вызова.
В приципе здесь все нормально


 

Да ниоткуда. просто боюсь, что все, что у меня в теле функции flash(), будет выполняться дольше, чем период вызова этой функции.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

kentik, ну так измерьте, методика быстро гуглится если что..    В прерывания  главное нельзя вставлять функции, использующие другие прерывания. А что у вас на аналоговом входе?

kentik
Offline
Зарегистрирован: 28.03.2013

dimax пишет:

А что у вас на аналоговом входе?


У меня там показания с операционного усилителя.

dmitriykisliy
Offline
Зарегистрирован: 03.03.2015

есть библиотека cyberlib.h, там delay_ms можно использовать в прерываниях (проверено)

dmitriykisliy
Offline
Зарегистрирован: 03.03.2015

dimax пишет:

kentik, ну так измерьте, методика быстро гуглится если что..    В прерывания  главное нельзя вставлять функции, использующие другие прерывания. А что у вас на аналоговом входе?

т.е. нельзя после запуска прерывания запустить другое прерывание?

1attachinterrupt(0,flash,RISING);
2void flash(){attachinterrupt(1,flash1,FALLING);}
3void flash1(){...}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

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

kentik
Offline
Зарегистрирован: 28.03.2013

dmitriykisliy пишет:

есть библиотека cyberlib.h, там delay_ms можно использовать в прерываниях (проверено)

с этой cyberlib.h косяк выскочил 

 

Все зависает мертво на строчке attachInterrupt(0, detect_up, LOW);

 вот на экранчике цифирька "1" уже не выводится.
 

bwn
Offline
Зарегистрирован: 25.08.2014

Четыре диммера у меня с этой библой без проблем работали. Atmega328.

dmitriykisliy
Offline
Зарегистрирован: 03.03.2015

я ба не инициализировал прерывание (70 строка) , а запрещал или разрешал (вместо 70 строки) и через регистры. код есть готовый, но на компе(завтра выкину) или пример arduino.ru/forum/proekty/fuoz-na-arduino-nano-s-328-chipom

8, 9 строки кода

EIMSK &= ~ (1 << INT0); // Запретить прерывание 0

ну и 

 

//EICRA &= ~((1<<ISC00)|(1<<ISC01)); //прерывание вызавается при сигнале LOW
//EICRA |= (1<<ISC01); // FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)
//EICRA |=(1<<ISC00)|(1<<ISC01) // RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH)
// EICRA |= (1<<ISC00); // прерывание вызывается при изменении значения на входе;