678.20K
Category: programmingprogramming

Программирование микроконтроллеров (КБ - 5). Дисплей GMG 12864. Отображение графики и текста

1.

Программирование микроконтроллеров (КБ-5)
Практика 5. Дисплей GMG12864.
Отображение графики и текста
2022

2.

Подготовка графического изображения
Создадим новое изображение в программе Kolourpaint. В меню
Image->Resize/Scale выберем размер изображения ‘128x64px’
(если создаете текстуру, выбирайте требуемый размер).
Совет:
Для рисования текстур
удобно включить сетку
в меню
View->Show Grid
‹#›

3.

Подготовка графического изображения
Сохраним изображение в формате Windows BMP Image, режим
цвета - Monochrome. При этом все цвета, отличные от белого
будут автоматически преобразованы в черный.
‹#›

4.

Подготовка графического изображения
Преобразуем изображение в массив байт, который можно
разместить во FLASH-памяти микроконтроллера. Используем
Online-генератор:
https://www.mischianti.org/images-to-byte-array-online-convertercpp-arduino/
Шаг 1. Загружаем BMP-изображение
‹#›

5.

Подготовка графического изображения
Шаг 2. Устанавливаем параметры Background colour: Black,
Invert image colors. Эти настройки необходимы, т.к. в нашей
версии дисплея черной заливке соответствует байт 0xFF, а
не наоборот (0x00).
‹#›

6.

Подготовка графического изображения
Шаг 3. Выбираем Output format -> Plain bytes, Draw mode Vertical, 1 bit per pixel. Эти настройки соответствуют версии и
типу прошивки дисплея и могут быть подобраны
экспериментально.
‹#›

7.

Подготовка графического изображения
Шаг 5. Нажимаем Generate, копируем полученный массив байт
в буфер обмена.
‹#›

8.

Подготовка графического изображения
Создаем в области глобальных переменных буфер дисплея массив из 128*64 байт, инициализируем сгенерированным
набором байт, соответствующих картинке (текстуре):
const uint8_t backlan[] = {0x00, 0x00, … };
‹#›

9.

Подготовка графического изображения
Отрисовываем изображение, записывая байты в RAM дисплея
страницу за страницей (задействуем те страницы памяти
RAM, которые нужны):
void DrawBacklan(){
for(int p=0; p<=7; p++){
cmd(0xB0 | p); // Set page p
cmd(0x10 | 0x00); // Set column address MSB (0x00...0x0F)
cmd(0x00); // Set column address LSB (0x00...0x0F)
for(int i=0; i<128; i++){
dat(backlan[128*p+i]);
}
}
}
‹#›

10.

Подготовка графического изображения
‹#›

11.

Отображение текстовой информации
Потребуется шрифт – массив байт, который ставит в
соответствие отображаемому символу его изображение на
дисплее. Можно взять шрифт, например, из библиотеки M-JBauer на github:
https://github.com/M-J-Bauer/OLED-or-LCD-128x64-graphicslibrary/blob/main/mp_oled_graphics_test.X/LCD_graphics_lib.c
‹#›

12.

Отображение текстовой информации
Запишем в константу FONT_WIDTH число байт, соответствующих
одному символу текста. В массиве font[] записываются блоки по
FONT_WIDTH байт, соответствующие ASCII-кодам символов
(первый блок соответствует ASCII-символу 0=NUL, и т.д.)
#define FONT_WIDTH 5
const uint8_t font[] = {
0x0, 0x0, 0x0, 0x0, 0x0,
// Ascii 0
0x7C, 0xDA, 0xF2, 0xDA, 0x7C,
//ASC(01)
0x7C, 0xD6, 0xF2, 0xD6, 0x7C,
//ASC(02)
0x38, 0x7C, 0x3E, 0x7C, 0x38,
‹#›

13.

Отображение текстовой информации
Напишем процедуру для вывода символа на дисплей (позиция
записи в RAM дисплея должна быть выставлена до вызова этой
процедуры). В конце символа выводим промежуток в 1px, чтобы
символы не “слипались”.
void PutChar(char x){
uint8_t *pData = (uint8_t *) &font[x * 5];
for(int i=0; i<5; i++ ){
dat( bitrev(*pData) );
pData++;
}
dat(0x00); // Spacing
}
‹#›

14.

Отображение текстовой информации
Функция bitrev() из примера меняет местами старшие и младшие
биты в байте. Ее вызов может потребоваться, если шрифт не
подходит к имеющейся версии дисплея. Пример реализации этой
функции:
uint8_t bitrev(uint8_t b){
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
‹#›

15.

Отображение текстовой информации
Напишем процедуру для вывода текстовой строки.
void PutString(const char pChar[], int strlen, uint8_t page, uint8_t column){
uint8_t pagenum = page;
uint8_t colnum = column;
cmd(0xB0 | pagenum); // Set Page p (Pages 0x00...0x0F)
cmd(0x10 | (column >> 4)); // Set column address MSB (0x00...0x0F)
cmd(column & 0x0F); // Set column address LSB (0x00...0x0F)
for(int i=0; i<strlen; i++){
if(colnum + FONT_WIDTH > LCD_W){
pagenum++;
colnum = 0;
cmd(0xEE); // End of line
cmd(0xB0 | (pagenum % 8)); // Set Page p (Pages 0x00...0x0F)
}
PutChar(pChar[i]);
colnum += (FONT_WIDTH + 1);
}
}
‹#›

16.

Отображение текстовой информации
Пример вывода текста на экран
// String writing example
const char* s = "Lazy quick fox jumped over lazy dog";
PutString(s, strlen(s), 0, 15);
‹#›
English     Русский Rules