Урок 67. Ардуино-библиотека OSD-генератора MAX7456. Описание библиотеки, проблемы некорректной работы, исправленный вариант.

OSD-дисплей

В уроке подробно расскажу об Ардуино-библиотеке для работы с OSD-генератором MAX7456. Представлю исправленный вариант библиотеки, корректно работающий с кириллическими текстами.

Предыдущий урок     Список уроков     Следующий урок

Для программного управления OSD-контроллером MAX7456 в системе Ардуино разработана библиотека MAX7456. Библиотека поддерживает большинство режимов и функций видеоконтроллера, удобна в использовании, работает стабильно.

 

Для использования библиотеки вместе с ней необходимо подключить библиотеку SPI.h и в блоке setup() разрешить работу интерфейса SPI.

#include <SPI.h>
#include <max7456.h>

void setup()
{
SPI.begin();
}

Загрузить библиотеку можно по ссылке max7456-master.zip.

Методы библиотеки MAX7456.

Max7456()

Конструктор. Создает экземпляр класса.

Max7456 osd;  // создаем экземпляр класса Max7456

 

Max7456(byte pinCS)

Конструктор. Инициализирует интерфейс, задает вывод CS.

  • pinCS – номер вывода CS.

Max7456 osd(10);  // создаем экземпляр класса Max7456, CS подключен к 10 выводу

 

void init(byte pinCS)

Функция инициализирует интерфейс, задает вывод для сигнала CS. Должна вызываться до использования других функций. По действию аналогична конструктору Max7456(byte pinCS).

osd.init(10);

 

void setBlinkParams(byte blinkBase, byte blinkDC)

Метод задает временные параметры мигания символов.

  • blinkBase – время мигания (BT);
Значение blinkBase Время мигания (BT), мс
в NTSC режиме в PAL режиме
00 _2fields 33 40
01 _4fields 67 80
10 _6fields 100 120
11 _8fields 133 160
  • blinkDC – параметр, определяющий соотношение времени включен/погашен.
Значение blinkDC Соотношение времени включен/погашен
включен погашен
00 _BT_BT BT BT
01 _BT_2BT BT 2 x BT
10 _BT_3BT BT 3 x BT
11 _3BT_BT 3 x BT BT

В качестве аргументов blinkBase и blinkDC могут быть использованы символьные константы. Они указаны во вторых столбцах таблиц.

osd.setBlinkParams(_6fields, _BT_2BT);

 

void setDisplayOffsets(byte horizontal, byte vertical)

Метод задает смещение информации на экране.

  • horizontal – смещение по горизонтали в пикселях. Может принимать значения от 0 до 63.
Значение horizontal Смещение, в пикселях
0 - 32, смещение влево
32 0, смещения нет
63 + 31, смещение вправо
  • vertical - смещение по вертикали в пикселях. Может принимать значения от 0 до 31.
Значение vertical Смещение, в пикселях
0 + 16, смещение вверх
16 0, смещения нет
31 - 15, смещение вниз

osd.setDisplayOffsets(30,10);

 

void clearScreen()

Метод очищает информацию экрана. Экранная память заполняется нулями.

osd. clearScreen();

 

void activateOSD(bool act=true)

Метод разрешает или запрещает вывод OSD-информации.

  • act = true – OSD разрешен;
  • act = false – OSD запрещен.

osd.activateOSD(true);

 

void activateExternalVideo(bool activExtVid=true)

Метод разрешает или запрещает вывод фонового изображения.

  • activExtVid = true – фоновое изображение разрешено;
  • activExtVid = false – серый фон.

 

void sendCharacter(const charact array, byte x, byte y)

Загружает карту изображения символа в память (EEPROM) знакогенератора.

  • array – массив карты изображения символа (54 байта). Формат массива описан в предыдущем уроке.
  • x – горизонтальная координата символа в памяти знакогенератора.
  • y – вертикальная координата символа в памяти знакогенератора.

Если аргумент y отсутствует, то функция воспринимает параметр x, как адрес символа в памяти знакогенератора.

Тип charact определен в библиотеке как массив размером 54 байта ( typedef byte charact[54];  ).

charact c={0x34,....}
max.sendCharacter(c,5,6); // загрузка карты 5 символа в 6 строке, т.е. адрес 65

max.sendCharacter(c,0x65); // загрузка карты символа с кодом 65

 

void getCharacter(charact array, byte x, byte y)

Метод по сравнению с предыдущим выполняет обратную функцию. Т.е. считывает карту изображения символа из памяти знакогенератора.

  • array – массив для чтения карты изображения символа (54 байта). Формат массива описан в предыдущем уроке.
  • x – горизонтальная координата символа в памяти знакогенератора.
  • y – вертикальная координата символа в памяти знакогенератора.

Если аргумент y отсутствует, то функция воспринимает параметр x, как адрес символа в памяти знакогенератора.

max.getCharacter(c,0x65); // чтение карты символа с кодом 65 в массив c.

 

void print(const char string[], byte x, byte y, byte blink = 0,byte inv = 0)

Метод записывает символьную строку в экранную память MAX7456, т.е. выводит строку на OSD экран.

  • string – строка для отображения.
  • x – горизонтальная координата начала строки в экранной памяти.
  • y – вертикальная координата начала строки в экранной памяти.
  • blink - при значении равном 1 символ мигает.
  • inv - при значении равном 1 символ отображается в инверсном состоянии.

Метод рассчитан на ASCII таблицу кодов символов в памяти знакогенератора, смещенную так, что по адресу 0 размещен символ пробел (' '). При стандартной ASCII кодировке работает неправильно. Ниже я приведу вариант библиотеки, в котором я исправил эту проблему. Также я исправил неприятности с выводом кириллического текста. В исходной версии библиотеки функция print с кириллицей работает не правильно.

max. print(“test”, 8, 1, 0, 0); // печать на экран слова test начиная с 8 символа 1 строки

 

void print(double value, byte x, byte y, byte before, byte after, byte blink=0,byte inv=0)

Метод выводит в экранную память число в формате float.

  • value – значение числа типа float.
  • x – горизонтальная координата начала числа в экранной памяти.
  • y – вертикальная координата начала числа в экранной памяти.
  • before – число цифр до децимальной точки.
  • after – число цифр после децимальной точки.
  • blink - при значении равном 1 символ мигает.
  • inv - при значении равном 1 символ отображается в инверсном состоянии.

При аргументе after равном 0, децимальная точка не выводится.

В исходном варианте библиотеки у функции те же проблемы с кодировкой знакогенератора. Со стандартной кодировкой ASCI I она не работает.

max.print(4.15, 10, 1, 2, 4);  // напечатает 04.1500

 

void printMax7456Chars(byte chars[],byte size, byte x, byte y, byte blink = 0, byte inv = 0)

Метод записывает последовательность символов в экранную память из текстового массива.

  • chars – массив символов.
  • size – число символов.
  • x – горизонтальная координата начала строки в экранной памяти.
  • y – вертикальная координата начала строки в экранной памяти.
  • blink - при значении равном 1 символ мигает.
  • inv - при значении равном 1 символ отображается в инверсном состоянии.

Функция print() работает с текстовыми строками. Она выводит символы последовательно, пока не встретится признак конца строки 0.

Функция printMax7456Chars выводит заданное число символов из массива.

max.printMax7456Chars(ccc, 5,  2,  1); // вывод на экран 5 символов из массива ccc

 

void printMax7456Char(const byte address, byte x, byte y, byte blink=0, byte inv=0)

Запись в экранную память одного символа.

  • address – адрес памяти знакогенератора (код символа).
  • x – горизонтальная координата символа в экранной памяти.
  • y – вертикальная координата символа в экранной памяти.
  • blink - при значении равном 1 символ мигает.
  • inv - при значении равном 1 символ отображается в инверсном состоянии.

max.printMax7456Char(‘S’,  1,  2); // вывод на экран символа S

 

static void printCharacterToSerial(const charact array, bool img = true)

Метод выводит в последовательный порт Serial массив карты изображения символа.

  • array – массив карты изображения символа (54 байта).
  • img – способ отображения:
  • img = true – символ выводится в виде рисунка;
  • img = false – символ выводится в виде массива байт.

 

static void getCARACFromProgMem(const char *table, byte i, charact c)

Метод считывает в массив карту изображения для одного символа (54 байта) из программной памяти.

  • table – указатель на массив данных знакогенератора в памяти программы.
  • i – адрес символа в знакогенераторе (код символа).
  • c – указатель на возвращаемый символ (массив 54 байта).

 

Проблемы работы с библиотекой MAX7456. Исправленный вариант.

Первая проблема заключается в том , что основная функция вывода информации print корректно работает с таблицей знакогенератора, в которой используется кодировка ASCII, но коды смещены так, что символу ‘ ‘ (пробел)  соответствует нулевой адрес, а символу ‘z’ соответствует адрес 0x5a. Также со стандартной кодировкой не работает print(float) для вывода чисел.

Я убрал смещение. Исправленный вариант библиотеки корректно работает со стандартным знакогенератором ASCII.

Вторая проблема – работа функции print с кириллическим тестом. Функция print() неправильно выводит текстовые строки на русском языке.

Я напечатал начало русского алфавита командой osd.print("АБВГДЕЖЗ",6,5);

И вот, что получилось на экране.

Библиотека MAX7456

Не буду подробно описывать последовательность поиска ошибки. Расскажу о результате.

Проблема оказалась в том, что кириллические символы Arduino IDE записывает в текстовые строки, используя кодировку Unicode.

Упрощенно кодировка Unicode выглядит так.

  • Если старший бит байта кода символа равен 0, то остальные 7 битов определяют код символа согласно стандарту ASCII. Т.е. символы с номерами меньше 128 это обычный ASCII текст. В этой области содержатся латинские символы, цифры, математические символы. Все эти символы корректно отображаются в исходной версии библиотеки MAX7456.
  • Если старший бит равен 1, то используется 16 разрядная кодировка символов. В эту кодировку попадают кириллические символы. Т.е. если в текстовой строке встретится русский символ, то он будет представлен 2 байтами.

Я загрузил в текстовый массив кириллические символы "АБВГД", и вывел их в монитор последовательного порта.

char ccc[]= "АБВГД";
for(int i=0; i<10; i++) {
Serial.println(ccc[i], HEX);
}

Вот, что получилось

Окно монитора

  • 0xd090 это код символа ‘А’ в стандарте Unicode;
  • 0xd091 - код символа ‘Б’ и т.д.

Отсюда и вытекает, что каждый кириллический символ отображается, как два символа: ”стрелка вправо” (код 0xd0) и правильный символ.

Я исправил функцию print, сделал в ней конвертацию Unicode в стандартный ASCII 8 битный код.

Исправленную версию библиотеки MAX7456 можно загрузить по ссылке max7456-master_1.zip.

Теперь функция osd.print("АБВГДЕЖЗ",6,5)  работает корректно.

Библиотека MAX7456

В следующем уроке приступим к практическому программированию MAX7456.

 

Научимся создавать и загружать шрифты, выводить информацию на экран.

Предыдущий урок     Список уроков     Следующий урок

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

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