Мне было интересно, если использовать ticker
прерывания могут мешать аппаратным прерываниям, вызванным нажатием кнопки.
Представьте, что я хотел бы использовать эти два типа прерываний:
ticker
таймер для обновления индикатора на маленьком дисплее каждый n
второйhardware interrupt
который запускает / останавливает процесс, прогресс которого отображается, если пользователь нажимает кнопкуВажный: Оба прерывания установлены общими глобальными volatile
флаги.
Будет ли это возможно для ticker
прерывание произойти в течение кнопка вызывала прерывание и в результате программа находилась в состоянии, когда глобальные флаги установлены противоречиво?
Имеет ли аппаратное и программное прерывание одинаковый «ранг»?
Если они произошли в одно и то же время, будет ли игнорироваться запрос на прерывание, возникающий несколько позже (но все еще перекрывающийся с первым), или просто помещаться в очередь и выполняться сразу после завершения первого прерывания? В этом случае флаги будут установлены неожиданным образом.
Могу ли я отключить один тип прерываний внутри ISR другого типа — т.е. игнорировать его?
Я надеюсь, что постановка задачи достаточно ясна даже без примера кода.
Я предполагаю, что вы используете AVR.
Когда прерывание срабатывает, другие прерывания отключаются во время работы подпрограммы прерывания. Поэтому любые прерывания, которые происходят в это время, просто помечаются. Когда процедура прерывания возвращается, глобальный флаг прерывания повторно включается, и любые опрошенные прерывания могут затем запускаться по одному за раз.
Вы можете вручную включить глобальные прерывания внутри подпрограммы для критических задач, которые должны выполняться, но по умолчанию отключены.
РЕДАКТИРОВАТЬ:
Есть ли способ отключить эту настройку флага? Я не хочу, чтобы таймер тикера выполнял прерывание после нажатия кнопки. Вот почему я спросил о рангах и возможности отключения по типу прерывания, если есть такая вещь
Вы можете удалить ожидающее прерывание, однако вам придется прочитать таблицу данных для AVR вашего Arduino. Вам нужно найти регистр для внешнего прерывания.
Например, на atmega328p внешнее прерывание 0 можно очистить, установив для его бита флага значение 1:
EIFR |= (1 << INTF2);
EIFR
= Регистр внешнего прерывания
INTF2
= Бит 0 — INTF0: флаг внешнего прерывания 0
Тем не менее, может быть гораздо проще опросить кнопку в вашем loop()
функция. Или, в лучшем случае, просто установите флаг для вас, чтобы действовать в loop()
функция. Там вы сможете решить, хотите ли вы реагировать или игнорировать прерывание
Существует проблема слишком большого количества ваших прерываний. Если вы используете синхронизацию или требуете точности, на это может повлиять большое количество времени. Поскольку длина очереди прерываний составляет всего 1, некоторые прерывания могут быть потеряны. И прерывание, которое полномочия millis()
& micros()
выполняется несколько раз в миллисекунду, поэтому громоздкое прерывание может привести к замедлению времени.
Также есть ли у вас какой-либо разборчивый код или оборудование?
Если нет, обработка прерывания кнопкой может быть запущена несколько раз за одно нажатие.
Других решений пока нет …