Подключение oled дисплея с контроллером SSD1306 к STM32 по I2C

Многие, наверное, знают о таких маленьких дешёвых (меньше $3) OLED дисплеях, которые можно найти в огромном ассортименте на ebay или aliexpress. В интернете существует множество различных статей о том, как подключать эти дисплеи к Arduino и другим МК, но для STM32f10x затруднительно найти даже библиотеку. Поэтому я решил написать эту статью.

Данный дисплей имеет разрешение 128х64 пиксела и контроллер SSD1306 и подклчается к микроконтроллеру по интерфейсу I2C.



Для STM32 была найдена библиотека для этого дисплея, но она была для серии f4xx — необходимо было модифицировать для f10x.

Исходные файлы модифицированной мной библиотеки можно взять тут.
ssd1306_i2c.c
ssd1306_i2c.h
Интерфейс для работы с I2C
ssd1306.c
ssd1306.h
Библиотека для работы с дисплеем. Представляет методы для рисования на дисплее, вывода текста, и вывода всего на oled.
fonts.c
fonts.h
Шрифты для вывода текста на экран. Там есть три шрифта, но можно создать любой свой при помощи этой программы или аналогов

Схема подключения предельно проста:
Vcc +3.3V. Допустимое напряжение — от 3.3В до 5В
GND GND
SCL PB6
SDA PB7

image

Для работы с библиотекой нужно подключить заголовочный файл:

#include "ssd1306.h"

И перед использованием инициализировать:

SSD1306_Init();

Теперь можно что-нибудь нарисовать:

SSD1306_GotoXY(0, 44); //Устанавливаем курсор в позицию 0;44. Сначала по горизонтали, потом вертикали.
SSD1306_Puts("Hello, habrahabr!!", &Font_7x10, SSD1306_COLOR_WHITE); //пишем надпись в выставленной позиции шрифтом "Font_7x10" белым цветом. 
SSD1306_DrawCircle(10, 33, 7, SSD1306_COLOR_WHITE); //рисуем белую окружность в позиции 10;33 и радиусом 7 пикселей

Всё, что мы нарисовали сейчас находится в буффере в оперативной памяти МК, чтобы вывести всё на дисплей необходимо вызвать:

SSD1306_UpdateScreen();

После этого наш дисплей обновится и будет выводить надпись и кружок. После вызова SSD1306_UpdateScreen() буффер в МК не сбрасывается сам, поэтому новые рисунки будут поверх предыдущих, для сброса можно заполнить всё чёрным цветом:

SSD1306_Fill(SSD1306_COLOR_BLACK);

Все функции библиотеки:

uint8_t SSD1306_Init(); //Инициализация

SSD1306_UpdateScreen(); //Посылаем данные из буффера в памяти дисплею

SSD1306_ToggleInvert(); //инвертирует цвета изображения в оперативной памяти

SSD1306_Fill(SSD1306_COLOR_t Color); //заполняем дисплей желаемым цветом

SSD1306_DrawPixel(uint16_t x, uint16_t y, SSD1306_COLOR_t color); //нарисовать один пиксел

SSD1306_GotoXY(uint16_t x, uint16_t y); //установить позицию текстового курсора

SSD1306_Putc(char ch, FontDef_t* Font, SSD1306_COLOR_t color); //вывести символ сh в позиции курсора

SSD1306_Puts(char* str, FontDef_t* Font, SSD1306_COLOR_t color); //вывести строку str в позиции курсора

SSD1306_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, SSD1306_COLOR_t c); //нарисовать линию

SSD1306_DrawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c); //наррисовать прямоугольник

SSD1306_DrawFilledRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c); //заполненный прямоугольник

SSD1306_DrawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, SSD1306_COLOR_t color); //треугольник

SSD1306_DrawCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c); //круг радиуса r

SSD1306_DrawFilledCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c); //заполненный круг

Доступные шрифты, но вы так же можете добавить свои, в том числе и русские:

  • Font_7x10
  • Font_11x18
  • Font_16x26

Дисплей работает довольно быстро(FPS около 14-18) на скорости I2C 400кГц(450 тоже без проблем, но рисковать не стал, а на 500 подтормаживает) и без проблем.

Использовал CooCox IDE. Готовый проект можно скачать тут: Яндекс.Диск.

P.S. с момента написания статьи и до её публикации из песочницы прошло довольно много времени(6 месяцев), за которое я успел несколько раз изменить библиотеку.

Более новую версию библиотеки с поддержкой DMA и тестовый проект для Keil и cubeMx можно взять здесь. Самую последнюю версию библиотеки вы найдёте тут.

Пример работы библиотеки:



С удовольствием отвечу на ваши вопросы! Удачи!

Комментарии 14

    +1
    Добро пожаловать! Спасибо за статью. Пользуясь случаем, спрошу, а есть то же самое, только для SPI версии?
      +1
      Спасибо!
      Нет, к сожалению, но на самом деле переделывать почти ничего не придётся, особенно в библиотеках на HAL — изменить лишь пару функций отправки. Команды ведь те же, данные тоже.
        +1
        Я пробовал для такого дисплея использовать библиотеку https://bitbucket.org/nadyrshin_ryu/ssd1306_stm32
        Поддерживает I2C и 4-проводной SPI
        2 шрифта, в т.ч. символы кириллицы
        0
        Странно. Поиск на github работает прекрасно.
          0
          А есть подобные дисплеи но большие, что бы заменить символьный LCD 4x16?
            0
            Такого типа есть ещё 1.8дюйма с таким же разрешением. А так есть много разных графических оледов в формате символьных. Например: http://www.compel.ru/FLzPny/SA0P/VPA-P8-Pb-PT-Pc-PF-Px-2W/
              0
              До 2.7 дюйма найти не проблема. Разрешение такое же — 128х64.
              Пример: http://www.compel.ru/2013/05/24/wex012864c-d-l-novyie-2-7-oled-displei-ot-winstar
              И такие(абсолютно совместимые) выпускает не только Winstar.
              0
              Как с поддержкой кириллицы?
                0
                кирилических шрифтов в интернете для данной библиотеки нет
                  +1
                  Есть кириллица. Я написал программку для генерации, но не успел оформить. Вот репозиторий её с инструкцией.

                  Вот видюшка на которой есть русский текст.
                0

                Я такой заводил с помощью u8glib.

                • НЛО прилетело и опубликовало эту надпись здесь
                    0
                    Хоп-хоп и в продакшен. А то, что эта библиотека требуется, сами разбирайтесь. Такие статьи страшнее новостей.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое