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

b612
Offline
Зарегистрирован: 12.03.2017

Добрый день, уважаемые !

У меня есть обработчик прерывания

ISR(TIMER1_COMPA_vect) { //прерывание по совпадению
  //определим длину следующего интервала
  //  тут всякий код
}

Само прерывание пока выключено.

Мне нужно, принудительно вызвать этот обработчик из основного потока.

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

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Ну и вызовите его

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

обработчик оформите в подпрограмму, её и вызывайте в любом месте скетча:

ISR(TIMER1_COMPA_vect) { //прерывание по совпадению
  //определим длину следующего интервала
  //  тут всякий код
my_isr();
}

void my_isr(){
здесь код
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b612 пишет:

Мне нужно, принудительно вызвать этот обработчик из основного потока.

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

Вы хотите "странного". Скорее всего это признак непродуманности программы.

В лоб обработчики вызывать нельзя, т.к. они отличаются от обычных функций.

Можно вызвать "тело обработчика" так, как написал коллега ua6em выше. Но Вы должны понимать, что в этом случае Вы работаете НЕ в контексте прерывания.

Наконец, можно заставить прерывание случиться немедленно. Для того прерывания, что у Вас в примере, достаточно прописать 1 в бит FOC1A регистра TCCR1C и оно случится и обработчик будет вызван.

Но, повторяю, подумайте о структуре программы. Если Вам потребовались такие вещи, скорее всего что-то не так с её архитектурой.

Logik
Offline
Зарегистрирован: 05.08.2014

ua6em пишет:

обработчик оформите в подпрограмму, её и вызывайте в любом месте скетча:

ISR(TIMER1_COMPA_vect) { //прерывание по совпадению
  //определим длину следующего интервала
  //  тут всякий код
my_isr();
}

void my_isr(){
здесь код
}

 

Если для отладки  my_isr() - годно. А для боевого применения  - только для реентерабельной функции, иначе наложатся два вызова и ТС проклянет ардуину, МК и ИТ в целом.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

ua6em пишет:

обработчик оформите в подпрограмму, её и вызывайте в любом месте скетча:

ISR(TIMER1_COMPA_vect) { //прерывание по совпадению
  //определим длину следующего интервала
  //  тут всякий код
my_isr();
}

void my_isr(){
здесь код
}

 

Если для отладки  my_isr() - годно. А для боевого применения  - только для реентерабельной функции, иначе наложатся два вызова и ТС проклянет ардуину, МК и ИТ в целом.

ТС полагаю и слова такого не знает, а так да, вероятность повторного вызова этой же функции весьма велика, но не столь и страшно, так как уровень вложенности не более 2-х, озу под стек должно хватить )))

Logik
Offline
Зарегистрирован: 05.08.2014

Ладно если вероятность еще высока! )))  А вот если раз в час/день/месяц? Можна такое и всю жизнь дебажить.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ну он наверное знает, зачем ему это понадобилось, лично я придумать зачем - не могу

Logik
Offline
Зарегистрирован: 05.08.2014

Чего там придумывать, нужно ему выполнять некоторое действие по таймеру и по кнопке, вот и лабает. Эх, куда мир катится...

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

Можно ещё по аналогии как ресет принудительно вызывали,

Объявить:
void (*myISR)() = 0x16; // TIMER1_COMPA_vect

Вызвать:
myISR();

Собссно так можно вообще на любой адрес перепрыгнуть. Осознавая конечно все возможные последствия ;)

inspiritus
Offline
Зарегистрирован: 17.12.2012

Он же сказал, что прерывания «выключены» , значит не проклянёт :)

b612
Offline
Зарегистрирован: 12.03.2017

Благодарю, кто откликнулся.

Сделал отдельной функцией, как советует ua6em

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

b612 пишет:

Благодарю, кто откликнулся.

Сделал отдельной функцией, как советует ua6em

 

я бы в тело функции на этапе проверки включил функцию проверки памяти, будете знать сколько отжирает, столько же может съедать ещё из-за возможного вызова прерывания, да наверное флаг надо включить в тело функции, если уже выполняется, ничего не выполнять