// sketch_07_01_I2C_TEA5767
#include
void setup()
{
Wire.begin();
setFrequency(93.0); // МГц
}
void loop()
{
}
void setFrequency(float frequency)
{
unsigned int frequencyB = 4 * (frequency * 1000000 + 225000) / 32768;
byte frequencyH = frequencyB >> 8;
byte frequencyL = frequencyB & 0XFF;
Wire.beginTransmission(0x60);
Wire.write(frequencyH);
Wire.write(frequencyL);
Wire.write(0xB0);
Wire.write(0x10);
Wire.write(0x00);
Wire.endTransmission();
delay(100);
}
Весь код, представляющий для нас интерес в этом примере, находится в функции setFrequency. Она принимает вещественное число — частоту в мегагерцах. То есть, если вы пожелаете собрать и опробовать этот проект, узнайте частоту, на которой вещает местная радиостанция с хорошим сильным сигналом, и вставьте ее значение в вызов setFrequency в функции setup.
Чтобы преобразовать вещественное значение частоты в двухбайтное представление, которое можно послать в составе пятибайтного сообщения, нужно выполнить некоторые арифметические операции. Эти операции выполняет следующий фрагмент:
unsigned int frequencyB = 4 * (frequency * 1000000 + 225000) / 32768;
byte frequencyH = frequencyB >> 8;
byte frequencyL = frequencyB & 0XFF;
Команда >> сдвигает биты вправо, то есть операция >> 8 сдвинет старшие 8 бит в сторону младших на 8 двоичных разрядов. Оператор & выполняет поразрядную операцию И (AND), которая в данном случае сбросит старшие 8 бит и оставит только младшие. Более полное обсуждение операций с битами вы найдете в главе 9.
Остальной код в функции setFrequency инициализирует передачу сообщения I2C ведомому устройству с адресом 0x60, который закреплен за приемником TEA5767. Затем осуществляется последовательная передача 5 байт, начиная с 2 байт частоты.
Прочитав документацию, вы узнаете о множестве других возможностей, доступных посредством разных сообщений, например о сканировании диапазона, выключении одного или двух каналов вывода звука и выборе режима моно/стерео.
В приложении мы еще вернемся к этому примеру и создадим библиотеку для Arduino, чтобы упростить работу с модулем TEA5767.
Взаимодействие между двумя платами Arduino
Во втором примере используются две платы Arduino, одна действует как ведущее устройство I2C, а другая — как ведомое. Ведущее устройство будет посылать сообщения ведомому, которое, в свою очередь, будет выводить их в монитор последовательного порта, чтобы можно было наглядно убедиться, что схема работает.
Схема соединения плат для этого примера показана на рис. 7.6. Обратите внимание на то, что модуль TEA5767 имеет встроенные подтягивающие сопротивления на линиях I2C. Однако в данном случае, когда друг к другу подключаются две платы Arduinos, такие резисторы отсутствуют, поэтому понадобится включить свои сопротивления с номиналом 4,7 кОм (рис. 7.6).

Рис. 7.6.Соединение двух плат Arduino через интерфейс I2C
В платы должны быть загружены разные скетчи. Оба скетча включены в состав примеров для библиотеки Wire. Программа для ведущей платы Arduino находится в меню File—>Example—>Wire—>master_writer (Файл—> Примеры—>Wire—>master_writer), а для ведомой платы — в меню File—> Example—>Wire—>slave_receiver (Файл—>Примеры—>Wire—>slave_receiver).
Запрограммировав обе платы, оставьте ведомую подключенной к компьютеру, чтобы увидеть вывод с этой платы в монитор последовательного порта и обеспечить питание ведущей платы Arduino.
Начнем со скетча в ведущей плате:
#include
void setup() {
Wire.begin(); // подключиться к шине i2c (для ведущего устройства
// адрес не указывается)
}
byte x = 0;
void loop() {
Wire.beginTransmission(4); // инициализировать передачу устройству #4
Wire.write("x is "); // послать 5 байт
Wire.write(x); // послать 1 байт
Wire.endTransmission(); // остановить передачу
x++;
delay(500);
}
Этот скетч генерирует сообщение вида x is 1, где 1 — число, увеличивающееся каждые полсекунды. Затем сообщение посылается ведомому устройству с адресом 4, как определено в вызове beginTransmission.
Задача ведомого скетча — принять сообщение от ведущего устройства и вывести его в монитор последовательного порта:
#include
void setup() {
Wire.begin(4); // подключиться к шине i2c с адресом #4
Wire.onReceive(receiveEvent); // зарегистрировать обработчик события
Serial.begin(9600); // открыть монитор последовательного порта
}
void loop() {
delay(100);
}
// эта функция вызывается всякий раз, когда со стороны ведущего устройства
// поступают очередные данные, эта функция зарегистрирована как обработчик
// события, см. setup()
void receiveEvent(int howMany) {
while (1 < Wire.available()) { // цикл по всем принятым байтам, кроме
Читать дальше