STM32: OLED и русский текст TrueType 

На этом уроке будем разбираться с тем, как отобразить на популярном среди DIY-энтузиастов OLED дисплее с контроллером SSD1306 русский текст, да ещё и с использование красивых шрифтов.

Список необходимых компонентов

Для выполнения всех экспериментов в этой инструкции потребуются: отладочная плата с микроконтроллером STM32F103C8T6, дисплей OLED и кабель QIIC для удобного подключения по I2C.

В корзину
В корзину
В корзину

Библиотека stm32-ssd1306

Используем известную библиотеку для работы с SSD1306 на stm32. У RobotClass есть своя редакция этой библиотеки, с некоторыми доработками (ссылка в конце).

Далее создаём в STM32CubeIDE новый проект, настраиваем периферию для работы с OLED через I2C интерфейс, а также подключаем библиотеку.

Создание шрифта

Как известно, True Type шрифты являются векторными. Чтобы их эффективно использовать на stm32 придётся их растеризовать в заданном размере. По сути, превратить каждую букву в привычный набор точек. Сделать это можно при помощи python-скрипта, который есть в той же библиотеке.

Устанавливаем python версии 3.9. Готовим файлик нужного нам шрифта, например: nasalization.ttf. И запускаем скрипт generate.py из папки: stm32-ssd1306-master\examples\custom-fonts

c:\Python39\python.exe ./generate.py --font nasalization.ttf --size 16 --atlas atlas.png --charset cp1251 --proportional
  • size — отвечает за высоту буквы шрифта, но не в пикселах.
  • atlas — указывает на необходимость изображения таблицы символов по окончании процедуры растеризации
  • charset — задаёт нужную кодировку
  • proportional — делает шрифт не моноширинным (когда каждый символ имеет одинаковую ширину), а пропорциональным.

По завершении работы скрипта мы получим два файла:

  • файл с кодами символов — font.c
  • изображением символов — atlas.png

Последний нужен сугубо для визуального контроля нашего творения. Если открыть файл font.c, то мы увидим, что символы шрифта получились размером 24×20 точек, а совсем не 16, как мы указывали в генераторе:

static const uint16_t Font24x20 [] = {
...

Также отметим, что у моноширинного шрифта все символы будут иметь размер 24×20, а вот у пропорционального (который мы и сделали) символы будут иметь разный размер: символ ! будет сильно уже, чем русская буква Щ. В случае такого «растопыристого» шрифта как nasalization пропорциональный вариант смотрится гораздо лучше моноширинного.

Теперь копируем этот файл в папку SSD1306/src нашего проекта. Если планируется использовать несколько шрифтов, то файлу лучше дать уникальное имя, например: font_24x20p.c

stm32cubeide библиотека stm32-ssd1306

Готово! Теперь шрифтом можно пользоваться.

Настройка проекта

Есть ещё один момент, который может помешать в покорении кириллицы. Нужно настроить проект таким образом, чтобы он переводил русский текст в IDE, написанный в кодировке UTF8 в текст CP1251 при компиляции.

Заходим в настройки проекта. Далее в раздел C/C++ Build. Первая вкладка Tool Settings, а в ней выбираем пункт MCU GCC Compiler / Miscellaneous. Добавляем флаги компиляции:

-finput-charset=UTF-8 -fexec-charset=cp1251

Сохраняем настройки. Готово, приступаем к программе.

Программа

Пусть на дисплей выводится строка — СТАРТ. Объявим её как указатель на массив char. Далее подключим наш шрифт.

/* USER CODE BEGIN PV */
char* text_cyr = "СТАРТ";
extern const SSD1306_Font_t Font_24x20;
/* USER CODE END PV */

Далее в коде, перед запуском суперцикла проведем инициализацию дисплея командой ssd1306_Init. Затем выводим нужные строки в конкретных координатах. Указываем нужный шрифт.

  /* USER CODE BEGIN 2 */
  ssd1306_Init();

  ssd1306_Fill(Black);
  ssd1306_SetCursor(35, 30);
  ssd1306_WriteString(text_cyr, Font_24x20, White);
  ssd1306_UpdateScreen();
  /* USER CODE END 2 */

Загружаем программу на STM32 и смотрим что получилось.

Кириллица на stm32 oled ssd1306

Размышления

Надо понимать, что шрифт с кириллицей занимает в 2 раза больше места, чем без оной. Если ещё использовать большие размеры шрифтов, то можно легко столкнуться с нехваткой места во флеш памяти микроконтроллера. А что если в программе требуется отобразить всего несколько слов большими буквами?

В библиотеке stm32_ssd1306 для этих целей есть возможность растеризовать не отдельные символы, а целый текст. В результате такой операции мы получим массив точек, который останется вывести на экране в нужном месте.

Для этого используем python-скрипт generate.py:

./generate.py --font nasalization.ttf --size 16 --string "СТАРТ"

В результате работы скрипта получим файл string.c с таким содержимым:

const unsigned char string_55x12 [] = {
...

Далее в программе мы можем отобразить это изображение с помощью функции ssd1306_DrawBitmap:

ssd1306_DrawBitmap(35, 30, string_55x12, 55, 12, White);

Полезные ссылки

Библиотека stm32_ssd1306 в репозитории github:

https://github.com/robotclass/stm32-ssd1306


Изменено:

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

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.