Поиск адреса OLED с использованием связи I2C и Arduino
Известно, что адрес OLED SSD1306 — 3C. Формат кадра следующий:
Из рисунка следует, что двоичный шаблон должен быть 01111000 для первого кадра (учитывая режим записи и предпоследний бит не имеет значения).
Итак, я пытался отправить первый кадр с помощью библиотеки Wire.h. Ниже приведен код
Wire.beginTransmission(0b01111001);
Но я получаю ответ (возвращаемое значение 2)
Однако, если я отправлю 00111100, я получу подтверждение (возвращаемое значение 0). Что не так в моей интерпретации?
@shivamag00, 👍0
Обсуждение2 ответа
Лучший ответ:
Вы неправильно понимаете, как используется библиотека 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
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
- OLED 'SH1106_WHITE' was not declared in this scope
- Сообщение об ошибке при попытке настроить библиотеку U8g2
- Проблема с настройкой i2c OLED wemos D1 mini shiled (64*24)
- Разница в распиновке (типы?) Uno/Mega
- Как ssd1306 справляется с разными размерами экрана?
- SSD1306 показывает статику, когда я пытаюсь отобразить изображение XBM
- Проблема с Arduino:Adafruit_SSD1306_128x64_i2c_init(); was not declared in the scope
- DHT20 и дисплей Oled не работают вместе
Вы должны просканировать шину, возможно, дисплей имеет другой адрес. Вы можете использовать этот скетч: https://playground.arduino.cc/Main/I2cScanner/, @Sim Son
Я ссылался на эту ссылку. Он показывает адрес 3c, но это не должно быть так, потому что на приведенном выше рисунке показана таблица данных ssd1306., @shivamag00