Я работаю с Arduino Mega 2560 и имею приложение, которое требует использования одного из трех разных таймеров, основанных на параметре, переданном вызывающей стороной. Мне нужно быть в состоянии сделать что-то вроде этого:
ISR(TIMERX_COMPA_vect){
foo;
bar;
}
Где X — номер таймера, переданного абонентом. Я не могу использовать препроцессор foo, так как номер таймера не известен, пока не настроен ISR.
Следовать за
Похоже, что ISR () является препроцессором: АРН / interrupt.h Если так, то, что я хочу сделать, не будет работать. Итак … есть ли другой способ добавить программу обработки прерываний «на лету»?
Основываясь на некоторых исследованиях аппаратных прерываний, то, что я пытался сделать, не представляется возможным. Вообще говоря, есть пять шагов для выполнения прерывания:
Когда прерывание становится активным, микроконтроллер выполняет следующие шаги:
Микроконтроллер закрывает текущую выполняемую инструкцию и сохраняет адрес следующей инструкции (ПК) в стеке.
Он также сохраняет текущее состояние всех прерываний внутри себя (т.е. не в стеке).
Он переходит в область памяти таблицы векторов прерываний, которая содержит адрес подпрограммы обслуживания прерываний.
Микроконтроллер получает адрес ISR из таблицы векторов прерываний и переходит к ней. Он начинает выполнять подпрограмму обслуживания прерываний, которая является RETI (возврат из прерывания).
После выполнения инструкции RETI микроконтроллер возвращается в то место, где он был прерван. Во-первых, он получает адрес счетчика программ (ПК) из стека, вставляя верхние байты стека в ПК. Затем он начинает выполняться с этого адреса.
Поскольку ISR должен быть по правильному адресу (на который указывает вектор прерывания), прежде чем он будет вызван (Шаг 4), он должен быть «завершен» перед загрузкой в Arduino и, таким образом, перед выполнением. Таким образом, предварительная обработка — самая последняя, в которой можно использовать любой вид подстановки переменных при назначении вектора прерывания ISR.
Других решений пока нет …