Введение
SPI (Serial Peripheral Interface) — это синхронный последовательный протокол связи, широко используемый для подключения микроконтроллеров к датчикам, дисплеям и микросхемам памяти. В этом руководстве мы создадим тест SPI с обратной связью с помощью симулятора Velxio. Тест с обратной связью отправляет байты через SPI и считывает ответ, подтверждая корректную работу протокола. Поскольку физического ведомого устройства нет, симулятор возвращает отправленный байт, что делает этот способ идеальным для изучения SPI без какого-либо оборудования.
Сборка схемы
Начнем с создания схемы. Единственный необходимый компонент — Arduino Uno, который мы разместим на холсте.

Чтобы добавить Arduino Uno, откройте выбор компонентов, нажав на значок ”+” на панели инструментов холста.

Найдите “Arduino Uno” и разместите его на холсте. Arduino Uno имеет выделенные выводы SPI:
- MOSI (Master Out Slave In) — вывод 11
- MISO (Master In Slave Out) — вывод 12
- SCK (Serial Clock) — вывод 13
- SS (Slave Select) — вывод 10 (мы будем использовать его как выбор микросхемы)
В этом тесте с обратной связью внешнее подключение не требуется, так как сигналы SPI являются внутренними для Arduino. Однако необходимо убедиться, что вывод SS (вывод 10) настроен как выход и изначально установлен в высокий уровень, а затем переключается в низкий во время передачи. Это обрабатывается в коде.
Разбор кода
Теперь рассмотрим код. Откройте редактор кода, нажав на вкладку “Code” на панели инструментов редактора.

Код написан на Arduino C++ и использует встроенную библиотеку SPI.h. Внешние библиотеки не требуются.
// SPI Loopback Test
// Sends bytes via SPI and logs the exchange.
// Without a physical slave, the emulator returns the sent byte.
#include <SPI.h>
#define SS_PIN 10
void setup() {
Serial.begin(9600);
Serial.println("========================");
Serial.println(" SPI Protocol Test");
Serial.println("========================");
Serial.println();
pinMode(SS_PIN, OUTPUT);
digitalWrite(SS_PIN, HIGH);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV16);
Serial.println("SPI initialized.");
Serial.print("Clock divider: 16 (");
Serial.print(F_CPU / 16);
Serial.println(" Hz)");
Serial.println();
// Send test pattern
Serial.println("Sending test pattern via SPI:");
byte testData[] = {0xAA, 0x55, 0xFF, 0x00, 0x42, 0xDE, 0xAD, 0xBE};
digitalWrite(SS_PIN, LOW); // Select slave
for (int i = 0; i < sizeof(testData); i++) {
byte sent = testData[i];
byte received = SPI.transfer(sent);
Serial.print(" TX: 0x");
if (sent < 16) Serial.print("0");
Serial.print(sent, HEX);
Serial.print(" RX: 0x");
if (received < 16) Serial.print("0");
Serial.print(received, HEX);
if (sent == received) {
Serial.println(" (loopback OK)");
} else {
Serial.println();
}
}
digitalWrite(SS_PIN, HIGH); // Deselect slave
Serial.println();
Serial.println("SPI test complete.");
}
void loop() {
delay(1000);
}
Разберем ключевые части:
#include <SPI.h>: Подключает библиотеку SPI Arduino.#define SS_PIN 10: Определяет вывод выбора ведомого как вывод 10.setup(): Инициализирует последовательную связь на скорости 9600 бод, настраивает вывод SS как выход и устанавливает его в высокий уровень, затем вызываетSPI.begin()для инициализации периферии SPI. Делитель тактовой частоты установлен на 16, что дает тактовую частотуF_CPU / 16(1 МГц для Arduino с частотой 16 МГц).- Тестовый шаблон: Массив из 8 байт (
0xAA, 0x55, 0xFF, 0x00, 0x42, 0xDE, 0xAD, 0xBE) отправляется по одному. digitalWrite(SS_PIN, LOW): Выбирает ведомое устройство (в режиме обратной связи это просто логический шаг).SPI.transfer(sent): Отправляет байт и одновременно принимает байт. В режиме обратной связи принятый байт равен отправленному.- Вывод в последовательный порт: Каждая передача выводится в шестнадцатеричном формате, и если отправленный и принятый байты совпадают, добавляется “(loopback OK)”.
digitalWrite(SS_PIN, HIGH): Отключает ведомое устройство после передачи.loop(): Пустой, за исключением задержки, так как тест выполняется только один раз вsetup().
Ключевые концепции
- Протокол SPI: SPI — это синхронный полнодуплексный протокол с четырьмя проводами: MOSI, MISO, SCK и SS. Ведущий генерирует тактовый сигнал и управляет выбором ведомого.
- Обратная связь: Соединение MOSI с MISO (или использование симулятора, который повторяет сигнал) позволяет тестировать аппаратное обеспечение SPI без внешнего ведомого устройства.
- Делитель тактовой частоты: Функция
SPI.setClockDivider()устанавливает частоту SCK относительно системной тактовой частоты. Меньшие делители означают более быструю связь. SPI.transfer(): Эта функция одновременно отправляет и принимает байт. Это основа связи SPI.
Распространенные ошибки и советы по отладке
- Настройка вывода SS: Вывод SS должен быть настроен как выход; в противном случае аппаратное обеспечение SPI может автоматически переключиться в ведомый режим. Всегда устанавливайте
pinMode(SS_PIN, OUTPUT)и устанавливайте его в высокий уровень в режиме ожидания. - Несоответствие скорости передачи: Убедитесь, что скорость передачи в мониторе последовательного порта соответствует
Serial.begin(9600). В Velxio монитор последовательного порта открывается автоматически. - Полярность и фаза тактового сигнала: Режим SPI по умолчанию (режим 0) использует SCK с низким уровнем в режиме ожидания и выборку данных по переднему фронту. Если ваше ведомое устройство ожидает другой режим, используйте
SPI.setDataMode(). - Отсутствие внешнего подключения: В этом тесте с обратной связью провода не нужны. Если вы подключаете реальное ведомое устройство, дважды проверьте соединения: MOSI к MOSI, MISO к MISO, SCK к SCK и SS к SS.
Предлагаемые расширения
- Добавьте внешнее ведомое устройство: Смоделируйте датчик или дисплей, добавив второй Arduino в качестве ведомого и написав скетч для ведомого.
- Измените тактовую частоту: Поэкспериментируйте с различными делителями тактовой частоты (например,
SPI_CLOCK_DIV2,SPI_CLOCK_DIV128) и наблюдайте за влиянием на скорость передачи. - Отправляйте большие объемы данных: Измените тестовый шаблон для отправки строки или показаний датчика.
- Используйте прерывания: Реализуйте связь SPI с помощью прерываний для неблокирующих передач.
Попробуйте сами
Готовы погрузиться? Откройте живой пример в Velxio и запустите симуляцию. Вы увидите вывод в последовательный порт с каждым переданным и принятым байтом, подтверждающий обратную связь.
Откройте тест SPI с обратной связью в Velxio
Удачного моделирования!