Общие сведения:
Шина I2C (ай-ту-си) это аббревиатура от "Inter-Integrated Circuit" - шина передачи данных между интегральными схемами. Данная шина изобретена компанией Philips Semiconductor (теперь NXP), для передачи данных между чипами на одной плате по двум линиям. Но простота протокола и удобство подключения привели к тому, что в настоящее время данная шина широко применяется для подключения отдельных модулей к микроконтроллерам.
Для возможности подключения нескольких ведомых к одной шине используются адресация. Каждое ведомое устройство на шине I2C имеет свой уникальный адрес. Только мастер является инициатором приёма/передачи данных, он отправляет сигнал Start за которым следует адрес ведомого и бит направления передачи. Завершается пакет, так же по инициативе мастера, который отправляет сигнал Stop. С более подробным описанием сигналов на шине I2C, составе пакета, подтягивающих резисторах, паразитных ёмкостях и длине шины I2C, можно ознакомиться на странице Wiki - I²C - Inter-Integrated Circuit, краткое руководство.
Аппаратная шина I2C это шина реализованная на физическом уровне (внутренними блоками микроконтроллера), такая шина имеет заранее определённые выводы. На платах Arduino UNO и Piranha UNO есть только одна аппаратная шина I2C использующая выводы: A4 - SDA и A5 - SCL. На некоторых платах, например, Arduino UNO R4 есть сразу несколько аппаратных шин I2C. Но есть и платы с микроконтроллерами у которых вообще нет аппаратных шин I2C. Достоинство аппаратных шин в том, что они не используют вычислительные ресурсы микроконтроллера, он может заниматься выполнением вашей программы параллельно с тем как принимаются или передаются данные по шине, "отвлекаясь" только на прерывания окончания приёма/передачи или совпадение адреса ведомого.
Для работы с аппаратной шиной в Arduino IDE используется предустановленная библиотека Wire.h
у которой заранее определены имена объектов:
Wire
- для работы с основной (или единственной) аппаратной шиной I2C.Wire1
- для работы с первой (после основной) аппаратной шиной I2C.Wire2
- для работы с второй аппаратной шиной I2C и т.д.
Программная шина I2C это шина реализованная (как понятно из названия) программно. Такая шина имеет ряд недостатков: она занимает память программ и часть ОЗУ, она использует вычислительные ресурсы микроконтроллера. Но у такой шины есть два преимущества:
- Можно создать несколько шин I2C, даже если их не было у микроконтроллера.
Например, на плате Arduino UNO можно создать до 10 программных шин I2C. - Можно выбрать любые выводы для создания шины I2C.
Выводы должны поддерживать работу как логический вход/выход.
Для реализации программных шин I2C предлагаем воспользоваться разработанной нами библиотекой iarduino_I2C_Software.h. Эта библиотека имеет тот же синтаксис, что и библиотека Wire.h
и поддерживает все её методы и функции для работы в качестве мастера. Обе библиотеки могут работать в одном скетче, так объекты библиотек создаются как экземпляры разных классов:
- Объекты библиотеки Wire являются экземплярами класса
TwoWire
. - Объекты библиотеки iarduino_I2C_Software являются экземплярами класса
SoftTwoWire
.
Подключение:
Шина I2C состоит из двух диний:
- SDA "serial data" - последовательные данные
- SCL "serial clock" - последовательное тактирование.
Для аппаратной шины I2C выводы линий SDA и SCL указаны на плате или в документации.
![](http://iarduino.ru/img/upload/3315bef65a38ce76e8cee014f2d4e633.png)
Для программной шины I2C выводы SDA и SCL вы назначаете сами.
![](http://iarduino.ru/img/upload/a075af1a314d36e69154a17e39b544e1.png)
Примеры:
В данном разделе раскрыты примеры работы в качестве мастера по программной шине I2C с использованием библиотеки iarduino_I2C_Software. Сама библиотека содержит больше примеров, доступных из меню Arduino IDE: Файл / Примеры / iarduino_I2C_Software.
Во всех примерах программная шина I2C создаётся на выводах: 3 (SDA) и 4 (SCL).
ВАЖНО: Будьте осторожны с примерами записи данных в регистры ведомого! Некоторые модули, в т.ч. Flash-I2C и Metro, могут сохранять записанные данные регистров в энергонезависимую память.
Пример записи одного байта в один регистр:
В примере, ведомому с адресом adr, в регистр reg, записываться значение data, которое увеличивается на 1 каждую секунду.
// Данные для записи (можно менять): // uint8_t adr = 0x09; // Адрес ведомого на шине I2C. uint8_t reg = 50; // Номер регистра в который нужно записать значение. uint8_t data = 0; // Значение для записи в регистр. // #include <iarduino_I2C_Software.h> // Подключаем библиотеку для работы с программной шиной I2C. SoftTwoWire sWire(3,4); // Создаём объект, указав выводы: SDA, SCL. // Допускается создавать несколько объектов, следовательно, несколько программных шин I2C. void setup(){ // sWire.begin(); // Инициируем работу с программной шиной I2C. } // // void loop(){ // sWire.beginTransmission(adr); // Инициируем передачу данных по шине I2C к устройству с адресом adr. При этом сама передача не начнётся. sWire.write(reg); // Помещаем в буфер для передачи один байт: адрес регистра для записи. sWire.write(data); // Помещаем в буфер для передачи один байт: данные для записи в регистр. // sWire.write(байт); // Следующие данные помещённые в буфер, будут записаны в следующие по порядку регистры. sWire.endTransmission(); // Выполняем инициированную ранее передачу данных. // Задержка перед новой записью: // data++; // Увеличиваем значение data. delay(1000); // Ждём 1 секунду. } //
Функция endTransmission()
возвращает результат записи, который можно использовать для проверки: 0-успех, 1 - переполнен буфер, 2 - получен NACK при передаче адреса, 3 - получен NACK при передаче данных, 4 - другая ошибка, 5 - timeout.
Если вместо библиотеки iarduino_I2C_Software
подключить библиотеку Wire
, не создавать объект sWire
, а использовать объект Wire
, то тот же пример будет работать с аппаратной шиной I2C.
Пример записи нескольких байт:
В примере, данные для передачи (4 байта из массива arr) передаются ведомому с адресом adr, начиная с регистра reg. Запись выполняется каждую секунду.
// Данные для записи (можно менять): // uint8_t adr = 0x09; // Адрес ведомого на шине I2C. uint8_t reg = 50; // Номер регистра с которого требуется начать запись. uint8_t arr[] = {1,2,3,4}; // От 1 до 32 байт для записи в регистры. uint8_t sum = 4; // Количество байт для записи в регистры. // #include <iarduino_I2C_Software.h> // Подключаем библиотеку для работы с программной шиной I2C. SoftTwoWire sWire(3,4); // Создаём объект, указав выводы: SDA, SCL. // Допускается создавать несколько объектов, следовательно, несколько программных шин I2C. void setup(){ // sWire.begin(); // Инициируем работу с программной шиной I2C. } // // void loop(){ // sWire.beginTransmission(adr); // Инициируем передачу данных по шине I2C к устройству с адресом adr. При этом сама передача не начнётся. sWire.write(reg); // Помещаем в буфер для передачи один байт (адрес первого регистра для записи). sWire.write(arr, sum); // Помещаем в буфер для передачи sum байт данных из массива arr (данные для записи). sWire.endTransmission(); // Выполняем инициированную ранее передачу данных. // Задержка перед новой записью: // delay(1000); // Ждём 1 секунду. } //
Функция endTransmission()
возвращает результат записи, который можно использовать для проверки: 0-успех, 1 - переполнен буфер, 2 - получен NACK при передаче адреса, 3 - получен NACK при передаче данных, 4 - другая ошибка, 5 - timeout.
Если вместо библиотеки iarduino_I2C_Software
подключить библиотеку Wire
, не создавать объект sWire
, а использовать объект Wire
, то тот же пример будет работать с аппаратной шиной I2C.
Пример чтения одного или нескольких регистров:
В примере, читаются sum байт, начиная с регистра reg, ведомого с адресом adr.
// Данные для чтения (можно менять): // uint8_t adr = 0x09; // Адрес ведомого на шине I2C. uint8_t reg = 50; // Номер регистра с которого требуется начать чтение. uint8_t sum = 4; // Количество байт для чтения из регистров. // #include <iarduino_I2C_Software.h> // Подключаем библиотеку для работы с программной шиной I2C. SoftTwoWire sWire(3,4); // Создаём объект, указав выводы: SDA, SCL. // Допускается создавать несколько объектов, следовательно, несколько программных шин I2C. void setup(){ // sWire.begin(); // Инициируем работу с программной шиной I2C. Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бит/сек. } // // void loop(){ // sWire.beginTransmission(adr); // Инициируем передачу данных по шине I2C к устройству с адресом adr. При этом сама передача не начнётся. sWire.write(reg); // Помещаем в буфер для передачи один байт (адрес первого читаемого регистра). sWire.endTransmission(false); // Выполняем инициированную ранее передачу данных, без установки STOP. sWire.requestFrom(adr, sum); // Читаем (запрашиваем) sum байт данных от устройства с адресом adr. // Выводим прочитанные данные: // while( sWire.available() ){ // Если в буфере остались данные... Serial.println(sWire.read()); // Выводим очередной прочитанный байт. } Serial.println("----------"); // // Задержка перед новым чтением: // delay(1000); // Ждём 1 секунду. } //
Функция requestFrom()
возвращает количество прочитанных байт, а функция available()
возвращает количество байт в буфере которые доступны для получения функцией read()
.
Если вместо библиотеки iarduino_I2C_Software
подключить библиотеку Wire
, не создавать объект sWire
, а использовать объект Wire
, то тот же пример будет работать с аппаратной шиной I2C.
Примеры использования объектов работы с шиной I2C:
Для работы библиотек iarduino с датчиками и модулями по шине I2C, нужно сначала подключить библиотеку для работы с самой шиной I2C, а потом указать ссылку на объект работы с шиной I2C в качестве первого параметра функции begin(). Таким образом библиотеки iarduino будут работать с модулями по той шине, с которой работает указанный им объект.
Для аппаратной шины указываются ссылки на объекты Wire, Wire1, Wire2, ..., библиотеки Wire.h, а для программной шины, ссылка на объект библиотеки iarduino_I2C_Software. Если ссылка не указана, то по умолчанию используется объект Wire (основная аппаратная шина I2C).
- Аппаратная шина:
В примере библиотека iarduino_AM2320 для работы с датчиком AM2320 будет работать по основной аппаратной шне I2C, так как ей была указана ссылка &Wire
.
#include <Wire.h> // Подключаем библиотеку Wire для работы с аппаратными шинами I2C, до подключения библиотеки iarduino_AM2320. #include <iarduino_AM2320.h> // Подключаем библиотеку iarduino_AM2320 для работы с датчиком влажности и температуры AM2320. iarduino_AM2320 sensor; // Создаём объект sensor для работы с датчиком AM2320, используя функции и методы библиотеки iarduino_AM2320. // void setup(){ // sensor.begin(&Wire); // Инициируем работу с датчиком AM2320, указав ссылку на объект для работы с шиной I2C на которой находится датчик. } // // void loop(){ // sensor.read(); // Читаем показания датчика. float t = sensor.tem; // Получаем температуру. float h = sensor.hum; // Получаем влажность. } //
- Программная шина:
В примере библиотека iarduino_AM2320 для работы с датчиком AM2320 будет работать по программной шне I2C, так как ей была указана ссылка &sWire
.
#include <iarduino_I2C_Software.h> // Подключаем библиотеку для работы с программной шиной I2C, до подключения библиотеки iarduino_AM2320. SoftTwoWire sWire(3,4); // Создаём объект sWire для работы с программной шиной I2C указав выводы которым будет назначена роль линий: SDA, SCL. // #include <iarduino_AM2320.h> // Подключаем библиотеку iarduino_AM2320 для работы с датчиком влажности и температуры AM2320. iarduino_AM2320 sensor; // Создаём объект sensor для работы с датчиком AM2320, используя функции и методы библиотеки iarduino_AM2320. // void setup(){ // sensor.begin(&sWire); // Инициируем работу с датчиком AM2320, указав ссылку на объект для работы с шиной I2C на которой находится датчик. } // // void loop(){ // sensor.read(); // Читаем показания датчика. float t = sensor.tem; // Получаем температуру. float h = sensor.hum; // Получаем влажность. } //
Более подробно о библиотеках iarduino работающих с модулями по шине I2C можно ознакомиться на странице Wiki - расширенные возможности библиотек iarduino для шины I2C.
Описание функций библиотеки:
В данном разделе описаны функции библиотеки iarduino_I2C_Software для создания и работы с программными шинами I2C.
Функции данной библиотеки полностью совместимы с функциями библиотекой Wire для работы с аппаратной шиной I2C в качестве мастера.
Подключение библиотеки:
- Указание выводов при создании объекта:
#include <iarduino_I2C_Software.h> // Подключаем библиотеку для работы с программной шиной I2C. SoftTwoWire sWire(3,4); // Создаём объект sWire, указав выводы: SDA, SCL. // SoftTwoWire sWire1(5,6); // Можно создать несколько объектов, а значит несколько шин.
- Указание выводов после создания объекта:
#include <iarduino_I2C_Software.h> // Подключаем библиотеку для работы с программной шиной I2C. SoftTwoWire sWire; // Создаём объект sWire. // void setup(){ // sWire.setPins(3,4); // Указываем выводы: SDA, SCL. sWire.begin(); // Инициируем работу в качестве мастера. } //
В большинстве случаев целесообразно указывать выводы сразу при создании объекта. Но бывают случаи когда выводы нужно назначить после совершения определённых действий. Например, ИК датчик температуры MLX90614 может работать в режиме I2C, а может выводить ШИМ на линию SDA, для отключения которого требуется подать импульс на вывод SCL длительностью 3 мс, значит назначать выводам роль линий SDA и SCL программной шины I2C целесообразно после проверки режима работы датчика.
Функция begin();
- Назначение: Инициализация работы с программной шиной I2C.
- Синтаксис:
- begin(); // Инициализация в роли ведущего (master).
- begin( АДРЕС ); // Инициализация в роли ведомого (slave).
- Параметры:
- uint8_t АДРЕС - Адрес в роли ведомого на шине I2C.
- Возвращаемое значение: bool - результат инициализации (true или false).
- Примечание:
- Функцию достаточно вызвать однократно, но только если уже указаны выводы шины.
- Библиотека версии 1.0.4 и ниже, не поддерживает роль ведомого.
- Пример:
sWire.begin(); // Инициируем работу программной шины I2C в качестве мастера.
Функция setPins();
- Назначение: Указание выводов программной шины I2C.
- Синтаксис: setPins( SDA , SCL );
- Параметры:
- int SDA - Номер вывода которому будет назначена роль линии SDA на шине I2C.
- int SCL - Номер вывода которому будет назначена роль линии SCL на шине I2C.
- Возвращаемое значение: bool - результат назначения ролей выводам (true или false).
- Примечание:
- Выводы указываются если они не были указаны при создании объекта или после отключения ранее указанных выводов функцией end().
- После указания выводов необходимо вызвать функцию begin().
- Выводы должны поддерживать ввод/вывод логических уровней.
- Выводы A0-A5 Arduino UNO поддерживают ввод/вывод логических уровней, значит их можно использовать на равне с выводами D0-D13.
- Пример:
sWire.setPins(3,4); // Указываем выводы программной шины (3-SDA,4-SCL).
Функция getPins();
- Назначение: Получение указанных ранее выводов программной шины I2C.
- Синтаксис: getPins(&SDA, &SCL);
- Параметры:
- int &SDA - Адрес переменной в которую требуется сохранить номер вывода SDA.
- int &SCL - Адрес переменной в которую требуется сохранить номер вывода SCL.
- Возвращаемое значение: bool - результат записи в переменные (true или false).
- Примечание: Если выводы не указаны или отключены функцией end(), то значения переменных останутся без изменений, а функция вернёт false.
- Пример:
int i=0, j=0; // Объявляем переменные для получения ранее указанных номеров выводов SDA и SCL sWire.getPins(&i,&j); // Получаем номер вывода SDA в переменную i, SCL в переменную j.
Функция end();
- Назначение: Отключение выводов программной шины I2C.
- Синтаксис: end();
- Параметры: Нет.
- Возвращаемое значение: Нет.
- Примечание:
- Отключённые выводы будут сконфигурированы как логические входы.
- Для включения нужно вновь указать выводы setPins(), а потом вызвать begin().
- Пример:
sWire.end(); // Отключаем ранее указанные выводы SDA и SCL.
Функция setClock();
- Назначение: Указание скорости передачи данных.
- Синтаксис: setClock( ЧАСТОТА );
- Параметры:
- uint32_t ЧАСТОТА - Скорость тактирования линии SCL в Гц.
- Возвращаемое значение: Нет.
- Примечание:
- Функцию можно вызывать как до, так и после функции begin().
- За 1 такт SCL передаётся 1 бит SDA, значит 1 бит/с = 1 Гц.
- По умолчанию используется частота 100'000 Гц.
- Библиотека версии 1.0.4 и ниже не использует таймеры и прерывания, а значит реальная частота тактирования линии SCL может немного отличаться от заданной.
- Можно указывать любую частоту от 1 Гц и выше, но реальная частота будет зависеть от производительности микроконтроллера и самого медленного устройства на шине, если оно поддерживает функцию удержания линии SCL.
- Документированные частоты:
- Стандартный режим: 100'000 Гц.
- Быстрый режим: 400'000 Гц.
- Быстрый режим плюс: 1'000'000 Гц.
- Высокоскоростной режим: 1'700'000 и 3'400'000 Гц.
- Сверхбыстрый режим: 5'000'000 Гц.
- Пример:
sWire.setClock(400000); // Перейти на частоту 400 кГц (быстрый режим).
Функция setWireTimeout();
- Назначение: Указание максимального времени ожидания ведомого.
- Синтаксис: setWireTimeout( ВРЕМЯ [ ,СБРОС ] );
- Параметры:
- uint32_t ВРЕМЯ - Максимальное время ожидания ведомого (timeout) в мкс.
- bool СБРОС - Необязательный флаг указывает отключить шину при достижении timeout.
- Возвращаемое значение: Нет.
- Примечание:
- По умолчанию ВРЕМЯ = 25'000 мкс, СБРОС = false.
- Если указать ВРЕМЯ = 0 мкс, то timeout отключён, ждать ведомого пока не ответит.
- Если флаг СБРОС не указан или равен false, то при достижении timeout ожидание ведомого завершится ошибкой и установится флаг сработавшего timeout, который нужно будет сбросить функцией clearWireTimeoutFlag().
- Если указать флаг СБРОС = true, то при достижении timeout, шина будет отключена, как при обращении к функции end() - отключение выводов.
- Пример:
sWire.setWireTimeout(10000); // Установить время ожидания ведомого в 10 мс. sWire.setWireTimeout(0); // Отключить timeout, ждать ведомого пока он не ответит. sWire.setWireTimeout(50000,true); // Ждать ведомого 50 мс, если не ответит отключить шину.
Функция getWireTimeoutFlag();
- Назначение: Получить флаг сработавшего timeout ожидания ведомого.
- Синтаксис: getWireTimeoutFlag();
- Параметры: Нет
- Возвращаемое значение: bool ФЛАГ сработавшего timeout (true или false).
- Примечание:
- Время ожидания ведомого задаётся функцией setWireTimeout().
- Если достигнут timeout ожидания ведомого, то нужно его сбросить clearWireTimeoutFlag().
Функция clearWireTimeoutFlag();
- Назначение: Сбросить флаг сработавшего timeout ожидания ведомого.
- Синтаксис: clearWireTimeoutFlag();
- Параметры: Нет
- Возвращаемое значение: Нет.
- Примечание:
- Проверить состояние флага сработавшего timeout можно функцией getWireTimeoutFlag().
- Функция указания времени setWireTimeout() так же сбрасывает этот флаг.
- Пример:
if( sWire.getWireTimeoutFlag() ){ // Если установлен флаг сработавшего timeout ожидания ведомого sWire.clearWireTimeoutFlag(); // Сбрасываем флаг сработавшего timeout ожидания ведомого } //
Функция beginTransmission();
- Назначение: Инициация передачи данных ведомому с указанием его адреса.
- Синтаксис: beginTransmission( АДРЕС );
- Параметры:
- uint8_t АДРЕС ведомого (от 0x00 до 0x7F).
- Возвращаемое значение: Нет.
- Примечание:
- Функция не начинает передачу данных по шине I2C, а инициирует её, то есть запоминает адрес ведомого и готовит буфер к получению данных для передачи функцией write().
Функция write();
- Назначение: Помещение данных в буфер для передачи.
- Синтаксис:
- write( БАЙТ ); // Помещение в буфер для передачи одного байта.
- write( МАССИВ, КОЛИЧЕСТВО ); // Помещение в буфер нескольких байт из массива.
- Параметры:
- uint8_t БАЙТ для помещения в буфер для передачи.
- uint8_t МАССИВ байтов для помещения в буфер для передачи.
- size_t КОЛИЧЕСТВО байт указанного массива для помещения в буфер для передачи.
- Возвращаемое значение: size_t Количество реально помещённых байт в буфер для передачи.
- Примечание:
- Функция не передаёт данные по шине I2C, а помещает их в буфер для передачи.
- Размер буфера определён идентификатором SOFT_I2C_BUFFER_LENGTH = 32 байта. Его можно изменить в начале файла iarduino_I2C_Software.h
- Функция возвращает не общее количество байт в буфере, а количество байт помещённых в буфер текущим обращением к данной функции.
Функция endTransmission();
- Назначение: Выполнение инициированной ранее передачи данных из буфера ведомому.
- Синтаксис: endTransmission( [СТОП] );
- Параметры:
- bool СТОП - Необязательный флаг указывает установить сигнал Stop после передачи.
- Возвращаемое значение: uint8_t РЕЗУЛЬТАТ передачи данных ведомому.
- 0 - Передача успешно завершена.
- 1 - Переполнен буфер для передачи.
- 2 - Получен NACK при передаче адреса (ведомый отсутствует).
- 3 - Получен NACK при передаче данных (ошибка ведомого, помехи на шине и т.д.).
- 4 - Другая ошибка.
- 5 - Превышен timeout ожидания ведомого (ведомый не отвечает).
- Примечание:
- Если флаг СТОП не указан или равен true, то после завершения передачи данных на шине I2C будет установлен сигнал Stop (освобождение шины).
- Если флаг СТОП равен false, то после завершения передачи данных шина останется занята мастером. Значит сигнал Start отправленный в новом пакете данных по шине I2C будет расценен ведомыми как сигнал ReStart.
- Пример:
uint8_t i[] = {1,2,3}; // Создаём массив для передачи данных ведомому. sWire.beginTransmission(0x09); // Инициируем передачу данных ведомому с адресом 0x09. sWire.write(5); // Помещаем в буфер для передачи один байт = 5. sWire.write(i, 3); // Помещаем в буфер для передачи 3 байта из массива i. sWire.endTransmission(); // Выполняем инициированную ранее передачу данных.
Функция requestFrom();
- Назначение: Чтение указанного количества байт ведомого в буфер.
- Синтаксис: requestFrom( АДРЕС , КОЛИЧЕСТВО [, СТОП ] );
- Параметры:
- uint8_t АДРЕС ведомого (от 0x00 до 0x7F).
- uint8_t КОЛИЧЕСТВО читаемых байт ведомого в буфер.
- bool СТОП - Необязательный флаг указывает установить сигнал Stop после чтения.
- Возвращаемое значение: uint8_t - Количество прочитанных байт по шине I2C.
- Примечание:
- Функция выполняет чтение указанного количества байт ведомого по шине I2C в буфер. Количество байт в буфере можно узнать функцией available(), а прочитать данные можно функциями read() или peek().
- Если флаг СТОП не указан или равен true, то после завершения чтения данных на шине I2C будет установлен сигнал Stop (освобождение шины).
- Если флаг СТОП равен false, то после завершения чтения данных шина останется занята мастером. Значит сигнал Start отправленный в новом пакете данных по шине I2C будет расценен ведомыми как сигнал ReStart.
- Размер буфера определён идентификатором SOFT_I2C_BUFFER_LENGTH = 32 байта. Его можно изменить в начале файла iarduino_I2C_Software.h
Функция available();
- Назначение: Возвращает количество байт, доступных для чтения из буфера.
- Синтаксис: available();
- Параметры: Нет.
- Возвращаемое значение: int - Количество байт в буфере для чтения.
Функция read();
- Назначение: Возвращает очередной байт из буфера для чтения.
- Синтаксис: read();
- Параметры: Нет.
- Возвращаемое значение: int - байт.
- Примечание:
- Данные читаются в буфер по шине I2C функцией requestFrom(), а читаются из буфера функцией rear() по принципу «первым пришёл - первым ушёл» (FIFO) first in, first out.
- Функция read() читает 1 байт не по шине I2C, а из буфера уже прочитанных данных.
- Каждый прочитанный байт функцией read() удаляется из буфера.
- Пример:
sWire.requestFrom(0x09, 3); // Читаем 3 байта ведомого с адресом 0x09. while( sWire.available() ){ // Если в буфере остались данные... int i = sWire.read(); // Читаем очередной байт из буфера. Serial.println( i ); // Выводим прочитанный байт. } //
Функция peek();
- Назначение: Возвращает очередной байт из буфера для чтения.
- Синтаксис: peek();
- Параметры: Нет.
- Возвращаемое значение: int - байт.
- Примечание: В отличии от rear(), функция peek() не удаляет байт из буфера.
- Пример:
if( sWire.peek()<10 ){ Serial.print( 0 ); } // Если число в буфере меньше 10, то выводим ведущий 0. Serial.println( sWire.read() ); // Выводим то же число, что ранее сравнивали с 10.
Функция flush();
- Синтаксис: flush();
- Параметры: Нет.
- Возвращаемое значение: Нет.
- Примечание: Библиотека версии 1.0.4 и ниже, не поддерживает эту функцию.
- Пример:
sWire.flush();
Функция onReceive();
- Назначение: Указание функции обработки полученных данных от мастера.
- Синтаксис: onReceive( ФУНКЦИЯ );
- Параметры:
- void (*)(int) ФУНКЦИЯ - Имя функции обработки полученных данных от мастера.
- Возвращаемое значение: Нет.
- Примечание:
- Функция предназначена для ведомого устройства.
- Функция указывает на функцию обработки полученных данных от мастера.
- Указанная функция (обработчик) будет вызываться каждый раз после завершения приема данных от мастера.
- Функция обработки полученных данных от мастера должна принимать в качестве единственного параметра типа int - Количество принятых байт данных от мастера.
- Библиотека версии 1.0.4 и ниже, не поддерживает эту функцию.
- Пример:
void fnc(int sum){ // sum - количество принятых байт от мастера. for(int i=0; i<sum; i++){ // Проходим по всем принятым от мастера байтам... int j = sWire.read(); // Читаем очередной байт из буфера. ... // Выполняем требуемые действия с байтом. } // } // sWire.onReceive( fnc ); // Указываем функцию обработки.
Функция onRequest();
- Назначение: Указание функции обработки получения запроса от мастера.
- Синтаксис: onRequest( ФУНКЦИЯ );
- Параметры:
- void (*)(void) ФУНКЦИЯ - Имя функции обработки получения запроса от мастера.
- Возвращаемое значение: Нет.
- Примечание:
- Функция предназначена для ведомого устройства.
- Функция указывает на функцию обработки получения запроса от мастера.
- Указанная функция (обработчик) будет вызываться каждый раз когда мастер запрашивает чтение очередного байта от ведомого.
- Библиотека версии 1.0.4 и ниже, не поддерживает эту функцию.
- Пример:
void fnc(void){ // sWire.write( i ); // Помещаем в буфер для передачи мастеру один байт i. } // sWire.onRequest( fnc ); // Указываем функцию обработки запроса от мастера.
Обсуждение