Библиотека Wire для Arduino для работы с шиной I2C

Добавлено 11 октября 2017 в 19:45

Описание библиотеки Wire

Данная библиотека позволяет вам взаимодействовать с I2C / TWI устройствами. На платах Arduino с компоновкой R3 (распиновка 1.0) SDA (линия данных) и SCL (линия тактового сигнала) находятся на выводах около вывода AREF. Arduino Due имеет два I2C / TWI интерфейса: SDA1 и SCL1 находятся около вывода AREF, а дополнительные линии находятся на выводах 20 и 21.

В таблице ниже показано, где расположены TWI выводы на разных платах Arduino.

Расположение выводов I2C/TWI на платах Arduino
ПлатаI2C/TWI выводы
Uno, EthernetA4 (SDA), A5 (SCL)
Mega256020 (SDA), 21 (SCL)
Leonardo2 (SDA), 3 (SCL)
Due20 (SDA), 21 (SCL), SDA1, SCL1

Начиная с Arduino 1.0, данная библиотека наследует функции Stream, что делает ее совместимой с другими библиотеками чтения/записи. Из-за этого send() и receive() были заменены на read() и write().

Примечание

Существуют 7- и 8-битные версии адресов I2C. 7 битов идентифицируют устройство, а восьмой бит определяет, идет запись или чтение. Библиотека Wire использует 7 битные адреса. Если у вас есть техническое описание или пример кода, где используется 8-битный адрес, вам нужно откинуть младший бит (т.е. сдвинуть значение на один бит вправо), получив адрес от 0 до 127. Однако адреса от 0 до 7 не используются, так как зарезервированы, поэтому первым адресом, который может быть использован, является 8. Обратите внимание, что при подключении выводов SDA/SCL необходимы подтягивающие резисторы. Для более подробной информации смотрите примеры. На плате MEGA 2560 есть подтягивающие резисторы на выводах 20 и 21.

Описание методов

Wire.begin()

Описание

Инициализирует библиотеку Wire и подключается к шине I2C как ведущий (мастер) или ведомый. Как правило, должен вызываться только один раз.

Синтаксис

Wire.begin()

Wire.begin(address)

Параметры

address: 7-битный адрес ведомого устройства (необязательно); если не задан, плата подключается к шине как мастер.

Возвращаемое значение

Нет.

Пример

Примеры для ведомого устройства смотрите в примерах к методам onReceive() и onRequest(). Примеры для ведущего устройства смотрите в примерах к остальным методам. .

Wire.requestFrom()

Описание

Используется мастером для запроса байтов от ведомого устройства. Эти байты могут быть получены с помощью методов available() и read().

Для совместимости с определенными I2C устройствами, начиная с Arduino 1.0.1, requestFrom() принимает аргумент логического типа данных, меняющий его поведение.

Если этот аргумент равен true, то requestFrom() после запроса посылает сообщение STOP, освобождая шину I2C.

Если этот аргумент равен false, то requestFrom() после запроса посылает сообщение RESTART. Шина не освобождается, что мешает другому устройству-мастеру влезть между сообщениями. Это позволяет одному ведущему устройству посылать несколько запросов, пока оно контролирует шину.

По умолчанию этот аргумент равен true.

Синтаксис

Wire.requestFrom(address, quantity)

Wire.requestFrom(address, quantity, stop)

Параметры
  • address: 7-битный адрес устройства, у которого запрашиваются байты;
  • quantity: количество запрашиваемых байтов;
  • stop : boolean. true посылает сообщение STOP после запроса. false посылает сообщение RESTART после запроса, сохраняя соединение активным.
Возвращаемое значение

byte: количество байтов, возвращенных от ведомого устройства.

Пример

Смотрите пример к методу read().

Wire.beginTransmission()

Описание

Начинает передачу на ведомое I2C устройство с заданным адресом. После него последовательность байтов для передачи ставится в очередь с помощью функции write(), и их передача с помощью вызова endTransmission().

Синтаксис

Wire.beginTransmission(address)

Параметры

address: 7-битный адрес устройства, на которое необходимо передать данные.

Возвращаемое значение

Нет.

Пример

Смотрите пример к методу write().

Wire.endTransmission()

Описание

Завершает передачу на ведомое устройство, которая была начата методом beginTransmission() и передает байты, которые были поставлены в очередь методом write().

Для совместимости с определенными I2C устройствами, начиная с Arduino 1.0.1, requestFrom() принимает аргумент логического типа данных, меняющий его поведение.

Если этот аргумент равен true, то requestFrom() после передачи посылает сообщение STOP, освобождая шину I2C.

Если этот аргумент равен false, то requestFrom() после передачи посылает сообщение RESTART. Шина не освобождается, что мешает другому устройству-мастеру влезть между сообщениями. Это позволяет одному ведущему устройству посылать несколько передач, пока оно контролирует шину.

По умолчанию этот аргумент равен true.

Синтаксис

Wire.endTransmission()

Wire.endTransmission(stop)

Параметры

stop : boolean. true посылает сообщение STOP после передачи. false посылает сообщение RESTART после передачи, сохраняя соединение активным.

Возвращаемое значение

byte, который указывает на состояние передачи:

  • 0: успех;
  • 1: данные слишком длинны для заполнения буфера передачи;
  • 2: принят NACK при передаче адреса;
  • 3: принят NACK при передаче данных;
  • 4: остальные ошибки.
Пример

Смотрите пример к методу write().

Wire.write()

Описание

Записывает данные от ведомого устройства в отклик на запрос от ведущего устройства, или ставит в очередь байты для передачи от мастера к ведомому устройству (между вызовами beginTransmission() и endTransmission()).

Синтаксис

Wire.write(value)

Wire.write(string)

Wire.write(data, length)

Параметры
  • value: значение для передачи, один байт.
  • string: строка для передачи, последовательность байтов.
  • data: массив данных для передачи, байты.
  • length: количество байтов для передачи.
Возвращаемое значение

byte: write() возвращает количество записанных байтов, хотя чтение этого количества не обязательно.

Пример
#include <Wire.h>

byte val = 0;

void setup()
{
  Wire.begin(); // подключиться к шине i2c
}

void loop()
{
  Wire.beginTransmission(44); // передача на устройство #44 (0x2c)
                              // адрес устройства задан в техническом описании
  Wire.write(val);            // отправить байт значения  
  Wire.endTransmission();     // остановить передачу

  val++;        // увеличить значение
  if(val == 64) // если дошли до 64-го значения (max)
  {
    val = 0;    // начать с начала
  }
  delay(500);
}

Wire.available()

Описание

Возвращает количество байтов, доступных для получения с помощью read(). Этот метод должен вызываться на ведущем устройстве после вызова requestFrom() или на ведомом устройстве внутри обработчика onReceive().

Синтаксис

Wire.available()

Параметры

Нет.

Возвращаемое значение

Количество байтов, доступных для чтения.

Пример

Смотрите пример к методу read().

Wire.read()

Описание

Считывает байт, который был передан от ведомого устройства к ведущему после вызова requestFrom(), или который был передан от ведущего устройства к ведомому.

Синтаксис

Wire.read()

Параметры

Нет.

Возвращаемое значение

byte: очередной принятый байт.

Пример
#include <Wire.h>

byte val = 0;

void setup()
{
  Wire.begin();        // подключиться к шине i2c (адрес для мастера не обязателен)
  Serial.begin(9600);  // настроить последовательный порт для вывода
}

void loop()
{
  Wire.requestFrom(2, 6);    // запросить 6 байтов от ведомого устройства #2

  while(Wire.available())    // ведомое устройство может послать меньше, чем запрошено
  { 
    char c = Wire.read();    // принять байт как символ
    Serial.print(c);         // напечатать символ
  }

  delay(500);
}

Wire.setClock()

Описание

Изменяет тактовую частоту для связи по шине I2C. У ведомых I2C устройств нет минимальной рабочей тактовой частоты, однако обычно используется 100 кГц.

Синтаксис

Wire.setClock(clockFrequency)

Параметры

clockFrequency: значение частоты (в герцах) тактового сигнала. Принимаются значения 100000 (стандартный режим) и 400000 (быстрый режим). Некоторые процессоры также поддерживают 10000 (низкоскоростной режим), 1000000 (быстрый режим плюс) и 3400000 (высокоскоростной режим). Чтобы убедиться, что необходимый режим поддерживается, обращайтесь к технической документации на конкретный процессор.

Возвращаемое значение

Нет

Wire.onReceive()

Описание

Регистрирует функцию, которая будет вызываться, когда ведомое устройство принимает передачу от мастера.

Синтаксис

Wire.onReceive(handler)

Параметры

handler: функция, которая должна будет вызываться, когда ведомое устройство принимает данные; она должна принимать один параметр int (количество байтов, прочитанных от мастера) и ничего не возвращать, т.е.:

void myHandler(int numBytes)

Возвращаемое значение

Нет.

Пример

Код для платы Arduino, работающей в качестве ведомого устройства:

#include <Wire.h>

void setup() 
{
  Wire.begin(8);                // подключиться к i2c шине с адресом #8
  Wire.onReceive(receiveEvent); // зарегистрировать обработчик события
  Serial.begin(9600);           // настроить последовательный порт для вывода
}

void loop() 
{
  delay(100);
}

//   функция, которая будет выполняться всякий раз, когда от мастера принимаются данные
//   данная функция регистрируется как обработчик события, смотрите setup()
void receiveEvent(int howMany) 
{
  while (1 < Wire.available()) // пройтись по всем до последнего
  { 
    char c = Wire.read();    // принять байт как символ
    Serial.print(c);         // напечатать символ
  }
  int x = Wire.read();    // принять байт как целое число
  Serial.println(x);      // напечатать число
}

Wire.onRequest()

Описание

Регистрирует функцию, которая будет вызываться, когда мастер запрашивает данные от ведомого устройства.

Синтаксис

Wire.onRequest(handler)

Параметры

handler: функция, которая должна будет вызываться, она не принимает параметров и ничего не возвращает, т.е.:

void myHandler()

Возвращаемое значение

Нет.

Пример

Код для платы Arduino, работающей в качестве ведомого устройства:

#include <Wire.h>

void setup() 
{
  Wire.begin(8);                // подключиться к i2c шине с адресом #8
  Wire.onRequest(requestEvent); // зарегистрировать обработчик события
}

void loop() 
{
  delay(100);
}

//   функция, которая будет выполняться всякий раз, когда мастером будут
// запрошены данные
//   данная функция регистрируется как обработчик события, смотрите setup()
void requestEvent() 
{
  Wire.write("hello "); // ответить сообщением
}

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.


Сообщить об ошибке