Часть 29: Подключение OLED-дисплея через один пин (SPI на 1 проводе)

Обычно для OLED нужны 4-5 пинов. Но мы можем использовать ShiftOut для эмуляции SPI всего на одном пине данных + питание.

Схема подключения:

  • Пин данных → DIN (MOSI) дисплея
  • GND → GND дисплея
  • VCC → VCC дисплея
  • Питание → VDD дисплея (через резистор 10 кОм)

Код для управления OLED через один пин:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define OLED_PIN PB0  // Пин 8
#define OLED_PORT PORTB
#define OLED_DDR DDRB

// Отправка байта через один провод (протокол 1-Wire SPI)
void oled_send_byte(uint8_t data, uint8_t isCommand) {
    // Начинаем с LOW
    OLED_PORT &= ~(1 << OLED_PIN);
    _delay_us(1);
    
    // Отправляем биты (MSB first)
    for (uint8_t i = 0; i < 8; i++) {
        if (data & 0x80) {
            OLED_PORT |= (1 << OLED_PIN);
        } else {
            OLED_PORT &= ~(1 << OLED_PIN);
        }
        _delay_us(2);
        data <<= 1;
    }
    
    // Завершаем HIGH
    OLED_PORT |= (1 << OLED_PIN);
    _delay_us(2);
}

// Инициализация OLED
void oled_init() {
    OLED_DDR |= (1 << OLED_PIN);  // Пин как выход
    OLED_PORT |= (1 << OLED_PIN); // Начинаем с HIGH
    
    _delay_ms(100);
    
    // Команды инициализации для SSD1306
    oled_send_byte(0xAE, 1);  // Display off
    oled_send_byte(0xD5, 1);  // Set display clock divide
    oled_send_byte(0x80, 1);
    oled_send_byte(0xA8, 1);  // Set multiplex
    oled_send_byte(0x1F, 1);  // 32 строки
    oled_send_byte(0xD3, 1);  // Set display offset
    oled_send_byte(0x00, 1);
    oled_send_byte(0x40, 1);  // Set start line
    oled_send_byte(0x8D, 1);  // Charge pump
    oled_send_byte(0x14, 1);  // Enable charge pump
    oled_send_byte(0x20, 1);  // Memory mode
    oled_send_byte(0x00, 1);  // Horizontal
    oled_send_byte(0xA1, 1);  // Segment remap
    oled_send_byte(0xC8, 1);  // COM output scan direction
    oled_send_byte(0xDA, 1);  // COM pins hardware config
    oled_send_byte(0x02, 1);
    oled_send_byte(0x81, 1);  // Contrast
    oled_send_byte(0x7F, 1);
    oled_send_byte(0xD9, 1);  // Precharge period
    oled_send_byte(0xF1, 1);
    oled_send_byte(0xDB, 1);  // VCOM detect
    oled_send_byte(0x40, 1);
    oled_send_byte(0xA4, 1);  // Display on resume
    oled_send_byte(0xA6, 1);  // Normal display
    oled_send_byte(0xAF, 1);  // Display on
}

// Отправка пиксельных данных
void oled_draw_pixel(uint8_t x, uint8_t y, uint8_t color) {
    // Устанавливаем страницу
    oled_send_byte(0x22, 1);  // Page start/end
    oled_send_byte(0x00, 1);
    oled_send_byte(0x07, 1);
    
    // Устанавливаем колонку
    oled_send_byte(0x21, 1);  // Column start/end
    oled_send_byte(0x00, 1);
    oled_send_byte(0x7F, 1);
    
    // Отправляем пиксельные данные
    for (uint8_t i = 0; i < 128 * 8; i++) {
        oled_send_byte(color ? 0xFF : 0x00, 0);
    }
}

void setup() {
    oled_init();
    oled_draw_pixel(0, 0, 1);  // Рисуем точку
}

void loop() {}

Вам также может понравиться

About the Author: ардуинчиков

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *