Встраиваемые системы

GPIO, UART, SPI, I2C

2016 год, проект SpaceX Falcon 9. Первый раз ракета садится обратно на платформу. За этим стоят сотни MCU: GPIO-пины управляют клапанами двигателей, UART гонит телеметрию на землю, SPI обновляет flash с параметрами ориентации, I2C читает 12 датчиков давления с двух проводов. Четыре протокола - один шедевр инженерии.

  • **Метеостанция:** I2C-датчики температуры, давления, влажности на 2 проводах + SPI-дисплей для отображения + UART для отправки данных на ПК
  • **Дрон:** SPI-гироскоп/акселерометр (6000 Гц выборка), I2C-барометр (высота), UART-GPS, GPIO-управление моторами через PWM
  • **Промышленный контроллер:** RS-485 (UART) для связи на 1 км, SPI-Flash для логов, I2C-EEPROM для настроек

Philips, 1980: изобретение I2C

В 1980 году инженеры Philips Semiconductors столкнулись с проблемой: телевизионные чипсеты требовали десятки интерфейсных линий между микросхемами. Ответом стал I2C - Inter-Integrated Circuit. Два провода, адресация до 128 устройств. Патент истёк в 2006 году - и протокол стал бесплатным для всех. SPI появился чуть раньше в Motorola (1979). UART ещё старше - 1960-е, IBM. Все три протокола пережили несколько поколений техники и живут в каждом современном устройстве.

Предварительные знания

  • Microcontroller Architecture

GPIO: цифровые пины

2003 год. Первый коммерческий Arduino-прото ещё не существует, но в Atmel уже понимают: MCU нужен выход во внешний мир. **GPIO** (General Purpose Input/Output) - самый примитивный способ. Каждый пин - либо **вход** (читаем 0 или 1 - кнопка нажата?), либо **выход** (устанавливаем 0 или 1 - включить LED). Ни протокола, ни пакетов - один бит, один провод.

**GPIO** - универсальные пины ввода/вывода. Режимы: **Input** (чтение: floating, pull-up, pull-down), **Output** (запись: push-pull, open-drain), **Alternate Function** (UART, SPI, I2C - пин управляется периферией), **Analog** (ADC/DAC). Состояние выхода: **0** = GND (0V), **1** = VCC (3.3V или 5V).

РежимPush-PullOpen-Drain
Выход 1Подключает к VCCОтключает (высокоимпедансный)
Выход 0Подключает к GNDПодключает к GND
ПрименениеLED, обычные выходыI2C (SDA, SCL), шины с несколькими устройствами
Внешний pull-upНе нуженОбязателен

**Скорость переключения** GPIO настраивается: Low (2 MHz), Medium (25 MHz), High (50 MHz), Very High (100 MHz). Высокая скорость = больше EMI и потребление тока. Для LED достаточно Low, для SPI-clock нужен High. Неправильная скорость - источник загадочных помех на осциллографе.

Кнопка подключена между пином PA0 и GND. Какой pull нужно настроить, чтобы без нажатия читать 1, а при нажатии - 0?

UART: последовательный порт

GPIO передаёт 1 бит на 1 провод. Для текста, чисел и команд нужен **протокол**. Самый простой - **UART** (Universal Asynchronous Receiver-Transmitter). Два провода: TX (передача) и RX (приём). Именно через UART отладочные printf() попадают в терминал на ПК. Каждый embedded-разработчик видел `/dev/ttyACM0` - это он.

**UART** - асинхронный последовательный протокол. Параметры: **Baud rate** (скорость, обычно 9600 или 115200 бод), **формат кадра** 8N1 = 8 бит данных + No parity + 1 stop бит. Нет тактового сигнала - передатчик и приёмник должны договориться о baud rate заранее. Линия в покое = 1 (idle), начало кадра = 0 (start bit).

ПараметрЗначениеПримечание
Проводов2 (TX + RX) + GNDПерекрёстное подключение: TX->RX, RX->TX
Скорость9600 - 3,000,000 бод115200 - стандарт для отладки
ДуплексFull-duplexОдновременная передача и приём
РасстояниеДо 15 м (RS-232)С RS-485: до 1200 м
УстройстваТочка-точка (1:1)Для 1:N нужен RS-485

**Главная ошибка новичков:** baud rate на передатчике и приёмнике ДОЛЖЕН совпадать. Если MCU настроен на 115200, а терминал на 9600 - в терминале будет мусор. UART асинхронный - нет тактового сигнала, который бы синхронизировал.

MCU отправляет данные по UART на 115200 бод, а ПК принимает на 9600 бод. Что увидит ПК?

SPI: быстрая синхронная шина

UART хорош для отладки, но дисплей на 240x320 пикселей - это 76800 байт на кадр. При 115200 бод - 5 секунд на один кадр. Катастрофа. Для быстрого обмена существует **SPI** (Serial Peripheral Interface) - синхронный протокол с отдельным тактовым сигналом. Скорости до **50+ MHz**. Один кадр дисплея - 12 миллисекунд.

**SPI** - синхронный, full-duplex протокол с 4 сигналами: **MOSI** (Master Out Slave In - данные от мастера), **MISO** (Master In Slave Out - данные от slave), **SCK/SCLK** (тактовый сигнал от мастера), **CS/SS** (Chip Select - выбор slave, active low). MCU = master, датчик/дисплей = slave.

ПараметрSPIUART
СинхронизацияСинхронный (SCK)Асинхронный (baud rate)
СкоростьДо 50+ MHzДо 3 Mbaud
Проводов4 (MOSI, MISO, SCK, CS)2 (TX, RX)
ДуплексFull-duplexFull-duplex
Устройства1 master + N slaves (N линий CS)Точка-точка
ПрименениеFlash, дисплеи, SD-картыОтладка, GPS, Bluetooth

**SPI Mode (CPOL/CPHA):** 4 комбинации определяют, по какому фронту SCK данные фиксируются. Mode 0 (CPOL=0, CPHA=0) - самый распространённый. Несовпадение Mode между master и slave = мусор. Всегда проверяйте datasheet устройства!

На SPI-шине подключены 3 slave-устройства. Сколько GPIO-пинов MCU нужно для CS?

I2C: мультиустройственная шина

Умные часы, 2013 год. Датчик пульса, акселерометр, барометр, гироскоп, магнитометр, EEPROM для настроек. SPI потребовал бы 6 линий CS + 3 общих = 9 дополнительных пинов только на периферию. **I2C** (Inter-Integrated Circuit) - два провода на всё: **SDA** и **SCL**. До 128 устройств. Уникальный 7-битный адрес на каждое.

**I2C** (произносится «ай-ту-си» или «ай-сквэрд-си») - синхронный, half-duplex протокол с адресацией. Два провода: **SDA** (Serial Data) и **SCL** (Serial Clock), оба с pull-up резисторами к VCC. Скорости: Standard (100 kHz), Fast (400 kHz), Fast Plus (1 MHz), High Speed (3.4 MHz). Master генерирует SCL, slave отвечает по адресу.

ПараметрI2CSPIUART
Проводов2 (SDA, SCL)4 + N (CS)2 (TX, RX)
Скорость100 kHz - 3.4 MHz1 - 50+ MHz9600 - 3M бод
ДуплексHalf-duplexFull-duplexFull-duplex
Адресация7-бит (до 128 устройств)CS-линия на устройствоНет (точка-точка)
Pull-upОбязательныНе нужныНе нужны
ПрименениеДатчики, EEPROM, RTCFlash, дисплей, SDОтладка, GPS, BT

**Когда что использовать?** I2C - для медленных датчиков (температура, давление, акселерометр), когда важна экономия пинов. SPI - для быстрых устройств (дисплей, Flash, SD-карта), когда скорость важнее числа проводов. UART - для связи с ПК, GPS-модулями, Bluetooth.

SPI быстрее, значит всегда лучше I2C. Нужно использовать SPI для всех задач

I2C использует 2 провода вместо 4+N, поддерживает до 128 устройств на одной шине и достаточно быстр для большинства датчиков (100-400 kHz). Для термометра, акселерометра, барометра I2C - оптимальный выбор

На реальной плате каждый провод - дорожка на PCB, место на разъёме и потенциальная точка отказа. 10 I2C-датчиков = 2 провода. 10 SPI-датчиков = 13 проводов + 10 GPIO пинов MCU под CS. Датчик температуры отдаёт данные раз в секунду - зачем ему 50 MHz SPI? I2C на 400 kHz более чем достаточно.

На I2C-шине подключены 5 датчиков. Сколько проводов (не считая GND и VCC) нужно от MCU?

Ключевые идеи

  • **GPIO** - базовый ввод/вывод: push-pull/open-drain выходы, pull-up/pull-down входы, скорость до 100 MHz
  • **UART** - асинхронный последовательный протокол (2 провода), до 3 Mbaud, отладка и связь точка-точка
  • **SPI** - синхронный, full-duplex, до 50+ MHz, 4 провода + CS на каждый slave: Flash, дисплеи, SD-карты
  • **I2C** - синхронный, 2 провода на 128 устройств, 100 kHz - 3.4 MHz, идеален для датчиков

Связанные темы

Интерфейсы - практическое применение знаний об архитектуре MCU:

  • Архитектура микроконтроллеров — Memory-Mapped I/O - так MCU обращается к регистрам UART/SPI/I2C
  • Таймеры и PWM — PWM через GPIO для управления моторами и яркостью LED

Вопросы для размышления

  • Проектируется умные часы с датчиком пульса, акселерометром, дисплеем и Bluetooth-модулем. Какой интерфейс подходит для каждого компонента и почему?
  • I2C использует open-drain с pull-up резисторами. Почему нельзя использовать push-pull для шины, к которой подключены несколько устройств?
  • GPIO - как отдельный нерв (вкл/выкл), I2C - как адресная шина спинного мозга. Какая аналогия подходит для SPI и UART?

Связанные уроки

  • emb-02 — Memory-Mapped I/O - основа обращения к регистрам UART/SPI/I2C
  • emb-04 — PWM через GPIO для управления моторами и яркостью LED
  • rob-03 — ROS 2 на роботах использует SPI/I2C для сенсоров и UART для GPS
  • rts-01 — Real-time ограничения диктуют выбор протокола: SPI vs I2C
  • par-01 — DMA-передача по SPI/UART - параллелизм на уровне железа
  • emb-05 — ADC/DAC работают через те же GPIO Alternate Function пины
  • net-01-intro
GPIO, UART, SPI, I2C

0

1

Войти