Часы Arduino Due SPI приостанавливают каждый октет

Я пытаюсь связаться с ведомым устройством SPI, используя Arduino DUE в качестве ведущего устройства. Устройство требует, чтобы команды были 32-битными, режим SPI 3.

Я запустил минимальный код (используя Arduino IDE 1.8.12) для отправки какой-то 32-битной ерунды и заметил, что часы останавливаются на некоторое время после отправки каждого октета. Также пауза после того, как CS становится НИЗКОЙ, слишком длинная.

Как лучше всего добиться чистой 32-битной передачи?

#include <SPI.h>

const int cs_pin = 25;
const SPISettings spi_settings(2000000, MSBFIRST, SPI_MODE3);
uint8_t tx_buffer[4];

void setup() {
  pinMode(cs_pin, OUTPUT);
  SPI.begin();
}

void loop() {
  tx_buffer[0] = 0xDE;
  tx_buffer[1] = 0xAD;
  tx_buffer[2] = 0xBE;
  tx_buffer[3] = 0xEF;

  SPI.beginTransaction(spi_settings);
  digitalWrite(cs_pin, LOW);
  SPI.transfer(tx_buffer, 4);
  digitalWrite(cs_pin, HIGH);
  SPI.endTransaction();
}
  • SCLK – канал 1 (желтый)
  • CS – CH3 (фиолетовый)
  • MOSI – CH4 (синий)

обзор увеличить масштаб

Ожидаемый сигнал:

, 👍0

Обсуждение

Замеченное время указывает, что на самом деле это 40, а не 32 бита, но это, похоже, не влияет на вопрос., @IceGlow

Регистр данных SPI имеет ширину всего 8 бит. Таким образом, у вас должно быть некоторое время, когда один байт отсутствует, чтобы загрузить следующий байт. На самом деле вы ничего не можете с этим поделать, кроме использования другого оборудования., @Delta_G

@Delta_G да, тоже так думал. Но на самом деле это происходит, даже если я устанавливаю более медленные часы SPI. Похоже, это намеренно. Думаю, мне стоит взглянуть, что происходит в библиотеке., @IceGlow


1 ответ


1

SPI является синхронным. Это означает, что при определенных ограничениях время и ширина любой части сигнала не имеют значения.

Что заставляет вас думать, что небольшая разница в тайминге — это плохо или что "пауза после CS становится НИЗКОЙ!" "слишком низкий"?

Если вы думаете, что это следует из временных диаграмм, эти времена являются минимальными временами (как правило), и все происходит либо на переднем, либо на заднем фронте тактового сигнала (в зависимости от режима SPI).

,

Ну, если вы посмотрите на нижнюю диаграмму, вы увидите, что после 8-ми фронтов тактового сигнала 9-й фронт не происходит сразу, как это было бы в непрерывном потоке. Он делает паузу на один цикл перед передачей следующего байта. Я понимаю, что это сработает, просто это займет немного больше времени. Просто интересно, почему, и если я могу избежать этого., @IceGlow

Это совершенно нормально. Почему вы хотите избежать этого?, @Majenko

В SPI не требуется ждать столько циклов после установки низкого уровня CS перед началом передачи. Он ожидает около 6 Tcl дополнительного времени., @IceGlow

@IceGlow Способ работы Arduino с SPI заключается в том, что он блокирует. Вы получаете байт. Вы помещаете его в регистр данных SPI. Вы ждете, пока он будет отправлен. Вы извлекаете полученный байт. Вы храните его где-то. Вы получаете следующий байт. Вы помещаете его в регистр данных SPI... и т. д. Если по какой-то причине вы хотите сделать его более «гибким», вам придется сделать это вне API Arduino и напрямую взаимодействовать с регистрами SPI. И даже использовать DMA для максимальной фоновой работы., @Majenko

ну, я играю с прямым управлением токами на приводе с помощью команд SPI. Я хотел бы иметь предсказуемые и минимальные задержки между командами, так как это увеличивает точность. Имеет ли это смысл? Но вопрос в том, могу ли я контролировать эти задержки до отправки первого байта, между байтами, после последнего байта, если захочу., @IceGlow

И извините, я не хотел сказать, что что-то сломано. Поведение библиотеки по умолчанию не нарушает никаких требований для SPI. Есть только некоторые запасы, я полагаю, для повышения стабильности некоторых устройств. Интересно, могу ли я избежать их., @IceGlow

@IceGlow Да, но не с кодом API Arduino., @Majenko