Можно ли ставить приоритеты между внешними прерываниями?

Мой вопрос довольно прост. Я использую одно внешнее прерывание на Mega2560, чтобы разбудить его сигналом тревоги от rtc DS3231 и записать данные с датчиков в течение примерно 30 секунд, и я также хотел бы использовать другое внешнее прерывание, чтобы разбудить его в случае обнаружения удара. измерить сигнал.

Дело в том, что я знаю, что внешние прерывания имеют приоритет перед внутренними прерываниями, но можно ли в моем случае поставить обнаружение удара перед тревогой? В случае, если удар происходит во время записи по тревоге, я бы предпочел записать сигнал удара.

Спасибо за помощь!

, 👍1

Обсуждение

Неужели важно уловить тот случай, когда оба перебивают огонь одновременно? Кажется, это довольно редкий случай. Возможно, было бы достаточно проверить флаг прерывания шока в начале аварийного ISR., @chrisl

Привет ! Итак, нельзя установить приоритеты между внешними прерываниями? Я согласен, что если шок произойдет в этот момент, это будет плохой приметой, но мне нужна была довольно надежная система. Ваша идея проверить флажок в момент тревоги просто скажет мне, произошел ли удар, но я не уловил бы его силы... Думаю, мне придется пойти на компромисс. Спасибо !, @JamesONeil


1 ответ


Лучший ответ:

2

Прерывания — неподходящее место для управления приоритетами. Прерывание обработчики должны быть как можно короче. Тогда вероятность двух из их одновременное появление очень мало. И даже если это произойдет, то прерывание с самым низким приоритетом будет задержано всего на несколько микросекунд, что не должно иметь большого значения.

В этом случае разумным подходом является использование обработчиков прерываний. установите глобальный флаг и больше ничего не делайте. Затем будет выполняться основная программа. проверяйте флажки и выполняйте настоящую работу, расставляя приоритеты по мере необходимости.

Концептуально, код может быть примерно таким:

// Глобальные флаги.
volatile bool alarmDetected;
volatile bool shockDetected;

// Обработчики прерываний.
void onAlarmInterrupt() { alarmDetected = true; }
void onShockInterrupt() { shockDetected = true; }

void loop() {
    if (shockDetected) {  // сначала проверьте это!
        measureShockData();
        if (gotEnoughShockData()) {
            shockDetected = false;
            alarmDetected = false;  // игнорировать тревогу
            goToSleep();
        }
    } else if (alarmDetected) {
        recordSensorData();
        if (gotEnoughSensorData()) {
            alarmDetected = false;
            goToSleep();
        }
    }
}

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

,

Привет ! Спасибо за ваше решение, я думаю, что я пойду с ним!, @JamesONeil