Что такое графический режим
Перейти к содержимому

Что такое графический режим

Видеорежимы

Выделяют два вида режимов работы видеоадаптера, отличающиеся способом формирования видеосигнала: графический и текстовый. Для монитора оба режима одинаковы.

Графический режим

Для графического Gr (Graphics) или АРА (All Points Addressable – все точки адресуемы) режима видеоадаптера характерна возможность индивидуального управления каждым пикселом (точкой или триадой) выводимого на экран изображения. Каждому выводимому пикселу соответствует двоичный код, хранимый в ячейках видеопамяти. Кодированием задают количество цветов, градаций яркости или таких атрибутов, как мерцание, инверсия и др. Для кодирования пиксела используется п битов, которые определяют число возможных состояний пиксела. При выводе цветных изображений число п бит/пиксел называют глубиной цвета. При этом количество отображаемых цветов равно 2п, а размер кадрового буфера видеопамяти, необходимый для хранения цветного изображения с разрешением N х М и глубиной цвета п бит/пиксел, составит N×M×n бит.

В настоящее время используются два цветовых режима:

  • • High Color с глубиной цветов:
    • – 15 бит/пиксел (215 = 32 768 цветов) и распределением битов между базовыми цветами (красным, зеленым и синим) R : G : В = 5 : 5 : 5,
    • – 16 бит/пиксел (65 536 цветов) и распределением битов между базовыми цветами 5:6:5 или 6:6:4;

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

    Ячейки памяти сканируются с частотой кадровой развертки, и за один цикл кадр выводится на экран. Процесс постоянного сканирования видеопамяти называется регенерацией изображения.

    Принцип образования цветовой палитры состоит в том, что путем включения/выключения лучей с одинаковым уровнем яркости при засветке триады основных цветов (красного, зеленого и синего) возможно создание палитры из 23 = 8 цветов. Если дополнительно использовать k уровней яркости для каждого цвета, то количество цветов палитры возрастает до 23к. Кодируемый уровень каждого базового цвета с помощью ЦАП переводится в аналоговый сигнал, который подается на модулятор ЭЛТ.

    В режимах High Color и True Color используется линейная организация видеопамяти, при которой для отображения цвета каждого пиксела на экране задействовано 2 или 3 байта. Растровый формат хранения изображения, при котором пикселы образа изображения на экране отображаются на биты ячеек памяти, называется битовой картой (Bit Мар).

    Битовая карта формируется в видеопамяти графического адаптера под управлением программы, исполняемой центральным процессором. На первом этапе процессор готовит порцию данных, а на втором – передает их в видеопамять по каналу связи. Передача данных от процессора возможна только в те моменты, когда в монитор из видеопамяти не выводятся биты для регенерации изображения. В противном случае данные от процессора попадут на экран и создадут помехи в виде "снега". Существует несколько путей решения этой проблемы:

    • • расширение разрядности шин каналов связи процессор-видеопамять и видеопамять-монитор, что позволит увеличить количество передаваемых бит за один цикл;
    • • использование кэша, что позволит повысить скорость формирования битовой карты;
    • • использование второго кадрового буфера в видеопамяти, что позволит разделить операции записи и считывания данных;
    • • использование двухпортовой видеопамяти, что позволит одновременно записывать и считывать данные;
    • • использование в видеоадаптере собственного специализированного процессора, способного формировать в видеопамяти битовую карту по командам из центрального процессора.

    Графический режим является основным режимом работы видеосистемы современного персонального компьютера, поскольку в нем на экран монитора можно вывести текст, рисунок, фотографию, анимацию или видеосюжет. Для эффективной работы в графическом режиме требуются значительный объем видеопамяти и высокопроизводительный компьютер.

    9. Устройство отображения информации

    Графический режим – это режим с адресацией всех точек экрана, позволяющий получать сложные, цветные и движущиеся изображения и связанный с обработкой процессором больших массивов информации. В этом режиме каждый байт видеобуфера хранит цветные значения одного или нескольких пикселов. Если пиксел кодируется n битами видеобуфера, то на экране одновременно можно наблюдать 2 n цветов. В адаптере CGA графический режим 320´200 использует 2 бита для кодирования цвета пиксела, т.е. на экране одновременно можно наблюдать 4 цвета из 16 цветов палитры. В каждом байте видеобуфера CGA хранятся значения четырех пикселов, причем левый младший пиксел в байте соответствует старшим байтам D7 и D6. В адаптере CGA реализуется прямое соответствие (без преобразования) между битами видеобуфера и пикселами экрана, а адаптерах EGA и VGA – косвенное отображение с использованием 16 регистров палитры, как и в текстовом режиме. На рис. 9.9 показаны схемы отображения содержимого видеобуферов CGA, EGA и VGA на экраны мониторов.

    видеобуфер ® экран CGA

    видеобуфер ® регистры палитры ® экран EGA

    видеобуфер ® регистры палитры ® регистры ЦАП® экран VGA

    Рис. 9.9. Схемы отображения видеобуферов на экраны CGA, EGA, VGA

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

    Хранение значений пикселов в видеобуферах CGA, EGA и VGA выполняется следующим образом (рис. 9.10).

    Рис. 9.10. Представление видеобуферов CGA, EGA и VGA в графическом режиме

    В CGA графические данные хранятся в двух блоках видеобуфера. Первый блок с начальным адресом B800:0000h предназначен для хранения значений пикселов 100 четных строк, а второй блок с начальным адресом B800:2000h – 100 нечетных строк. Видеобуфер VGA и EGA, как уже отмечалось, в текстовом режиме состоит из четырех блоков или двоичных плоскостей 0 – 3, адресуемых параллельно, т.е. адрес относится к четырем байтам соответственно четырех плоскостей. Если в CGA возможен прямой доступ к видеобуферу, то в EGA и VGA непосредственное обращение к видеобуферу исключено. При чтении содержимого видеобуфера VGA (EGA), связанного с выполнением команд MOV, CMP, LODS и т.д., происходит параллельная выборка четырех байтов, которые загружаются в соответствующие регистры‑защелки, т.е. байт из двоичной плоскости 0 загружается в регистр-защелку 0 и т.д. Каждый байтовый срез четырех регистров хранит 4-разрядные значения пиксела. В EGA используется 4 бита для хранения значения пиксела, а в VGA – 8 бит. Регистры‑защелки содержат 8 4-разрядных значений пикселов.

    При выполнении команд MOV, CMP, LODS и т.д., П осуществляет запись данных в видеобуфер при указании в них соответствующего адреса. При этом выполняется параллельная модификация байт во всех четырех плоскостях с учетом содержимого четырех регистров‑защелок и байта данных П. Регистры-защелки представляют собой ортогональную память, допускающую обращение как по байтам, так и по разрядам (пикселам) всех байтов, что упрощает программирование графического режима. Передачами данных между П, регистрами-защелками и видеобуфером управляет графический контроллер со средствами маскирования, реализующий с помощью программно доступных регистров пикселные и байтные операции.

    Как уже отмечалось, графический режим называют режимом АРА (All Points Addressable) с адресацией всех точек. В этом режиме видеопамять хранит битовый образ пикселного представления изображения на экране. Каждый байт видеопамяти хранит значение одного или значения нескольких пикселов, причём нумерация битов и пикселов противоположная, т.е. самому левому, младшему, пикселу соответствуют старшие биты байта. Число одновременно наблюдаемых цветов на экране определяется числом битов, соответствующих каждому пикселу. Так, например, в 16-ти цветном графическом режиме под любой пиксел отводится четыре бита. Если разрешающая способность цветного режима АРА 640´480, то необходимый объем страницы видеопамяти равен

    Характеристики графических режимов адаптера VCA приведены в табл. 9.5.

    Начальный адрес видеопамяти

    Число байтов в странице

    Размер матрицы символа

    Из табл. 9.5 видно, что на рост емкости страницы видеопамяти влияют увеличение разрешающей способности и количество одновременно наблюдаемых цветов.

    Режимы 4, 5 и 6 необходимы для реализации стандартов CGA, а режимы D, G, F и 10 – для поддержания стандарта EGA. Стандарту VGА принадлежат режимы 11, 12, 13, из которых наиболее употребительным является режим 12.

    Видеопамять в зависимости от режима может иметь одну, две или четыре битовых плоскостей. Битовые плоскости иначе ещё называют банками. На рис. 9.11 показана организация видеопамяти в виде четырёх битовых плоскостей (0–3) для режимов D, E, 10, 12 (рис. 9.11, а), двух плоскостей, например, 0 и 2 для режимов 4 и 5 (рис. 9.11, б) и одной плоскости для режимов 6 и 11 (рис. 9.11, в).

    Рис. 9.11. Организация видеопамяти для режимов D, E, 10 и 12а),
    режимов 4, 5 б) и режимов 6 и 11 в)

    При наличии в видеопамяти нескольких битовых плоскостей выполняется их параллельная адресация, т.е. осуществляется одновременная выборка байтов всех плоскостей по одному и тому же адресу и занесение их в регистры-защелки.

    На рис. 9.12 для 16-цветного режима изображена схема связи битовых плоскостей с соответствующими 8-битовыми режимами-защелками R0-R3.

    Рис. 9.12. Схема связи двоичных плоскостей 0-3 видеопамяти с регистрами-защелками R0-R3

    Считанный из битовых плоскостей битовый срез байтов определяет количество одновременно наблюдаемых цветов. Таким образом, цвет пиксела на экране обуславливается четырьмя битами (рис. 9.11, а), двумя битами (рис. 9.11, б) или одним битом (рис. 9.11, в) с учетом шестнадцати 6-битовых регистров палитры атрибутного контроллера, т.е. указанные 4, 2 или 1 бит задают номер цвета в соответствующем регистре палитры. Для двух- или четырехцветного режимов используются первые 2 или 4 регистра палитры. Затем 6-битовое значение выбранного регистра палитры преобразуется в 8-битовый индекс (адрес) для доступа к одному из двухсот пятидесяти шести 18-битовых регистров ЦАП. Каждый 18-битовый регистр хранит определенный цвет и содержит три 6-битовых части, соответствующие красному, зеленому и синему цветам. В регистры ЦАП записывается таблица цветов, которую можно программно изменить.

    В режиме 13 атрибутный контроллер не участвует. В этом случае каждый байт видеопамяти поступает непосредственно в ЦАП для выбора желаемого цвета пиксела с помощью таблицы цветов.

    В адаптере VGA обработку данных, передаваемых между процессором и видеопамятью, выполняет графический контроллер, содержащий 9 регистров, доступ к которым осуществляется через регистр данных (3CFh) и регистр индекса (3CEh), выбирающего желаемый регистр. К числу регистров графического контроллера относятся: регистр установки/сброса (индекс 0), индекс разрешения установки/сброса (индекс 1), регистр сдвига данных (индекс 3), регистр режима (индекс 5) и регистр маски битов (индекс 8).

    Адаптер реализует 3 режима записи и 2 режима чтения из видеопамяти. По умолчанию BIOS устанавливает режим записи 0 и режим чтения 0. При осуществлении режима записи необходимо предварительно в регистры-защелки загрузить текущее содержимое байтов видеопамяти. В регистре режима биты 0-1 задают режимы записи (00 – режим записи 0, …, 11 – режим записи 3), бит 3 указывает на режим чтения (0 – режим чтения 0, 1 – режим чтения 1).

    Рассмотрим выполнение наиболее сложного режима записи 0. Для реализации этого режима секвенсер адаптера содержит регистр маски карты (индекс 2). Секвенсер координирует передачу данных из видеопамяти или графического контроллера в атрибутный контроллер и имеет 5 программно-доступных регистров, обращение к которым выполняется с помощью регистра данных (3C5h) и регистра индекса (3С4h), предназначенного для выбора конкретного регистра по его индексу.

    Регистр маски битов (индекс 8) графического контроллера используется для защиты соответствующих битов регистров-защелок от воздействия содержимого регистра данных процессора, например AL. Если в регистре маске битов разряды D0=D1=D3=0, то в регистрах-защелках запрещается изменение битов D0, D1 и D3. Единичное значение какого-либо бита регистра маски битов разрешает модификацию соответствующих битов в регистрах-защелках.

    Рассмотрим следующий пример. Пусть необходимо представить пиксел коричневого цвета в строке 0 и столбце 1 экрана в режиме записи 0. На рис. 9.13 изображена схема очистки текущего содержимого регистров-защелок. Рис. 9.13 показывает выбор первых байтов в битовых плоскостях видеопамяти по его начальному адресу. Затем в регистре маске устанавливается код 010…0b, маскирующий все биты, кроме шестого, в регистрах-защелках. После этого необходимо выполнить чтение содержимого видеопамяти в регистры-защелки путем выполнения команды MOV AL,ES:[BX], причем содержимое регистра AL здесь игнорируется. После этого в регистр AL заносится нулевое значение и выполняется команда MOV ES:[BX],AL, которая очищает шестой битовый срез в регистрах-защелках (шестые биты в первых байтах двоичных плоскостей (3-0) видеопамяти).

    Рис. 9.14 показывает вывод пиксела коричневого цвета на экран.

    Рис. 9.13. Схема очистки битового среза регистров-защелок
    и фрагмент программы

    Рис. 9.14. Схема вывода пиксела на экран и фрагмент программы

    Вначале устанавливается код 0110 в регистре маски карты, задающий коричневый цвет выводимой точки. Код в регистре маски карты определяет цвет пиксела на экране. После этого любое значение с D6=1 в регистре AL при выполнении команды MOV ES:[BX],AL устанавливает требуемую точку коричневого цвета на экран. Если в регистре маски карты поместить код 0001 или 0010, то это будет соответствовать изображению на экране точки синего или зеленого цвета.

    При выполнении операции записи пиксела в видеопамять необходимо выполнить следующие действия:

    — установить тип графического режима с помощью функции 0 прерывания Int 10h;

    — задать режим записи 0 в регистре режима графического контроллера.

    После этого для осуществления режима записи 0 устанавливается адрес нулевых байтов видеопамяти и устанавливаются биты в регистре маски битов, кроме бита, соответствующего заданному пикселу. Затем выполняется чтение содержимого требуемых битов видеопамяти в регистры-защелки и последующая очистка их битового среза. В заключение производится установка регистра маски карты для задания желаемого цвета и запись точки в видеопамять.

    Здесь следует отметить, что при выполнении процессором команд: MOV RG,VRAM, CMP RG,VRAM или AND RG,VRAM из четырех двоичных плоскостей видеопамяти по одному и тому же заданному в команде адресу видеопамяти извлекаются четыре байта, которые затем автоматически помещаются в соответствующие регистры-защелки.

    Аналогичным образом при выполнении, например, команды: MOV VRAM,RG производится модификация содержимого регистров-защелок и параллельная запись их в битовые плоскости по заданному в команде адресу видеопамяти.

    В режиме записи 0 на формирование данных выводимых из регистров-защелок в битовые плоскости видеопамяти в режимах D, E, 10 и 12 влияет содержимое регистра маски битов, регистра маски карты, регистра установки/сброса, регистра разрешения установки/сброса, регистра данных процессора и регистра сдвига данных (рис. 9.15)

    Рис. 9.15. Структурная схема реализации режима записи 0

    Регистр установки/сброса, содержащий биты В0-В3 по числу регистров-защелок, управляет установкой единичных значений или сбросом в нулевое состояние битов выбранных регистров-защелок. Так, если в регистре установки/сброса бит В3=0 и бит В0=1, то все немаскируемые биты третьего регистра-защелки сбрасываются в нулевое состояние, а немаскируемые биты нулевого регистра-защелки устанавливаются в единичное состояние. Работа регистра установки/сброса координируется регистром разрешения установки/сброса. Если, например, в регистре разрешения установки/сброса бит В3=1, то это соответствует разрешению работы бита В3 регистра установки/сброса.

    Регистр установки/сброса обладает более приоритетным воздействием на значения регистров-защелок, чем регистр маски карты, т.е. разрешенный бит регистра установки/сброса запрещает действие одноименного бита регистра масок карты. Если в регистре маски карты какой-либо бит равен нулю, то этот бит защищает соответствующий регистр-защелку от записи в него значения регистра данных процессора с учетом того, что одноименный бит регистра установки/сброса неразрешен.

    Таким образом, передача содержимого регистра данных процессора осуществляется в немаскируемые биты немаскируемого регистра-защелки с запрещенным сбросом или установкой его битов.

    Более сложные операции над содержимым регистров-защелок выполняются с использованием регистра сдвига данных, в формате которого биты 0-2 определяют количество сдвигов вправо в выбранном регистре-защелке и биты 3-4 задают логические функции И, ИЛИ и исключающее ИЛИ. По умолчанию биты регистра сдвига равны 0.

    Наиболее простым является режим записи 1. В этом режиме содержимое регистров-защелок передается в соответствующие выбранные байты битовых плоскостей видеопамяти без использования дополнительных регистров маскирования. Режим записи 1 наиболее пригоден для организации сдвигов изображения на экране путем считывания байтов битовых плоскостей видеопамяти в регистры-защелки и перезаписи их в видеопамять по новому адресу. На рис. 9.16 показана схема реализации режима записи 1 и фрагмент программы копирования содержимого одной строки в другую.

    Режим записи 1, как и любой другой режим, устанавливается по известной методике, связанной с доступом к регистру режима графического контроллера:

    MOV DX , 3CEh ; задаем регистр индекса

    MOV AL , 5 ; указываем индекс регистра режима

    INC DX ; устанавливаем адрес регистра данных

    Рис. 9.16. Схема реализации режима записи 1 и фрагмент программы
    копирования из одной области VRAM в другую

    В режиме записи 2 младшие четыре бита регистра AL процессора выполняют те же функции, что и разряды 4-битного регистра маски карты в режиме записи 0, т. е. определяют цвет пиксела экрана (рис. 9.17).

    Рис. 9.17. Схема реализации режима записи 2

    Программа установок пиксела заданного цвета на экране в режиме записи 2 почти аналогична программе того же назначения, что и для режима записи 0. В режиме записи 2 может быть использован и регистр установки/сброса (на рис. 9.17 этот регистр не показан).

    В режиме записи 3 байт данных в регистре AL процессора может быть сдвинут вправо на заданное число битов, которое определено в регистре сдвига данных. После этого полученный результат объединяется по И с содержимым регистра маски битов и затем используется в качестве маски битов регистров-защелок. Действие разрешенных битов регистра установки/сброса аналогично действию битов этого регистра в режиме записи 0.

    Адаптер VGA (EGA) выполняет два режима чтения 0 и 1.

    В режиме чтения 0 необходимо заранее установить регистр выбора карты (индекса 4), выбирающий битовую плоскость. Биты 0 и 1 этого регистра задают номер битовой плоскости 0-3 для режима чтения 0. На рис. 9.18 показана схема реализации режима чтения 0.

    Рис. 9.18. Схема реализации режима чтения 0

    Режим чтения 0 или 1 определяется значением бита 3 регистра режима графического контроллера. Для доступа к этому регистру необходимо записать индекс 5 в регистр адреса (порт 3СЕh), а в регистр данных (порт 3CFh) значение бита 3, равное 0 или 1.

    Режим чтения 1 заключается в том, что каждый битовый срез регистров-защелок, считанных четырех байтов из битовых плоскостей 0-3 видеопамяти сравнивается с 4-битовым кодом заданного цвета, предварительно записанного в регистр сравнения цвета (индекс 2). В том случае, если сравниваемые коды совпадают, то в регистре AL процессора соответствующий бит устанавливается в 1, в противном случае – сбрасывается в 0. Таким образом, режим чтения 1 позволяет определить цвет пиксела на экране. Для выполнения этого режима, кроме того, применяется 4-битовый регистр безразличия цвета, позволяющий игнорировать некоторые биты кода цвета. Регистру безразличия цвета присвоен индекс 7, засылаемый в регистр адреса (порт 3CEh). Сброс бита этого режима с помощью порта 3CFh приводит к игнорированию соответствующей битовой плоскости. На рис. 9.19 показана схема выполнения режима чтения 1.

    Графический и текстовый режим дисплеев Winstar

    Графические дисплеи, в том числе и типа OLED, больше всего представленные на нашем рынке фирмой Winstar, имеют куда меньший спрос по отношению к строчным и публикаций по их применению также намного меньше. Между тем, именно графические OLED-дисплеи из-за отсутствия привязки к таблицам шрифтов предопределенного рисунка, предоставляют наилучший способ для получения эргономичных индикаторных устройств для самых разных надобностей. Причем оказалось, что графический режим в контроллере WS0010 иницируется проще и работает стабильнее, чем текстовый.

    Прежде чем перейти к рассмотрению собственно графических дисплеев, рассмотрим вечнозеленую проблему с проблемами включения текстового режима контроллера WS0010, которая получила неожиданное и очевидное решение (ах, где были мои глаза!).

    Решение проблем текстового режима WS0010

    Общеизвестно, что строчные дисплеи Winstar имеют проблемы со стабильностью при инициации. Выяснилось, кстати, что характерно это совсем не только для «проклятых китайцев»: добытые мной с большими трудностями образцы Newhaven Display 16х2, находящейся на другой стороне земного шара, внешне являются полной копией Winstar, за исключением расположения некоторых надписей и названия фирмы на нашлепке (той же формы и с тем же шрифтом):

    image

    Содержащие, как написано в datasheets, некий «LCD comparable» контроллер, эти дисплеи ведут себя совершенно идентично китайским и имеют те же недостатки. Очевидно, на проверку других фирм, вроде Midas, времени тратить не стоит: судя вот по этой публикации, и там без международной кооперации не обошлось. Глобализированная экономика рулез!

    Трудности текстового режима выражаются в том, что при запуске (например, при перезагрузке или ручном ресете программы управляющего контроллера) на дисплеях может появляться мусор, а строки 0 и 1 произвольно меняются местами. Эксперименты показали, что от метода включения (8-ми или 4-х битный) это не зависит. Особенно остро стоит этот вопрос при необходимости периодической софтовой перезагрузки, например, по Watchdog-таймеру.

    Частично проблему решает аккуратное отношение к питанию (от отдельного источника, и ни в коем случае не от USB Arduino), и отдельная перезагрузка через выключение-включение питания дисплея после запуска управляющей программы (см. предыдущую публикацию автора). Как выяснилось, автор этих строк не единственный, кто предлагал подобное решение проблемы: автор надстройки над LuquidCrystal под названием WinstarOLED также включил в нее специальный pw_pin, с помощью которого в момент запуска программы передергивается питание дисплея.

    Но это все, конечно, самодеятельность и полумеры. На радикальный способ натолкнулся некто SeregaB (см. его публикацию на easyelectronics.ru — благодарю Tomasina за наводку). Он вообще-то ставил совсем другую задачу: научиться работать как раз с графическим, а не текстовым режимом. Попытавшись попереключаться между режимами, он быстро обнаружил, что «переключение в графический режим происходило нормально, а из графического в «текстовый» — очень коряво». Тогда он вспомнил, что «когда-то, давным-давно, когда ДШ еще печатали на бумаге, в каком-то из ДШ на HD44780 я читал, что переключение режимов надо делать только при выключенном экране». И все заработало.

    Из цитировавшейся публикации я тут просто воспроизведу две процедуры переключения, несколько адаптировав их под использование совместно с LuquidCrystal (экземпляр класса здесь называется OLED1).

    Переключение в графический режим:

    Переключение в текстовый режим:

    Как мы увидим далее, первая процедура не очень-то и нужна: WS0010 переключается в графический режим с полпинка, достаточно послать в него команду 0x1F. А вот вторая последовательность команд оказалась очень по делу. Для пробы она включалась прямо в скетч с использованием LuquidCrystal в таком виде:

    Затем эта функция вызывалась в setup прямо сразу после инициации библиотеки:

    Если перед этим еще вставить какой-нибудь delay(500), то демонстрация оказывается очень наглядной: после нажатия кнопочки ресета платы Arduino на экране, как обычно появляется мусор, но только на мгновение: после срабатывания функции экран очищается и все строки оказываются на своих местах.

    Функция работает и так, но для удобства я заменил этой последовательностью команд содержимое функции LiquidCrystalRus::clear() в файле модернизированной библиотеки LiquidCrystalRus_OLED.cpp, о которой шла речь ранее (напомню, что скачать ее можно с сайта автора). Ожидания выполнения команды в библиотеке не предусмотрено, потому для надежности после каждой команды там в общем стиле библиотеки вставлены задержки 100 мкс. В скетчах, использующих этот вариант LiquidCrystalRus_OLED, в начале setup обязательно надо вызывать функцию clear(), при этом она заодно и почистит экран.

    Теперь займемся, наконец, графическим режимом.

    Графический режим в текстовых дисплеях WEH001602

    Для начала я попробовал имевшийся у меня текстовый дисплей WEH001602BG переключить в графический режим. Отметим, что у графического 100х16 и текстового (конфигурации 20х2, у 16х2 просто меньше точек по горизонтали) дисплеев идентичные матрицы, только у текстового они разделены промежутками на знакоместа. Это сильно ограничивает применение графического режима в текстовых дисплеях, и еще больше текстового режима в графических. Но для проверки, как это работает, можно использовать любой их них.

    image

    Дисплей вместе с часами DS1307 подключался к Arduino Nano по следующей схеме:

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

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

    Никакой русской таблицы нам здесь не потребуется, потому применяется стандартная (неотрихтованная) LiquidCrystal, которая в графическом режиме работает безупречно. Чтобы не возиться с отладкой всех вариантов библиотеки, в случае, когда включены параллельно текстовый и графический варианты дисплеев, то для каждого я применяю свою библиотеку (для текстового модернизированную Rus_OLED, для графического обычную). Подключение при этом можно все равно делать к одним и тем же ножкам контроллера, за исключением выводов разрешения E, согласно вышеприведенной схеме.

    Далее я частично использовал наработки автора упоминавшейся библиотеки WinstarOLED (сама по себе эта надстройка над LuquidCrystal, на мой взгляд, недоработана, и применять ее as is нецелесообразно). Он ввел удобную функцию установки графического курсора (здесь исправлена ошибка оригинала в части максимального значения x):

    Константа LCD_SETDDRAMADDR определена в библиотеке LiquidCrystal. Дисплей 100х16, как и текстовый, делится на две строки 0 и 1, потому y здесь может принимать только два значения. А горизонтальная координата x варьируется от 0 до 99. По установленной координате командой lcd.write() посылается байт, отдельные биты которого определяют светящиеся позиции вертикальной линии длиной в 8 точек. Крайняя левая позиция в верхней строке имеет координаты 0,0, крайняя правая в нижней — 99,1. Причем верхней точке будет соответствовать младший бит, а нижней точке — старший.

    Для удобства кодирования картинок я расчертил табличку, в которой можно быстро создать нужный код вручную. Для полных таблиц шрифтов, конечно, целесообразно применять специальные редакторы (которых не меньше миллиона разной степени самодеятельности), но 10 цифр с нужным порядком бит быстрее обработать вручную, тем более, что автоматически создаваемые шрифты часто все равно приходится допиливать руками. В соответствии со сказанным выше, глиф, например, цифры 2 шрифтом 10х16 будет кодироваться следующим образом:

    image

    Все это записывается в двумерный массив вида:

    Для каждой цифры 0-9 создается отдельный такой массив Data0, Data1, Data2 и так далее. Для часов, кроме цифр, потребуется еще двойная точка. Ее можно сделать покороче:

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

    Для вывода каждой цифры и отдельно для двойной точки пишется отдельная функция:

    Все функции одинаковые, но используют разные массивы, а для двойной точки и другие пределы цикла. Получилось не слишком экономично в части объема кода (см. об этом далее), зато наглядно и легко править ошибки. Учет промежутков между символами производится на стадии вывода, указанием соответствующей позиции (для чтения часов применяется библиотека RTClib):

    Десять цифр по 20 байт займут в памяти 200 байт — около 10% ее объема (а широкий шрифт 16х16, как в примере ниже, и все 16%). Полный одноязычный шрифт такого размера вместе с цифрами, без учета всяческих знаков препинания и спец. символов, содержит от 62 (английский) до 74 (русский без Ё) символов, значица, займет почти половину оперативной памяти ATmega328. Потому фокусы с массивами и функциями вывода раздельно для каждого символа придется отменить, и делать, как положено. То есть шрифты оставлять в программной памяти и загружать через PROGMEM, а все рисунки глифов оформлять в виде единого массива шрифта, и загружать для вывода по номеру символа в единой таблице. В противном случае и памяти не хватит и код программы раздуется до неуправляемого объема. Здесь мы на этом останавливаться не будем, потому что в наших простых примерах все это не потребуется — мы каждый раз будем ограничиваться небольшим строго необходимым количеством символов.

    Из-за большого размера полного текста скетча GraphicOLED_DC1307 я его не привожу, скачать его можно здесь. В тексте сохранена функция resetOLED, которая передергивает питание дисплея при перезагрузке контроллера (через pwrPin D2), но она ни разу не понадобилась, так что ее можно спокойно удалить. Результат работы программы показан на фото:

    image

    К сожалению, одновременное пребывание в текстовом и графическом режиме исключено, потому, если вы хотите использовать оставшееся место, то придется рисовать свои шрифты (там остается место примерно на 7 символов шрифта 5х7 в каждой строке).

    Графический дисплей WEG010016A

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

    Для проверки текстового режима была загружена программа имитации дисплея часов-календаря с датчиком внешней температуры, описанная в предыдущей публикации. Полученный результат заставил меня вспомнить, что разные дисплеи Winstar могут быть по разному ориентированы относительно разъема (в данном случае у WEG010016A разъем вверху, у текстовых WEH001602B, которые мы применяли выше — внизу, у типа С — вообще сбоку):

    image

    С ориентацией дисплея будем разбираться далее, а пока так посмотрим, что получилось. А получилось ничего хорошего: текстовый режим (разумеется, снабженный костылем, о котором речь шла в начале статьи) работает безупречно, но на практике его применять бессмысленно из-за отсутствия промежутков между символами. Потому не будем на нем задерживаться, а перейдем к рассмотрению графического режима.

    Сами процедуры установки графического режима те же самые, что разбирались выше для текстового варианта. Осталось разобраться с переворотом дисплея, если у него разъем вверху относительно экрана. Конечно, можно, просто перевернуть дисплей, но положение с обращенным вниз разъемом мне кажется более естественным и удобным. Кроме того, при использовании типа с разъемом сбоку может понадобиться ориентировать разъем вправо, а не влево. Для ориентации «вверх ногами» необходимо преобразовать картинку — то есть поменять местами первую и последнюю позиции по горизонтали, строки, а также реверсировать порядок бит в байтах, составляющих массив (при этом младший бит будет соответствовать нижней точке).

    Так как у меня уже были разрисованы десять цифр для предыдущего случая, то для последней задачи оставалось ввести процедуру программной реверсии:

    Поменять порядок следования координат по горизонтали и строк по вертикали можно внесением изменений в функцию setGraphicCursor:

    Функции вывода массива каждой цифры при этом остаются теми же самыми, только добавляется реверсия бит:

    Полный скетч вывода часов GraphicOLED_DC1307_100x16 можно скачать отсюда, а результат для дисплея WEG010016AL представлен на фото:

    image

    А вот на этом фото шрифт другого типа (16х16) на дисплее WEG010016CG (дисплей также перевернут):

    image

    Если вы создадите шрифт заново, поменяв порядок бит вручную, то реверсии делать не надо и программа будет выполняться быстрее (хотя на глаз особых задержек и так не заметно). Но приведенная процедура переворота бит пригодится в любом случае — для отображения различных картинок. Например, из одной стрелки, направленной вверх-вправо, программным путем можно получить сразу четыре направления.

    Картинка и код стрелки (координаты и биты в таблице инвертированы в соответствии с нижним положением разъема для дисплея WEG010016AL, см. выше):

    image

    Функции вывода разнонаправленных стрелок:

    На фото ниже представлен результат программы-заготовки дисплея датчика скорости и направления ветра. Как видите, здесь оказалось очень просто реализовать в одной строке шрифты разных размеров совместно с картинками:

    image

    В заключение добавлю, что вот тут находится очень интересная библиотека для работы с WS0010 в графическом и текстовом режимах по SPI. В текстовом она большей частью копирует Liquid Crystal (а что там еще можно придумать?), а в графическом имеет функции рисования графических примитивов, встроенные шрифты (толстый, как у меня, и обычный 5х7) и еще много всего другого.

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

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