Запуск передачи SPI с помощью прерывания в Arduino Due
У меня есть DDS, который управляется Arduino DUE, цикл() ожидает последовательных команд и на их основе вызывает ту или иную функцию, которая устанавливает частоту, фазу, амплитуду и т. д. DDS через SPI. В дополнение к этому я хочу иметь возможность использовать внешнее прерывание, запускаемое сигналом TTL, для сброса аккумулятора фазы DDS. Сброс фазы осуществляется записью в регистр SPI — resetPhase().
Каким-то образом функция resetPhase() запускается правильно, но как только я добавляю к ней SPI.transfer, связь SPI перестает работать вообще, не только через прерывания, но и функции, запускаемые через последовательные команды, перестают работать.
>Есть ли способ заставить это работать?
SPISettings spiSettings = SPISettings(10000000, MSBFIRST, SPI_MODE0);
void setup()
{
pinmode(chipSelect, OUTPUT);
int syncPIN = digitalPinToInterrupt( interruptPin);
SPI.usingInterrupt(syncPIN);
attachInterrupt(syncPIN, resetPhase, RISING);
}
void resetPhase():
{
SPI.beginTransaction(spiSettings);
digitalWrite(chipSelect, LOW);
SPI.transfer(controlRegister);
digitalWrite(chipSelect, HIGH);
SPI.endTransaction();
}
@shz, 👍0
Обсуждение1 ответ
В общем, лучше делать как можно меньше действий в подпрограмме обслуживания прерываний (ISR).
resetPhase
— это ваш ISR, и обычно он устанавливает флаг или семафор, чтобы сигнализировать коду с более низким приоритетом о том, что необходимо выполнить определенную работу и, в данном случае, вероятно, не более того. Тогда ваш код loop
, заметив, что флаг установлен, очистит флаг и выполнит свою работу.
Я полагаю, что авторы библиотеки думали, что SPI.usingInterrupt
облегчит использование SPI, но выполнение ввода-вывода в ISR кажется немного противоречащим лучшим практикам. Эти проблемы отражены здесь, а также некоторые другие предостережения относительно прерываний и ISR. . Возможно, это не тот ответ, который вы ищете, но я надеюсь, что он поможет.
- Программирование ведомого SPI для Arduino
- Использование экрана SD-карты на Arduino Due
- 16-битный SPI на Arduino Due
- Контакт клавиатуры как прерывание (проводка или программирование)
- Поддерживает ли MFRC522 собственный SPI Arduino Due?
- Невозможно установить низкий уровень на выводе MOSI даже после завершения SPI
- Проблема с настройкой Arduino Due SPI на АЦП.
- Правильное использование SPI с ISR
Вероятно, при передаче SPI используется прерывание, которое не может сработать, поскольку вы уже находитесь в прерывании. Вы должны иметь операции SPI вне прерывания и просто обновлять некоторые переменные и устанавливать флаг в своем прерывании., @Majenko
Однако я не знаком с внутренней работой библиотеки Due SPI. Лучше всего перестраховаться и не использовать SPI в прерывании., @Majenko
@Маженко Я думал, что SPI.usingInterrupt специально предназначен для этой цели
// Если SPI используется внутри прерывания, эта функция регистрирует // это прерывание с библиотекой SPI, поэтому метод BeginTransaction() может // предотвращаем конфликты. Входной номер прерывания — это используемый номер. // с помощью AttachInterrupt. Если SPI используется из другого прерывания // (например, таймер), номер прерывания должен быть 255. static void usingInterrupt(uint8_t ignoreNumber);
, @shz