Поиск адреса OLED с использованием связи I2C и Arduino

arduino-uno oled ssd1306

Известно, что адрес OLED SSD1306 — 3C. Формат кадра следующий:

Из рисунка следует, что двоичный шаблон должен быть 01111000 для первого кадра (учитывая режим записи и предпоследний бит не имеет значения).
Итак, я пытался отправить первый кадр с помощью библиотеки Wire.h. Ниже приведен код Wire.beginTransmission(0b01111001); Но я получаю ответ (возвращаемое значение 2)

Однако, если я отправлю 00111100, я получу подтверждение (возвращаемое значение 0). Что не так в моей интерпретации?

, 👍0

Обсуждение

Вы должны просканировать шину, возможно, дисплей имеет другой адрес. Вы можете использовать этот скетч: https://playground.arduino.cc/Main/I2cScanner/, @Sim Son

Я ссылался на эту ссылку. Он показывает адрес 3c, но это не должно быть так, потому что на приведенном выше рисунке показана таблица данных ssd1306., @shivamag00


2 ответа


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

0

Вы неправильно понимаете, как используется библиотека Wire. Хотя первый байт в передаче называется байтом адреса, фактический адрес состоит только из 7 старших битов этого байта. Бит направления отсутствует в адресе.

Поэтому методу Wire.beginTransmission() нужен адрес в качестве параметра без бита направления. Этот бит устанавливается в соответствии с используемой функцией (0 для Wire.beginTransmission() и 1 для Wire.requestFrom()).

0b0111100 — это реальный адрес (при подключении контакта адреса к земле) (обратите внимание, что всего 7 бит, так как адрес имеет только 7 бит). Тогда байт адреса операции записи будет 0b01111000, хотя библиотека скрывает это от вас. Вам нужно предоставить 7-битный адрес функции.

последний бит не имеет значения

Как упоминалось выше, это неверно. Этот бит (самый младший бит адреса) устанавливается выводом адреса SA0. Похоже, что он у вас привязан к земле, которая устанавливает соответствующий бит в адресе в ноль. Если бы вы привязали его к Vcc, это было бы 1.

,

Я понимаю, где ошибся. Спасибо. Однако у меня есть еще один вопрос. Как отправить бит чтения/записи??, @shivamag00

@shivamag000, как писал Крисл, вы не отправляете его вручную. Бит чтения/записи автоматически обрабатывается функциями Wire.startTransmission() (очищает бит для обращения к ведомому устройству в режиме записи) и Wire.requestFrom() (устанавливает бит для обращения к ведомому устройству в режиме чтения). Важно использовать только 7-битный адрес, предпочтительно в формате, отличном от двоичного, что может немного сбивать с толку., @Sim Son

Да, бит направления данных обрабатывается библиотекой. Когда вы используете функции записи (Wire.beginTransmission() и Wire.endTransmission()), для бита направления будет использоваться ноль. Если вы используете функцию чтения Wire.requestFrom(), она будет использовать 1 для бита направления., @chrisl

Также имейте в виду, что фактическая передача выполняется в Wire.endTransmission(). До этого никакие данные передаваться не будут., @chrisl

Спасибо @chrisl, @shivamag00


0

I2C имеет 7-битное адресное пространство. Фактический адрес устройства: 0b0111100 (=0x3c). Последовательности 0b01111001 и 0b01111000 адресуют одно и то же ведомое устройство, при этом первая (младшим битом является 1) начинает передачу чтения, вторая начинает передача записи.

Младшие значащие биты вам не нужны при использовании Wire.h: режим работы устанавливается автоматически при использовании Wire.startTransmission(addr) ( возвращает 0, когда подчиненное устройство ACK подтвердит команду записи) и Wire.requestFrom(addr) (возвращает 0, когда подчиненное устройство подтвердит команду чтения).

,

Даже если я отправлю `0b01111000`, nack будет получен, @shivamag00

@shivamag000 это не то, что вы написали в своем вопросе («Однако, если я отправлю 00111100, я получу подтверждение»), и возвращаемое значение 0 означает, что ведомое устройство получило ACK, @Sim Son

@shivamag000 также, 0b01111000 - это не то, что вы должны передавать в Wire.beginTransmission(). Он принимает **7**-битный адрес. Вам лучше не связываться с двоичным форматом, просто выполните Wire.beginTransmission(0x3c)..., @Sim Son

не могли бы вы показать ссылку, где говорится, что wire.begin принимает семибитные адреса, @shivamag00

@shivamag000 https://www.arduino.cc/en/Reference/WireBeginTransmission, @Sim Son

Спасибо @Sim сын, @shivamag00