Проблема с OLED дисплеем - Не работает команда DISPLAY_OFF.

ddr2
Offline
Зарегистрирован: 27.12.2020

Использую библиотеку https://github.com/Matiasus/SSD1306 библиотека работает, тест main.c работает. 

После чего добавил вызов  пытаюсь отключить дисплей вызовом функции:

_delay_ms(1000);
SSD1306_Send_Command (SSD1306_DISPLAY_OFF);

Дебаг uart'ом говори что при вызове "SSD1306_Send_Command (SSD1306_DISPLAY_OFF);"  Ардуино уно зависает в этом месте.

Может кто в курсе, в чём может быть проблема?  

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ddr2 пишет:

Может кто в курсе, в чём может быть проблема?  

Мож кто и в курсе, кто ж его знает.

ddr2
Offline
Зарегистрирован: 27.12.2020

Нашёл другую библиотеку https://github.com/AlexAlexFr/SSD1306-driver в которой Display_Off работает, оказалось команда DISPLAY_OFF отправляется по другому адресу, да и библиотеки работают с разными адресами для одного и того же дисплея 1306. Вырвал из второй библы кусок Display_Off, теперь всё работает.  Только мелкий шрифт напрягает. :)

ЕвгенийП, спасибо за помощь)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не за что! Обращайтесь!

ddr2
Offline
Зарегистрирован: 27.12.2020

Кто-нибудь в курсе почему одна библиотека (Matiasus/SSD1306) работает с адресом '0b111100' (60), а другая (AlexAlexFr/SSD1306-driver) с адресом '0b1111000' (120) ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Мож кто и в курсе, кто ж его знает.

(в прошлый раз Вам это помогло, надеюсь, и сейчас поможет)

ddr2
Offline
Зарегистрирован: 27.12.2020

Да спасибо, этот адрес "0b111100" (60) указан в документации на экран, а этого адреса "0b1111000" (120), в котором работает режим Display_Off в документации нет, но видимо автор этой библиотеки не запаривается над Display_Off(), так как возможно отключает экран ключом по питанию или занулив пин с которого питает.  

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ddr2 пишет:

Кто-нибудь в курсе почему одна библиотека (Matiasus/SSD1306) работает с адресом '0b111100' (60), а другая (AlexAlexFr/SSD1306-driver) с адресом '0b1111000' (120) ?

Вы что-нибудь слышали о шине I2C?

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ddr2 пишет:

этот адрес "0b111100" (60) указан в документации на экран

Там говорится о двух адресах: “b0111100” или “b0111101”, а вот про 0x78 действительно нет. 

Но адрес там сдвинут влево на 1 бит (п. 8.1.5(а)), поэтому реально в регистре “b011110sx”, где s - 0 или 1 в зависимости от того, куда разведён пин D/C, а x - 0 или 1 в зависимости от того это операция записи или чтения.

Возможно, автор одной из библиотек честно сдвигает адрес, а другой решил сдвинуть заранее, потому он уже сдвинут влево. Но точно это только он(а) знает, потому Ваш вопрос "почему" несколько не по адресу.

ddr2
Offline
Зарегистрирован: 27.12.2020

Понял, то есть мы имеем 8 битный регистр адреса (7 + RW = 8), а в доке указан только часть адреса 7 бит без RW. Спасибо. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ddr2 пишет:

Понял, то есть мы имеем 8 битный регистр адреса (7 + RW = 8), а в доке указан только часть адреса 7 бит без RW. Спасибо. 

Не совсем верно.

Адрес - 7-битный. Не часть, а полный.

Но в регистр кроме адреса записывается еще бит RW, который не является частью адреса.

ddr2
Offline
Зарегистрирован: 27.12.2020

andriano пишет:
Не совсем верно. Адрес - 7-битный. Не часть, а полный. Но в регистр кроме адреса записывается еще бит RW, который не является частью адреса.

Спасибо за уточнение. Действительно i2c у нас поток данных, первые 7 бит в потоке это адрес Slave устройства, далее RW-бит. 

ddr2
Offline
Зарегистрирован: 27.12.2020

Короче в библе Matiasus/SSD1306 тоже всё работает, нужно было по аналогии с другими функциями написать sleep_mode(), а SSD1306_Send_StartAndSLAW()как раз сдвигает slave address (0x3c << 1) влево. 

uint8_t SSD1306_SleepMode (uint8_t address, uint8_t sleep_on)
{
  // init status
  uint8_t status = INIT_STATUS;

  // TWI: start & SLAW
  // -------------------------
  status = SSD1306_Send_StartAndSLAW (address);
  // request succesfull
  if (SSD1306_SUCCESS != status) {
    // error
    return status;
  }

  // send command
  // -------------------------    
  if (sleep_on) 
        status = SSD1306_Send_Command (SSD1306_DISPLAY_OFF);
  else
        status = SSD1306_Send_Command (SSD1306_DISPLAY_ON); 
  // request succesfull
  if (SSD1306_SUCCESS != status) {
    // error
    return status;
  }

  // success
  return SSD1306_SUCCESS;
}