STM32 и OLED SSD1306

На этом уроке мы разберёмся с подключением OLED дисплея к микроконтроллеру из семейства STM32. Для эксперимента используем отладочную плату на STM32F030F4P6, хотя на месте этого МК может быть любой другой STM32.

Подключать будем достаточно распространённый дисплей OLED, с контроллером SSD1306 и разрешением 128 x 32 точки.

Соединяем эти два устройство шиной I2C. Хотя в данном примере мы использовали QIIC разъёмы (подробнее о QIIC), в действительности можно использовать любую другую плату и соединить их хоть пайкой. Главное соблюдать принцип подключения по шине I2C.

Оба использованных в данном уроке устройства можно приобрести у нас в магазине:

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

Настройка выводов

Создаём новый проект в STM32CubeIDE и выбираем подходящую модель микроконтроллера. В данном примере использовался STM32F030F4P6.

Затем, открываем экран Pinout & Configuration, далее раздел Connectivity. Выбираем там любой доступный I2C и в настройках параметр Mode устанавливаем в значение I2C.

STM32F030 и OLED SSD1306
Этих настроек для эксперимента будет достаточно.

Программа

Чтобы не писать код управления дисплеем с нуля, используем готовую библиотеку, в которой реализовано общение с контроллером дисплея SSD1306. Ссылка на исходный код в конце статьи.

О том как настроить среду для работы с библиотеками можно узнать из урока.

Переходим к коду файла main.c. Подключим библиотеку, добавив соответствующую директиву в начале программы:

/* USER CODE BEGIN Includes */
#include "ssd1306.h"
/* USER CODE END Includes */

И чуть ниже вставим код для вывода текста на дисплей.

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

  ssd1306_Fill(Black);
  ssd1306_SetCursor(5, 10);
  ssd1306_WriteString("Hello world!", Font_11x18, White);
  ssd1306_UpdateScreen();
  /* USER CODE END 2 */ 

Готово. Загружаем программу на микроконтроллер и наблюдаем:

OLED дисплей 128x32 RobotClass, QIIC

В рассматриваемой библиотеке есть все основные функции для создания графики. Описание этих функций можно подсмотреть в файле ssd1306.h. Вот некоторые из них:

ssd1306_Fill — заливка экрана одним цветом

ssd1306_DrawPixel — отрисовка точки

ssd1306_Line — отрисовка линии по алгоритму Брезенхэма

ssd1306_WriteString

ssd1306_Line — отрисовка лигии по алгоритму Брезенхэма

ssd1306_DrawCircle — окружность

ssd1306_DrawRectangle — прямоугольник

ssd1306_DrawBitmap — изображение

Собственно, остановимся на последней функции. Выведем на экран логотип RobotClass.

Вывод изображения на OLED

Для начала, как и в предыдущих примерах для работы с дисплеями (OLED 0.96, Nokia5110) мы подготовим изображение. Преобразуем его в массив.

Разрешение нашего дисплея — 128 x 32 точки. Следовательно, обрезаем и масштабируем картинку ровно под этот размер и сохраняем в формате BMP в режиме 256 цветов на точку. При этом сама картинка должна быть монохромной, без градаций серого.

Есть в вашем конкретном редакторе не получается сохранить файл в таком формате, можно открыть его в обычном Paint и сохранить там.

Затем, открываем наш инструмент для конвертирования картинок в массив:

https://tools.robotclass.ru/bmp2bin/bmp2bin.html

Загружаем файл, и жмём «Конвертировать». Настройки можно не трогать. Полученный массив вставляем в нашу программу:

/* USER CODE BEGIN PV */
const uint8_t logo [] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x04, 0xfc, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x1f, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x1e, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x03, 0xf0, 0x3e, 0x00, 0xf0, 0xfc, 0x03, 0xf0, 0xff, 0x81, 0xc0, 0x00, 0x00, 0x0c, 0x07, 0x00,
	0x03, 0xfc, 0xfc, 0x00, 0xfc, 0xfe, 0x0f, 0xf8, 0xff, 0x87, 0xf7, 0x00, 0x70, 0x3f, 0x1f, 0x80,
	0x03, 0x9e, 0xfc, 0x00, 0xfc, 0xc7, 0x1e, 0x3c, 0x1c, 0x0f, 0xf7, 0x00, 0xf0, 0x7f, 0x3f, 0x80,
	0x03, 0x8e, 0xfc, 0x00, 0x7c, 0xc7, 0x3c, 0x1e, 0x1c, 0x1c, 0x17, 0x00, 0xf8, 0x71, 0x38, 0x00,
	0x03, 0x8e, 0xfc, 0x00, 0xfc, 0xc7, 0x38, 0x0e, 0x1c, 0x38, 0x07, 0x01, 0xf8, 0x70, 0x38, 0x00,
	0x03, 0xfc, 0xfc, 0x00, 0xfc, 0xfe, 0x38, 0x0e, 0x1c, 0x38, 0x07, 0x01, 0xf8, 0x78, 0x3e, 0x00,
	0x03, 0xf8, 0x3e, 0x00, 0xf0, 0xfe, 0x38, 0x0e, 0x1c, 0x38, 0x07, 0x01, 0xdc, 0x3e, 0x1f, 0x80,
	0x03, 0xf0, 0x1f, 0x03, 0xe0, 0xff, 0x38, 0x0e, 0x1c, 0x38, 0x07, 0x03, 0xfc, 0x1f, 0x0f, 0xc0,
	0x03, 0xf8, 0x1f, 0xc7, 0xf0, 0xc3, 0xb8, 0x0e, 0x1c, 0x38, 0x07, 0x03, 0xfe, 0x07, 0x81, 0xc0,
	0x03, 0xb8, 0x3f, 0xff, 0xf0, 0xc3, 0xbc, 0x0e, 0x1c, 0x3c, 0x07, 0x07, 0xfe, 0x03, 0xa1, 0xc0,
	0x03, 0x9c, 0x1f, 0xff, 0xe0, 0xc7, 0x9e, 0x1c, 0x1c, 0x1e, 0x37, 0x07, 0x0e, 0x63, 0xb1, 0xc0,
	0x03, 0x8e, 0x0d, 0xff, 0xc0, 0xff, 0x0f, 0xfc, 0x1c, 0x0f, 0xf7, 0xf7, 0x07, 0x7f, 0x3f, 0xc0,
	0x03, 0x8f, 0x00, 0x78, 0x00, 0xfe, 0x07, 0xf0, 0x1c, 0x07, 0xf7, 0xfe, 0x07, 0x7e, 0x3f, 0x80,
	0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* USER CODE END PV */

Предыдущий код можно не удалять. Лучше оформим его в виде функции для последующего использования.

Для этого объявим две функции, старую для отрисовки текста и новую для изображения:

/* USER CODE BEGIN PFP */
void displayDrawBitmap();
void displayDrawText();
/* USER CODE END PFP */

А затем реализации для них:

/* USER CODE BEGIN 4 */
void displayDrawBitmap(){
    ssd1306_Fill(Black);
    ssd1306_DrawBitmap(0, 0, logo, 128, 32, White);
    ssd1306_UpdateScreen();
}
void displayDrawText(){
    ssd1306_Fill(Black);
    ssd1306_SetCursor(5, 10);
    ssd1306_WriteString("Hello world!", Font_11x18, White);
    ssd1306_UpdateScreen();
}
/* USER CODE END 4 */

Теперь в суперцикле добавим вызовы этих функций через паузу в 3 секунды.

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    displayDrawText();
    HAL_Delay(3000);
    displayDrawBitmap();
    HAL_Delay(3000);
  }
  /* USER CODE END 3 */

Готово. Загружаем на STM32 и смотрим.

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

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


Изменено:

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

Ваш адрес email не будет опубликован.