Какие функции отключены с помощью noInterrupts()?

Страница Arduino для noInterrupts() говорит:

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

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

Я подумывал о вызове библиотеки датчиков DHT, которая внутренне использует millis(), в то время как прерывания отключены, чтобы избежать одновременного удара битов и обслуживания прерываний, если это возможно (прерывание будет удерживаться и обрабатываться после этого) .

Какие функции обязательно отключаются при отключении прерываний?

А как насчет входящей связи? Я предполагаю, что на ATmega32U4 (например, Leonardo) ситуация будет немного хуже, поскольку один процессор поддерживает USB и все остальное.

, 👍0

Обсуждение

Следующая команда grep ISR *.cpp создаст список всех функций ISR в ядре Arduino. Это функции HardwareSerial (UART/USB: прием, передача) и таймера (миллис, микромикрофон, тон)., @Mikael Patel


2 ответа


1

Из того, что я обнаружил, отключение прерываний определенно отключит увеличение значений micros() и millis(). Это означает, что также каждый метод, который их использует, например Delay() также будет работать неправильно.

Конечно, прерывания, добавленные вручную с помощью attachInterrupt(), также не будут работать должным образом.

Согласно комментариям @Juraj, вещи, которые также не будут работать, — это последовательные прерывания. Также такие библиотеки, как Wire, требуют прерываний для своей логики.

РЕДАКТИРОВАТЬ: @EdgarBonet Вы правы, я удалил неверную информацию.

,

Последовательный прием обрабатывается с прерыванием для аппаратных последовательных портов (включая собственный USB) и программных последовательных портов., @Juraj

Отправка и получение библиотеки Wire реализованы в прерывании., @Juraj

ШИМ, который вы получаете от AnalogWrite(), не обрабатывается прерываниями: он генерируется самими таймерами., @Edgar Bonet


0

SPI.transfer() также использует прерывания, но вы можете «вручную» дождаться их, чтобы знать, когда следует продолжить. Например, у меня была программа, в которой мне нужно было отправить 45 байт за 50 мкс (частота обновления 20 кГц). Во время тестирования я продолжал видеть колебания в потоке данных — примерно каждые 4 мкс, насколько я помню. Время прерывания micros(). Отключил прерывания при передаче данных и дрожание ушло. Итак, команда для отправки байта выглядела так, повторенная 45 раз (без цикла for):

spdr = byte0; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
spdr = byte1; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
spdr = byte2; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
:
spdr = byte43; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
spdr = byte44; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;

Итак, для передачи потребовалось 17 тактовых импульсов с тактовой частотой SPI, установленной на 8 МГц. После передачи я снова включил прерывания, чтобы дождаться следующего фронта входящего сигнала и отправить следующий пакет.

,