Многие, наверное, знают о таких маленьких дешёвых (меньше $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 можно взять здесь. Самую последнюю версию библиотеки вы найдёте тут.

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



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

Комментарии (12)


  1. UA3MQJ
    25.10.2016 01:25
    +1

    Добро пожаловать! Спасибо за статью. Пользуясь случаем, спрошу, а есть то же самое, только для SPI версии?


    1. SL_RU
      25.10.2016 01:39
      +1

      Спасибо!
      Нет, к сожалению, но на самом деле переделывать почти ничего не придётся, особенно в библиотеках на HAL — изменить лишь пару функций отправки. Команды ведь те же, данные тоже.


    1. Silnur
      25.10.2016 12:29
      +1

      Я пробовал для такого дисплея использовать библиотеку https://bitbucket.org/nadyrshin_ryu/ssd1306_stm32
      Поддерживает I2C и 4-проводной SPI
      2 шрифта, в т.ч. символы кириллицы


  1. x893
    25.10.2016 02:27

    Странно. Поиск на github работает прекрасно.


  1. vitaliy91
    25.10.2016 12:13

    А есть подобные дисплеи но большие, что бы заменить символьный LCD 4x16?


    1. SL_RU
      25.10.2016 14:57

      Такого типа есть ещё 1.8дюйма с таким же разрешением. А так есть много разных графических оледов в формате символьных. Например: http://www.compel.ru/FLzPny/SA0P/VPA-P8-Pb-PT-Pc-PF-Px-2W/


  1. ElectricFromUfa
    25.10.2016 12:29

    Как с поддержкой кириллицы?


    1. golf2109
      25.10.2016 13:18

      кирилических шрифтов в интернете для данной библиотеки нет


    1. SL_RU
      25.10.2016 14:44
      +1

      Есть кириллица. Я написал программку для генерации, но не успел оформить. Вот репозиторий её с инструкцией.

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


      1. SL_RU
        26.10.2016 18:54

        Ой, извините. Ссылка что-то не скопировалась =Р Тут на гитхабе программа для генерации шрифтов


  1. Vooon
    25.10.2016 14:25

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


  1. GoldenStar
    26.10.2016 00:10

    Статья отличная, спасибо, а вот дисплеи так себе — на ярком солнце абсолютно слепые. Летал на коптере летом и пользовался вольтметром для батарей Fr-Sky Li-Po voltage sensor FLVS-01. Вообще ни чего не видно на экране под прямыми солнечными лучами. В помещении хорошо смотрится, но ни как не на улице.