Ви не увійшли.
Сторінки 1
Є в наявності робочий дисплей OLED 128x32 з І2С інтерфейсом. Намагаюсь керувати ним "в ручну", тобто без використання бібліотек. Хотілося б спробувати створити свою, під себе.
Суть проблеми: не можу розібратись з даташитом як виводити інформацію на дисплей. Після ініціалізації, які мають бути команди?
Щоб зрозуміліше було, наприклад, я хочу засвітити перший піксель у верхньому лівому куті. Хтось може, простими словами, написати послідовність команд і даних? Зрозумівши як виконується дана проста задача, я зможу вже побачити біль-менш яснішу картину.
Неактивний
Який драйвер? SSD1306/SH1106?
Керувати окремими пікселями - трошки складніша задача. Дуже просто керувати стовпчиками по 8 пікселів. Дисплей просто відображає вміст своєї памяті у побітовому вигляді на екрані. Порядок слідування байтів можна задати (розбирався лише з SSD1306, там це називається режимом адресації), наприклад: послідовні 4 байти відображають один стовпчик з 32 пікселів, наступні 4 - другий... - режим зручний для графіки, або можна задати так: 128 байтів відображають шматок екрану 8x128 пікселів, наступні 128 - такий же шматок на 8 пікселів нижче... - режим зручний для тексту. Писати байти в память дисплея можна, а от читати неможливо, тому для реалізації графіки Вам доведеться тримати в памяті мк копію памяті дисплея. Одразу після адресації i2c пристрою передаєте байт, який задає режим даних або команд, в режимі команд задаєте початкову позицію, з якої буде писатись в память, коли наступного разу будете в режимі даних. Даташит слід читати так: вибираєте режим адресації і використовуєте команди, позначені для Вашого режиму адресації, доманди для іншого режиму адресації ігноруєте, інакше воно Вас заплутає.
Неактивний
В ініціалізації є команди 0х20, 0х00
Ось алгоритм функції щоб щось вивести на дисплей:
- Старт біт І2С
- Відправка (SLA+W) - адреса дисплея з відзнакою Write
- Відправка (0b11000000) - наступний байт будуть дані
- Відправка (0b00000001) - байт даних, що потрібно відобразити в першій колонці першої сторінки
- Стоп біт І2С
Чи правильний мій шлях? Чи можете в подібному алгоритмі пояснити як потрібно?
Остання редакція PolArt (2023-03-30 14:36:06)
Неактивний
Це з працюючого коду:
#define DISPLAY_WIDTH 128
#define DISPLAY_HEIGHT 32
#define LCD_I2C_ADR (0x78 >> 1)
const uint8_t initSequence [] PROGMEM = {
0xae, // Display OFF (sleep mode)
0x8d, 0x14, // Set DC-DC enable
0xd9, 0x22, // Set pre-charge period
0xdb, 0x20, // Set vcomh: 0x20=0.77xVcc
0xd5, 0x80, // Set Display Clock Divide Ratio/Oscillator Frequency
0x81, 0x7f, // Set contrast control register
0xa4, // Output RAM to Display
0xa6, // Set display mode. A6=Normal; A7=Inverse
0x20, 0b00, // Set Memory Addressing Mode: 00=Horizontal 01=Vertical 10=Page
0x21, 0, 127, // Setup column start & end address
0x22, 0, DISPLAY_HEIGHT/8-1,// Setup page start & end address
0xd3, 0x00, // Set display offset (vertical shift)
0x40 + 0, // Set Display Start Line
0xa0, // Set Segment Re-map: a0=address 0 mapped; a1=address 127 mapped.
0xa8, DISPLAY_HEIGHT-1, // Set multiplex ratio
0xc0, // Scan Direction: c0=from COM0; c8=from COM[mux]
#if DISPLAY_HEIGHT==64
0xda, 0x12,
#elif DISPLAY_HEIGHT==32
0xda, 0x02,
#endif
0xaf // Display ON
};
const uint8_t posSequence [] PROGMEM = {
0xb0, // Set Page Start Address for Page Addressing Mode
0x00, 0x10 // Set Column Start Address for Page Addressing Mode
};
void lcd_command(uint8_t cmd[], uint8_t size) {
uint8_t i;
i2c_start((LCD_I2C_ADR << 1) | 0);
i2c_byte(0x00); // 0x00 for command, 0x40 for data
for (i = 0; i < size; i++)
i2c_byte(cmd[i]);
i2c_stop();
}
void lcd_command_P(const uint8_t cmd[], uint8_t size) {
uint8_t i;
i2c_start((LCD_I2C_ADR << 1) | 0);
i2c_byte(0x00); // 0x00 for command, 0x40 for data
for (i = 0; i < size; i++)
i2c_byte(pgm_read_byte(&cmd[i]));
i2c_stop();
}
void lcd_data(uint8_t data[], uint16_t size) {
uint16_t i;
i2c_start((LCD_I2C_ADR << 1) | 0);
i2c_byte(0x40); // 0x00 for command, 0x40 for data
for (i = 0; i < size; i++)
i2c_byte(data[i]);
i2c_stop();
}
void lcd_clear(void) {
lcd_command_P(posSequence, sizeof(posSequence));
uint16_t i;
i2c_start((LCD_I2C_ADR << 1) | 0);
i2c_byte(0x40); // 0x00 for command, 0x40 for data
for (i = 0; i < DISPLAY_WIDTH*DISPLAY_HEIGHT/8; i++)
i2c_byte(0);
i2c_stop();
}
void lcd_init(void) {
i2c_init();
lcd_command_P(initSequence, sizeof(initSequence));
lcd_clear();
}
i2c_byte() - це відправка байту, з дисплею взагалі нічого не читається
Неактивний
Є зрушення! При чому проблема була не в моїй логіці, а банальна помилка в моєму коді. Це жесть, в мене кілька днів через цей дисплей мізки кипіли
Поки що виводить чихарду незрозумілу. Тепер потрібно буде розбиратись з адресацією. Але дуже дякую за допомогу!!!
Неактивний
Я помітив, що при включенні живлення память вже заповнена випадковими байтами, коли включаєш вивід памяті на дисплей, то буде таке як на фото, очищення треба робити самому записом нулів у всі комірки.
Неактивний
Сторінки 1