МИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ
КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ
Ордена Трудового Красного Знамени федеральное государственное бюджетное образовательное учреждение высшего образования
«Московский технический университет связи и информатики»
(МТУСИ)
Кафедра «Интеллектуальные системы в управлении и автоматизации»
(ИСУиА)
ПРАКТИЧЕСКАЯ РАБОТА №7
По дисциплине
Технологии промышленного интернета вещей
По теме
«Протокол передачи данных I2C»
Выполнили:
Студенты 4-го курса
Группы БАП2201
Ли Самен
Мягков А.К.
Проверил:
к.т.н., доцент
Воронов В.И.
Москва 2026
СОДЕРЖАНИЕ
ВЫПОЛНЕНИЕ 3
ВЫВОДЫ 6
Протокол I2C (Inter-Integrated Circuit) – это синхронная полудуплексная шина связи, разработанная компанией Philips для передачи данных между интегральными схемами. В отличие от простого цифрового ввода/вывода, позволяющего передавать лишь логический уровень (0 или 1), I2C обеспечивает последовательную передачу целых байтов данных (от 0 до 255).
Физически связь осуществляется по двум линиям (рисунок 1):
– SDA (Serial Data) – линия передачи данных;
– SCL (Serial Clock) – линия тактирования (синхронизации).
Обязательным условием работы является наличие общей земли (GND) между устройствами. Аппаратная реализация протокола в микроконтроллере ATmega328P (на базе которого построена Arduino Nano) выведена на аналоговые пины A4 (SDA) и A5 (SCL).
Рисунок 1 – Логическая схема подключения двух устройств по шине I2C
Суть синхронизации в I2C заключается в следующем: ведущее устройство (Master) генерирует тактовые импульсы на линии SCL. Приёмник (Slave) считывает состояние линии SDA строго в моменты присутствия высокого логического уровня на SCL. Это исключает ошибки десинхронизации, вызванные разницей в тактовых частотах микроконтроллеров.
Для организации обмена данными в сети используется адресация. Каждое ведомое устройство имеет уникальный 7-битный адрес (от 0 до 127). Перед началом передачи полезной нагрузки Master транслирует в эфир адрес целевого устройства. Только Slave с совпадающим адресом подтверждает готовность к приёму, остальные узлы на шине игнорируют передачу. Благодаря этому к двум проводам можно подключить до 127 периферийных устройств.
ВЫПОЛНЕНИЕ
Для практической реализации протокола была собрана схема из двух плат Arduino Nano. Первая плата выступала в роли ведущего (Master), вторая – ведомого (Slave с адресом 0x08). Целью работы была передача числового значения от Master к Slave и изменение физического состояния (включение/выключение встроенного светодиода) на принимающей стороне в зависимости от полученных данных.
Логика работы программы (Листинг 1, Листинг 2) включает следующие этапы:
1) Инициализация аппаратной шины TWI (I2C) с использованием встроенной библиотеки Wire. Master запускается без адреса, Slave – с параметром 0x08;
2) На стороне Master реализован цикличный счётчик (от 0 до 255). Каждые 500 мс инициируется пакетная передача: формирование старт-бита, отправка адреса Slave, отправка байта данных, формирование стоп-бита;
3) На стороне Slave реализована система прерываний. При поступлении адреса 0x08 и последующих данных аппаратно вызывается функция-обработчик receiveEvent. Внутри прерывания считывается байт из буфера и устанавливается флаг готовности данных;
4) В основном цикле loop() ведомой платы проверяется флаг: если полученное значение превышает порог 127, на пин LED_BUILTIN подается высокий уровень, в противном случае – низкий.
Листинг 1 – Программа для Arduino Nano 1 (Master) на языке C++ |
#include <Wire.h> #define SLAVE_ADDRESS 0x08 byte counter = 0; void setup() { Wire.begin(); Serial.begin(9600); } void loop() { Wire.beginTransmission(SLAVE_ADDRESS); Wire.write(counter); byte error = Wire.endTransmission(); if (error == 0) { Serial.print("Успешно отправлено: "); Serial.println(counter); } else { Serial.println("ОШИБКА: Устройство не найдено!"); } counter++; delay(500); } |
Листинг 2 – Программа для Arduino Nano 2 (Slave) на языке C++ |
#include <Wire.h> #define SLAVE_ADDRESS 0x08 volatile byte receivedValue = 0; volatile bool dataReady = false; void setup() { Serial.begin(9600); Wire.begin(SLAVE_ADDRESS); Wire.onReceive(receiveEvent); pinMode(LED_BUILTIN, OUTPUT); } void loop() { if (dataReady) { if (receivedValue > 127) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } Serial.print("Получено от Мастера: "); Serial.println(receivedValue); dataReady = false; } } void receiveEvent(int howMany) { while (Wire.available()) { receivedValue = Wire.read(); } dataReady = true; } |
На рисунке 2 представлена физическая схема соединения плат. Проводами соединены пины GND (рыжий провод), A4 (белый провод, линия SDA) и A5 (коричневый провод, линия SCL).
Рисунок 2 – Схема соединения двух Arduino Nano по интерфейсу I2C
Примечание: в условиях коротких соединений в лабораторной работе были использованы внутренние подтягивающие резисторы микроконтроллера. При проектировании промышленных систем на шину SDA и SCL обязательно устанавливаются внешние резисторы номиналом 4.7 кОм между линиями и питанием +5В.
Для верификации работоспособности системы была проведена проверка с использованием инструмента последовательного порта (Serial Monitor) в Arduino IDE. В ходе тестирования (рисунок 3) было зафиксировано, что Master успешно отправляет инкрементируемые значения, а Slave корректно их принимает.
Рисунок 3 – Лог монитора последовательного порта:
слева – Master (отправка), справа – Slave (приём и управление светодиодом)
Визуально было подтверждено срабатывание исполнительного механизма: встроенный светодиод на плате Slave переходил в состояние «Включено» при получении значений из диапазона 128–255, и в состояние «Выключено» при получении значений 0 – 127.
ВЫВОДЫ
Реализована передача данных между двумя микроконтроллерами Arduino Nano по протоколу I2C. В отличие от дискретного ввода-вывода, применение интерфейса I2C позволило организовать адресную передачу многобитных пакетов данных по двухпроводной шине. В программном коде ведомого устройства была применена аппаратная обработка прерываний для асинхронного приёма данных без блокировки основного цикла программы. Функциональность созданной сети проверена путём мониторинга последовательного порта и визуального наблюдения за управлением индикатором на устройствах.
