Работа с I2C в библиотеке Wire
- Войдите на сайт для отправки комментариев
Всех приветствую!
Потратил несколько часов на поиск и чтение по теме, но так и не могу прояснить для себя, как же работать по шине I2C? Может мне кто-нибудь подскажет некоторые моменты? Буду конкретен:
1. Устройство имеет адрес 0х21. Соответственно для записи адрес 0х42 для записи и 0х43 для чтения. Какие же адреса указывать в Wire.RequestFrom и Wire.Begintransmission?
2. Устройство имеет адрес 0х21, но кроме того имеет внутренний регистр с адресом 0х01, в который я хочу записать байт 0х5а. Как будет выглядеть код?
3. Устройство имеет адрес 0х21, но кроме того имеет внутренний регистр с адресом 0х01, из которого я хочу прочитать байт. Как будет выглядеть код?
4. Таки надо подтягивающие резисторы на шину ставить,или они уже есть в МК?
Спасибо за помощь в виде ссылки или просто куска кода.
В мк не те резисторы что для i2c. И в зависимости от ардуино они либо уже есть на плате либо нет.
Хорошо, т.е. использовать внутренние резисторы МК, если только он на шине мастер все же возможно? Или полюбому ставить внешние? Если важна конкретика- то платформа Due.
У due 2 шины для i2c. На одной уже стоят резисторы, а на другую их НУЖНО установить.
Обычно ставят внешние, и часто - на плате с датчиком
А по I2C - возьмите библиотеку для какого-нибудь датчика, да посмотрите, как с ним работают
А по I2C - возьмите библиотеку для какого-нибудь датчика, да посмотрите, как с ним работают
Так вот и не могу найти. Народ подключает датчики температуры и LCD, пишутся библиотеки целые и собственные реализации I2C, но туда лезть- темный лес совсем. Мне просто не понятен(исходя из референса к библиотеке) алгоритм обмена данными с устройством в случае наличия у него своих внутренних регистров.
Насколько я понимаю по даташиту "Both TWD and TWCK are bidirectional lines, connected to a positive supply voltage via a current source or pull-up resistor (see Figure 34-2 on page 715). When the bus is free, both lines are high. The output stages of devices connected to the bus must have an open-drain or open-collector to perform the wired-AND function.TWD and TWCK pins may be multiplexed with PIO lines. To enable the TWI, the programmermust perform the following step:
На одной шине они есть снаружи припаяны на ардуиновскрй плате , а на второй их нет и нужно их туда подпаять.
Да, увидел на схеме, что линии SDA SCL подтянуты на 3,3В, спасибо. Т.е. на них можно подключать напрямую. Все, п.4 закрыт :)
Чтобы не напрягать особенно народ, приведу кусок кода обмена по интерфейсу:
#include <Wire.h> String inputString = "20"; // a string to hold incoming data boolean stringComplete = false; // whether the string is complete int pos = 0; void setup() { Wire.begin(); // join i2c bus (address optional for master) Serial.begin(9600); // start serial for output inputString.reserve(3); } void loop() { if (stringComplete) { pos = inputString.toInt(); Wire.beginTransmission(0x21); Wire.write(pos); delay(100); Wire.requestFrom(0x21, 1); // request 6 bytes from slave device # while(Wire.available()) // slave may send less than requested { char c = Wire.read(); // receive a byte as character Serial.println(c, HEX); // print the character } Wire.endTransmission(); inputString = ""; stringComplete = false; } delay(500); } // For DEBUGGING void serialEvent() { while (Serial.available()) { // get the new byte: char inChar = (char)Serial.read(); // add it to the inputString: inputString += inChar; // if the incoming character is a newline, set a flag // so the main loop can do something about it: if (inChar == '\n') { stringComplete = true; } } }Проблема в том, что значение из нужного регистра отображаются только со второго раза( нужно ввести дважды номер регистра, чтобы получить его значение. Вопрос простой: что не так?
Мне просто не понятен(исходя из референса к библиотеке) алгоритм обмена данными с устройством в случае наличия у него своих внутренних регистров.
Ну вот, например, запись в регистр ds3231:
void RTC_DS3231::setreg(const uint8_t addr, const uint8_t val) { Wire.beginTransmission(DS3231_ADDRESS); Wire.write(addr); // адрес регистра Wire.write(val); // значение Wire.endTransmission();}Спасибо, с записью стало понятно.
Так же разобрался с чтением:
Wire.beginTransmission(0x21); //начинаем работу с шиной Wire.write(pos); // сообщаем ведомому, какой регистр будем читать Wire.endTransmission(); //это обязательно! Wire.beginTransmission(0x21); // начинаем заново работу с шиной Wire.requestFrom(0x21, 1); // требуем 1 байт от устройства из регистра с номером pos char c = Wire.read(); // receive a byte as character Serial.println(c, HEX); // print the character // } Wire.endTransmission(); // оканчиваем работу с шинойВсем спасибо, все работает!