4.10. Интерфейсы связи - SPI.md
Мы уже познакомились с UART для простой связи точка-точка и с I2C для подключения множества устройств на одну шину. Но что, если нам нужна максимальная скорость? Например, для потоковой передачи данных на цветной дисплей или для быстрой записи на SD-карту. В таких задачах на сцену выходит SPI (Serial Peripheral Interface) — последовательный периферийный интерфейс.
SPI — это, пожалуй, самый быстрый из трёх последовательных интерфейсов, которые мы рассматриваем. Он, как и I2C
, является синхронным, но его архитектура позволяет достигать гораздо более высоких скоростей передачи данных.
Принцип работы SPI - прямое соединение
Если I2C
можно сравнить с автобусом, где все ждут на одной дороге, то SPI больше похож на прямую телефонную линию между двумя абонентами. Связь всегда происходит между одним Ведущим (Master
, наш Рудирон
) и одним Ведомым (Slave
).
Для базового соединения SPI использует четыре провода:
- SCLK (Serial Clock) - линия тактирования. Сигналы по ней генерирует Ведущий, задавая темп обмена данными.
- MOSI (Master Out, Slave In) - линия, по которой Ведущий передаёт данные Ведомому.
- MISO (Master In, Slave Out) - линия, по которой Ведомый передаёт данные Ведущему.
- SS (Slave Select) / CS (Chip Select) линия выбора ведомого. Это очень важный пин. Ведущий использует его, чтобы «активировать» конкретное ведомое устройство, с которым он хочет сейчас общаться. На пине SS активного устройства должен быть установлен низкий уровень (
LOW
).
Преимущество такой архитектуры в том, что данные могут передаваться одновременно в обе стороны (полнодуплексный режим) - Рудирон
может отправлять байт на SD-карту и в то же самое время получать другой байт от неё.
Подключение нескольких устройств
“Но как же подключить несколько устройств, если линия прямая?” — спросите вы. Очень просто! Линии SCLK, MOSI и MISO остаются общими для всех устройств, а вот линия SS для каждого ведомого будет своя, идущая от отдельного GPIO
пина Рудирона
.
Когда Рудирону
нужно поговорить, например, с дисплеем, он устанавливает LOW
на пине SS
, подключённом к дисплею, и HIGH
на всех остальных пинах SS
. Таким образом, только дисплей будет «слушать» команды, а остальные устройства на шине будут их игнорировать.
SPI на плате Рудирон
Рудирон
предоставляет целых два аппаратных SPI-интерфейса, что является большим преимуществом для сложных проектов.
Основной SPI (SPI1):
- MOSI: Пин 3 (
F0
). - MISO: Пин 0 (
F3
). - SCLK: Пин 2 (
F1
). - SS: По умолчанию для библиотеки
SPI
может использоваться пин 1 (F2
), но вы можете выбрать любой другойGPIO
пин для управления линиейSS
.
Дополнительный SPI (SPI2):
- MOSI: Пин 21 (
D6
). - MISO: Пин 24 (
D2
). - SCLK: Пин 22 (
D5
). - SS: Любой свободный
GPIO
пин.
Библиотека SPI
Для работы с интерфейсом используется стандартная библиотека SPI
.
Инициализация — SPI.begin()
В setup()
необходимо инициализировать интерфейс.
#include <SPI.h> // Подключаем библиотеку
void setup() {
SPI.begin(); // Инициализируем SPI
}
Настройка транзакции — SPI.beginTransaction()
Перед тем, как начать обмен данными с конкретным устройством, хорошей практикой является настройка параметров SPI (скорость, порядок бит и режим работы) в соответствии с требованиями этого устройства.
// Настраиваем SPI для нашего устройства: 4 МГц, старший бит вперёд, режим 0
SPISettings mySettings(4000000, MSBFIRST, SPI_MODE0);
void loop() {
SPI.beginTransaction(mySettings);
// Здесь будет код обмена данными
...
SPI.endTransaction();
}
Обмен данными — SPI.transfer()
Это ключевая функция для отправки и приёма данных. Она одновременно отправляет байт и принимает байт.
byte incomingByte = SPI.transfer(outgoingByte);
outgoingByte
— байт, который вы хотите отправить.incomingByte
— байт, который был получен от ведомого в тот же самый момент. Если вам не нужно ничего получать, вы можете просто проигнорировать возвращаемое значение.
Пример (условное чтение из SPI-устройства):
#include <SPI.h>
const int ssPin = 1; // Используем пин 1 как Slave Select
void setup() {
Serial.begin(9600);
SPI.begin();
pinMode(ssPin, OUTPUT);
digitalWrite(ssPin, HIGH); // Устройство неактивно
}
void loop() {
digitalWrite(ssPin, LOW); // Активируем ведомое устройство
// Отправляем команду "прочитать регистр 0x10"
SPI.transfer(0x10);
// Отправляем "пустой" байт, чтобы получить ответ
byte data = SPI.transfer(0x00);
digitalWrite(ssPin, HIGH); // Деактивируем ведомое устройство
Serial.print("Получены данные: 0x");
Serial.println(data, HEX);
delay(1000);
}
Зачем это нужно?
Благодаря высокой скорости и полнодуплексному режиму, SPI является идеальным выбором для задач, требующих интенсивного обмена данными:
- Работа с памятью: чтение и запись на SD-карты и микросхемы Flash-памяти.
- Дисплеи: быстрый вывод графики на TFT и OLED экраны.
- Сетевые модули: подключение Ethernet-контроллеров (
W5500
) и радиомодулей (NRF24L01
). - Быстрые преобразователи: работа с высокоскоростными АЦП и ЦАП.
Поздравляем! Вы завершили изучение основных инструментов для программирования микроконтроллеров. Вы научились управлять цифровыми и аналоговыми сигналами, использовать прерывания для мгновенной реакции, организовывать многозадачность и общаться с внешним миром через интерфейсы UART, I2C и SPI. Теперь у вас есть все необходимые знания, чтобы приступить к созданию собственных, даже самых смелых проектов. Удачи в ваших начинаниях
- Страницы
- 1. Введение
- 1.01. Лабораторная работа №1.1
- 1.02. Лабораторная работа №1.2
- 1.03. Лабораторная работа №1.3
- 1.04. Лабораторная работа №1.4
- 1.05. Лабораторная работа №1.5
- 2. Основы электроники
- 2.01. Электрический ток и параметры цепи
- 2.01.1. Лабораторная работа №2.1.1
- 2.01.2. Лабораторная работа №2.1.2
- 2.02. Сопротивление в цепи
- 2.02.1. Лабораторная работа №2.2.1
- 2.02.2. Лабораторная работа №2.2.2
- 2.03. Полупроводники
- 2.03.1. Лабораторная работа №2.3.1
- 2.03.2. Лабораторная работа №2.3.2
- 3. Основы программирование на C++
- 3.01. Типы данных и переменные
- 3.01.1. Практикум
- 3.02. Операторы в C++
- 3.02.1. Практикум
- 3.03. Структуры ветвления
- 3.03.1. Практикум
- 3.04. Структуры повторения
- 3.04.1. Практикум
- 3.05. Массивы
- 3.05.1. Практикум
- 3.06. Функции
- 3.06.1. Практикум
- 3.07. Решения задач
- 4. Программирование микроконтроллеров
- 4.01. Цифровые сигналы и GPIO
- 4.01.1. Лабораторная работа №4.1.1
- 4.01.2. Лабораторная работа №4.1.2
- 4.01.3. Лабораторная работа №4.1.3
- 4.01.4. Лабораторная работа №4.1.4
- 4.01.5. Лабораторная работа №4.1.5
- 4.01.6. Лабораторная работа №4.1.6
- 4.01.7. Лабораторная работа №4.1.7
- 4.01.8. Лабораторная работа №4.1.8
- 4.02. Аналоговые сигналы и ШИМ
- 4.02.1. Лабораторная работа №4.2.1
- 4.02.2. Лабораторная работа №4.2.2
- 4.02.3. Лабораторная работа №4.2.3
- 4.02.4. Лабораторная работа №4.2.4
- 4.02.5. Лабораторная работа №4.2.5
- 4.03. Аналоговый сигнал и АЦП
- 4.03.1. Лабораторная работа №4.3.1
- 4.03.2. Лабораторная работа №4.3.2
- 4.03.3. Лабораторная работа №4.3.3
- 4.03.4. Лабораторная работа №4.3.4
- 4.03.5. Лабораторная работа №4.3.5
- 4.04. Аналоговый сигнал и ЦАП
- 4.04.1. Лабораторная работа №4.4.1
- 4.04.2. Лабораторная работа №4.4.2
- 4.05. Генерация и измерение импульсов
- 4.05.1. Лабораторная работа №4.5.1
- 4.05.2. Лабораторная работа №4.5.2
- 4.06. Аппаратные прерывания
- 4.06.1. Лабораторная работа №4.6.1
- 4.06.2. Лабораторная работа №4.6.2
- 4.07. Псевдопараллелизм
- 4.07.1. Лабораторная работа №4.7.1
- 4.07.2. Лабораторная работа №4.7.2
- 4.08. Интерфейсы связи - UART
- 4.08.1. Лабораторная работа №4.8.1
- 4.09. Интерфейсы связи - I2C
- 4.09.1. Лабораторная работа №4.9.1
- 4.10. Интерфейсы связи - SPI
- 4.10.1. Лабораторная работа №4.10.1
- home
-
imgs
- 1. Введение
- 1.01. Лабораторная работа №1.1
- 1.02. Лабораторная работа №1.2
- 1.03. Лабораторная работа №1.3
- 1.04. Лабораторная работа №1.4
- 1.05. Лабораторная работа №1.5
- 2. Основы электроники
- 2.01. Электрический ток и параметры цепи
- 2.01.1. Лабораторная работа №2.1.1
- 2.01.2. Лабораторная работа №2.1.2
- 2.02. Сопротивление в цепи
- 2.02.1. Лабораторная работа №2.2.1
- 2.02.2. Лабораторная работа №2.2.2
- 2.03. Полупроводники
- 2.03.1. Лабораторная работа №2.3.1
- 2.03.2. Лабораторная работа №2.3.2
- 3. Основы программирование на C++
- 3.01. Типы данных и переменные
- 3.01.1. Практикум
- 3.02. Операторы в C++
- 3.02.1. Практикум
- 3.03. Структуры ветвления
- 3.03.1. Практикум
- 3.04. Структуры повторения
- 3.04.1. Практикум
- 3.05. Массивы
- 3.05.1. Практикум
- 3.06. Функции
- 3.06.1. Практикум
- 3.07. Решения задач
- 4. Программирование микроконтроллеров
- 4.01. Цифровые сигналы и GPIO
- 4.01.1. Лабораторная работа №4.1.1
- 4.01.2. Лабораторная работа №4.1.2
- 4.01.3. Лабораторная работа №4.1.3
- 4.01.4. Лабораторная работа №4.1.4
- 4.01.5. Лабораторная работа №4.1.5
- 4.01.6. Лабораторная работа №4.1.6
- 4.01.7. Лабораторная работа №4.1.7
- 4.01.8. Лабораторная работа №4.1.8
- 4.02. Аналоговые сигналы и ШИМ
- 4.02.1. Лабораторная работа №4.2.1
- 4.02.2. Лабораторная работа №4.2.2
- 4.02.3. Лабораторная работа №4.2.3
- 4.02.4. Лабораторная работа №4.2.4
- 4.02.5. Лабораторная работа №4.2.5
- 4.03. Аналоговый сигнал и АЦП
- 4.03.1. Лабораторная работа №4.3.1
- 4.03.2. Лабораторная работа №4.3.2
- 4.03.3. Лабораторная работа №4.3.3
- 4.03.4. Лабораторная работа №4.3.4
- 4.03.5. Лабораторная работа №4.3.5
- 4.04. Аналоговый сигнал и ЦАП
- 4.04.1. Лабораторная работа №4.4.1
- 4.04.2. Лабораторная работа №4.4.2
- 4.05. Генерация и измерение импульсов
- 4.05.1. Лабораторная работа №4.5.1
- 4.05.2. Лабораторная работа №4.5.2
- 4.06. Аппаратные прерывания
- 4.06.1. Лабораторная работа №4.6.1
- 4.06.2. Лабораторная работа №4.6.2
- 4.07. Псевдопараллелизм
- 4.07.1. Лабораторная работа №4.7.1
- 4.07.2. Лабораторная работа №4.7.2
- 4.08. Интерфейсы связи - UART
- 4.08.1. Лабораторная работа №4.8.1
- 4.09. Интерфейсы связи - I2C
- 4.09.1. Лабораторная работа №4.9.1
- 4.10. Интерфейсы связи - SPI
- 4.10.1. Лабораторная работа №4.10.1
- home