Как отправлять данные через I2C без проводной библиотеки?

У меня есть следующий цифровой потенциометр: DS1803-100, которым, согласно спецификации, можно управлять с помощью двухпроводного последовательного интерфейса. Мне удалось заставить его работать с помощью провода, однако я не могу заставить его работать, используя только digitalWrite (ссылка на код). Кто-нибудь может сказать мне, почему? Для справки, 0x50-это бит адреса + r/!w, 0xA9-это команда (запись в pot 0 в моем случае), а следующий 0xA9-это значение для записи. Я знаю, что с кодом что-то не так, но не могу понять, что именно. Заранее благодарю вас!

EDIT: Вот код

int PIN_SCK = 12;
int PIN_SDA = 11;

const int delayvalue = 10;

void setup(){
    digitalWrite(PIN_SCK, 1); // I can first declare the state
    digitalWrite(PIN_SDA, 1);
    pinMode(PIN_SCK, OUTPUT); // then turn them on
    pinMode(PIN_SDA, OUTPUT);

    delay(1000);

    digitalWrite(PIN_SDA, 0); // start bit

    shift_out(PIN_SDA, PIN_SCK, 0x50);
    shift_out(PIN_SDA, PIN_SCK, 0xA9);
    shift_out(PIN_SDA, PIN_SCK, 0xA9);

    digitalWrite(PIN_SDA, 1); // stop bit

}

void loop(){

}
// uint8_t is the same as 8 bits aka one byte
void shift_out(uint8_t datapin, uint8_t clockpin, uint8_t val){
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        digitalWrite(datapin, !!(val & (1 << (7 - i))));
        delay(1);
        digitalWrite(clockpin, 0);
        delay(delayvalue);
        digitalWrite(clockpin, 1);
        delay(delayvalue);
    }

    digitalWrite(datapin, 0); // to enable stop bit
    delay(100); // wait fro aknowledgement

}

, 👍2

Обсуждение

Что это за код? Не стесняйтесь размещать код здесь., @Nick Gammon

Хорошо, отредактировал код., @Calin


2 ответа


Лучший ответ:

4

Ну, короткий ответ: это был бит подтверждения, я забыл отправить тактовый импульс, чтобы получить его (да! мое устройство генерирует часы для подключенного потенциометра, я ждал, пока устройство "пошлет" мне бит, мне нужно было "запросить" бит на восходящем фронте часов).

Длинный ответ: сейчас код выглядит так:

int PIN_SCK = 12;
int PIN_SDA = 11;

const int delayvalue = 10;

void setup(){
    digitalWrite(PIN_SCK, 1); // Я могу сначала объявить состояние
    digitalWrite(PIN_SDA, 1);
    pinMode(PIN_SCK, OUTPUT); // затем включите их
    pinMode(PIN_SDA, OUTPUT);

    delay(1000);

    digitalWrite(PIN_SDA, 0); // start bit
    delay(10);
    digitalWrite(PIN_SCK, 0);
    delay(10);

    shift_out(PIN_SDA, PIN_SCK, 0x50);
    shift_out(PIN_SDA, PIN_SCK, 0xA9);
    shift_out(PIN_SDA, PIN_SCK, 0xA9);

    digitalWrite(PIN_SDA, 1); // stop bit

}

void loop(){

}
// uint8_t-это то же самое, что 8 бит aka one byte
void shift_out(uint8_t datapin, uint8_t clockpin, uint8_t val){
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        digitalWrite(datapin, !!(val & (1 << (7 - i))));
        delay(1);
        digitalWrite(clockpin, 1);
        delay(delayvalue);
        digitalWrite(clockpin, 0);
        delay(delayvalue);
    }

    digitalWrite(datapin, 0); // to enable stop bit
    delay(10);

    // Здесь я обрабатываю сигнал AKNOWLEDGE, который происходит после
    // каждый отправленный байт. Будь то адрес, команда или значение
    digitalWrite(clockpin, 1);
    delay(10);
    digitalWrite(clockpin, 0);
    delay(10);

}

Таким образом, в основном я следовал и точно воспроизводил сигналы на этой временной диаграмме с одним небольшим исключением: я не генерировал восходящее ребро, когда ожидал бит подтверждения (в основном диаграмма, но с SCK, равным 0 прямо под битами подтверждения).

Надеюсь, это кому-нибудь поможет!

,

1

I2C намного сложнее, чем просто смещение байтов.

См.: I2C - Двухпроводный периферийный интерфейс - для Arduino

Ваш код, похоже, не принимает ничего из этого во внимание.

Почему вы не хотите использовать проводную библиотеку? Аппаратное обеспечение на чипе (какой чип у вас есть?) поддерживает его. Зачем игнорировать это и пытаться сделать это самостоятельно?

,

У меня нет проблем с использованием библиотеки wire, однако мне было интересно, почему этот код не работал в первую очередь, так как, по моему мнению, он должен был работать. И да, я уже закончил тем, что использовал провод на своем Arduino Pro Mini. Спасибо за информацию! :), @Calin

Мне действительно любопытно, что я сделал не так в своем коде. Разве я не принял во внимание бит подтверждения, я просто подождал 100 мс, пока подчиненный отправит этот бит, и продолжил, или что я сделал?, @Calin

Ну, мне удалось заставить его работать, я опубликую ответ немного позже., @Calin