MSP430: Драйвер OLED 128x64 SSD1306 +++
Главная »Проекты »MSP430: Драйвер OLED 128x64 SSD1306
MSP430: Драйвер OLED 128x64 SSD1306

Здесь рассматривается драйвер на Си (IAR) для OLED 128x64 с управляющим контроллером SSD1306. Данный драйвер использует для управления дисплеем аппаратный интерфейс I2C микроконтроллера MSP430G2553. Особенностью драйвера является отказ от использования экранного буфера, т.к. данный контроллер имеет недостаточный для этой цели объем ОЗУ (512 байт). Это, в сочетании с невозможностью чтения из дисплея, несколько сужает возможности графики, т.к. не позволяет накладывать новое изображение рядом или на ранее выведенное. Однако, часто такое наложение не требуется и, при грамотной реализации, получаемое изображение выглядит весьма эргономично.

Hardware

Внешний вид и размеры OLED:

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

Драйвер реализован на платформе MSP-EXP430G2 LaunchPad. Для подключение дисплея требуется всего 4 провода:

OLED

LaunchPad

VCC VCC
GND GND
SCL P1.6
SDA P1.7

На плате LaunchPad необходимо снять джампер J5/P1.6, чтобы подключенный через эту цепь светодиод LED2 не шунтировал сигнал SCL.

Software

Состав файлов драйвера:

Имя

Описание

SSD1306_I2C.c Исполняемый код драйвера дисплея
SSD1306_I2C.h Заголовочный файл драйвера дисплея
TI_USCI_I2C_master.c Исполняемый код драйвера I2C
TI_USCI_I2C_master.h Заголовочный файл драйвера I2C
TI_USCI_I2C_master legal.txt Файл лицензии Texas Instruments драйвера I2C
font6x8.h Заголовочный файл шрифта 6х8
font12x16.h Заголовочный файл шрифта 12х16

Функции драйвера используют глобальный динамический буфер в памяти максимальным размером на 1 строку + 1 байт (129 байт) – это необходимо учитывать при установке размера кучи (heap), задав, например, значение 0x90 (при этом, размера стека (stack) в 0x20 вполне достаточно).

Как уже было сказано выше, драйвер дисплея использует аппаратный интерфейс I2C. Это позволяет разгрузить ядро контроллера и повысить стабильность работы. В свою очередь для работы по шине I2C используется несколько модернизированный код от Texas Instruments – slaa382a. Изменения коснулись в основном во введении возможности задать значение предделителя, определяющего скорость шины – введена функция TI_USCI_I2C_setprescale. Вызов данной функции должен предшествовать первому применению остальных методов. Также, вызвав функцию TI_USCI_I2C_setprescale перед новым обращением к шине, можно изменить скорость обмена. Тактирование шины осуществляется от сигнала SMCLK, деленного на величину (UCB0BR0 + UCB0BR1 x 256). Т.к. значение UCB0BR1 приравнено 0, то частота тактирования I2C равна SMCLK/UCB0BR0.

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

Система координат имеет начало в левом верхнем углу экрана с пикселя с координатами X = 0 и Y = 0. Положительное направление по оси X – вправо, по оси Y – вниз (переназначение координат не используется). Память дисплея организована 8-ю страницами по 128 байт.

В пределах страницы младший бит отображает пиксель ближайший к началу координат.

Исходный код снабжен комментариями (правда, в основном, на английском), которые помогут разобраться в реализации.

void ssd1306_Init(unsigned char bus_prescale);

Функция инициализация индикатора. Вызывается однократно, настраивает шину I2C и производит начальную инициализацию дисплея. Перед вызовом данной функции необходимо разрешить прерывания. Параметр bus_prescale задает значение предделителя, например, при значении 2, и частоте SMCLK = 1 МГц, частота шины равна 500 кГц.

ssd1306_DisplayOff();
ssd1306_DisplayOn();

Макросы выключения/включения дисплея.

ssd1306_Clear();

Макрос очистки дисплея.

ssd1306_DisplayNormal();
ssd1306_DisplayInverce();

Макросы переключения режима отображения нормальное/инверсное.

void ssd1306_SetContrast(unsigned char contrast);

Установка контраста. Параметр contrast определяет значение контраста (малым значениям соответствует менее яркое изображение). При инициализации устанавливается значение 0xC8 (200).

void ssd1306_SetCursor(unsigned char x, unsigned char p);

Установить позицию вывода: x – по горизонтали (в пикселах); p – по вертикали (в страницах).

void ssd1306_SendCommand(unsigned char command);

Послать дисплею команду command. Команда для внутреннего использования и расширения возможностей драйвера.

void ssd1306_SendData(unsigned char *data, unsigned char count);

Послать дисплею данные из буфера data, в количестве count. Команда для внутреннего использования и расширения возможностей драйвера.

void ssd1306_FillDisplay(unsigned char data);

Заполнить весь дисплей однородными данными data по-странично (0xFF – высветить; 0x00 – погасить).

void ssd1306_DrawPixel(unsigned char x, unsigned char y, unsigned char clear);

Нарисовать/погасить пиксел. (x,y) – координаты в пикселах; clear: если 1 – установить пиксел в 0 (погасить), если 0 – в 1 (высветить).

void ssd1306_DrawLine(unsigned char x1, unsigned char y1, 
                      unsigned char x2, unsigned char y2, unsigned char clear);

Нарисовать/стереть отрезок из точки (x1,y1) в точку (x2,y2), координаты в пикселах; clear: если 1 – установить пикселы отрезка в 0 (погасить), если 0 – в 1 (высветить).

void ssd1306_DrawHLine(unsigned char x, unsigned char y, unsigned char sx);

Нарисовать горизонтальную линию от точки (x,y) длиной sx (в пикселах).

void ssd1306_DrawVLine(unsigned char x, unsigned char y, unsigned char sy);

Нарисовать вертикальную линию от точки (x,y) длиной sy (в пикселах).

void ssd1306_DrawRect(unsigned char x, unsigned char y, 
                      unsigned char sx, unsigned char sy);

Нарисовать незаполненный прямоугольник: (x,y) – координаты (в пикселах) верхнего левого угла; (sx,sy) – ширина и высота в пикселах.

void ssd1306_FillRect(unsigned char x, unsigned char y, 
                      unsigned char sx, unsigned char sy, unsigned char data);

Залить прямоугольник значением data; (x,y) – координаты (в пикселах) верхнего левого угла; (sx,sy) – ширина и высота в пикселах.

void ssd1306_DrawImage(unsigned char x, unsigned char y, 
                       unsigned char sx, unsigned char sy,
                       const unsigned char img[], unsigned char invert);

Нарисовать битовую картинку; (x,y) – координаты (в пикселах) верхнего левого угла; (sx,sy) – ширина и высота в пикселах; invert: если 1 – инверсный вывод.

В драйвер встроено 2 шрифта, с одинаковым набором символов, размером 6х8 и 12х16 пикселей:

void ssd1306_Draw6x8Str(unsigned char x, unsigned char p, const char str[], 
                     unsigned char invert, unsigned char underline);

Вывести строку str[] шрифтом 6х8 на страницу p в горизонтальную координату x (в пикселах); invert: если 1 – инверсно; underline: если 1 – с подчеркиванием. Данная функция может выводить строку только на указанную страницу. Всего на дисплей можно вывести 8 строк по 21 символ.

void ssd1306_Draw12x16Str(unsigned char x, unsigned char y, const char str[],
                          unsigned char invert);

Вывести строку str[] шрифтом 12х16: (x,y) – координаты верхнего левого угла в пикселах; invert: если 1 – инверсно. Данная функция может выводить строку в любое место дисплея.

ssd1306_DeactivateScroll();

Макрос выключения ранее включенного скролирования.

void ssd1306_HorzScroll(unsigned char dir_left, unsigned char start_page, 
                        unsigned char end_page, unsigned char speed);

Включить горизонтальное скролирование: dir_left – направление (1: влево, 0: вправо); start_page, end_page – начальная и конечная скролируемые страницы; speed – скорость (во фреймах).

Возможные скорости скролирования (меньше – быстрее):

  • SSD1306_2_FRAMES
  • SSD1306_3_FRAMES
  • SSD1306_4_FRAMES
  • SSD1306_5_FRAMES
  • SSD1306_25_FRAMES
  • SSD1306_64_FRAMES
  • SSD1306_128_FRAMES
  • SSD1306_256_FRAMES
void ssd1306_DiagScroll(unsigned char dir_left, unsigned char rows_fixed, 
                        unsigned char rows_scroll, unsigned char start_page, 
                        unsigned char end_page, unsigned char speed, 
                        unsigned char vert_offset);

Включить горизонтальное и вертикальное скролирование: dir_left – горизонтальное направление (1: влево, 0: вправо); rows_fixed – количество фиксированных (сверху) строк; rows_scroll – количество скролируемых строк; start_page, end_page – начальная и скролируемые конечная страницы; speed – скорость (во фреймах).

Demo

Демо-пример сначала показывает "мультфильм", демонстрирующий работу вышеуказанных методов, затем работает как термометр – шрифтом 12x16 отображает измеренное встроенным в м/к термодиодом значение температуры.

К статье прилагаются файлы:


Внимание! Запрещается воспроизведение данной статьи или ее части без согласования с автором. Если вы желаете разместить эту статью на своем сайте или издать в печатном виде, свяжитесь с автором.
Автор статьи: Вершинин И.В.

+