Урок 7 — графическая библиотека для дисплея st7783

Работа с цветными графическими дисплеями TFT (библиотека UTFT)

Библиотека

Поддерживаемые дисплеи

Дисплеи Инициализация
Цветной графический дисплей 2.8 TFT 320х240   Данный дисплей совместим с любыми Arduino.

UTFT myGLCD(TFT01_24SP, 6, 5, 4, 3, 2);

Дисплей можно подключать к любым выводам Arduino указав № выводов при объявлении объекта myGLCD библиотеки UTFT:
UTFT myGLCD(TFT01_24SP, SDI/MOSI, SCK, CS, RESET, DC/RS);

На дисплее установлен преобразователь уровней, так что его можно подключать и к 3В и к 5В логике.

Описание работы с сенсорным экраном находится в разделе Wiki работа с TouchScreen

UTFT myGLCD(TFT32MEGA, 38, 39, 40, 41); // дисплей на чипе ILI9341.
или
UTFT myGLCD(TFT32MEGA_2, 38, 39, 40, 41); // дисплей на чипе HX8357C.

Дисплеи поставляются на базе чипа ILI9341 или HX8357C. Если изображение на дисплее отображается зеркально, то измените тип дисплея: укажите либо TFT32MEGA, либо TFT32MEGA_2.

Если Вы не планируете использовать SD карту, то выводы 50-53 можно использовать для подключения других модулей.

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

UTFT myGLCD(TFT28UNO, A2, A1, A3, A4, A0);

Если Вы не планируете использовать SD карту, то выводы 10-13 можно использовать для подключения других модулей.

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

Описание работы с сенсорным экраном находится в разделе Wiki работа с TouchScreen

UTFT myGLCD(TFT01_24SP, 5, 4, 8, 7, 6);

Дисплей можно подключать к любым выводам Arduino указав № выводов при объявлении объекта myGLCD библиотеки UTFT:
UTFT myGLCD(TFT01_24SP, SDI/MOSI, SCK, CS, RESET, DC/RS);

Уровень логической «1» на входах дисплея ≤ 3,3 В.
Если Вы используете 5 В логику, то подключайте входы дисплея через делители:

При питании от 3,3 В необходимо замкнуть перемычку J1 на обратной стороне платы дисплея.

Если Вы желаете использовать SD-карту, то выводы SD_CS, SD_MOSI, SD_MISO и SD_SCK необходимо подключить к Arduino по аппаратной шине SPI:

Если аппаратный вывод CS(SS) Arduino занят, то вывод SD_CS можно подключить к любому другому выводу Arduino, указав его номер в скетче (см пример в файле image_SD библиотеки UTFT).

TouchScreen можно подключать к любым выводам Arduino указав № выводов при объявлении объекта myTouch библиотеки URTouch:
URTouch myTouch( T_CLK, T_CS, T_DIN, T_OUT, T_IRQ);
Например: URTouch myTouch(13, 12, 11, 10, 9);

Указанные в примере выводы Arduino для подключения TouchScreen пересекаются с выводами аппаратной шины SPI на платах Arduino Uno, Pro Mini, Nano и т.д. Если Вы желаете использовать на этих платах и TouchScreen, и SD-карту , то для TouchScreen нужно выбрать другие выводы Arduino, например, аналоговые выводы A0-A4, указав их в скетче при объявлении объекта:
URTouch myTouch(A0, A1, A2, A3, A4);

Описание работы с сенсорным экраном со встроенным контроллером функций TouchScreen находится в разделе Wiki работа с TouchScreen по последовательной шине данных.

UTFT myGLCD(TFT01_22SP, 5, 4, 8, 7, 6);

UTFT myGLCD(TFT18SHLD, 5, 4, 8, 7, 6);

Дисплей можно подключать к любым выводам Arduino указав № выводов при объявлении объекта myGLCD библиотеки UTFT:
UTFT myGLCD(TFT01_22SP, SDI/MOSI, SCK, CS, RESET, DC/RS);

Уровень логической «1» на входах дисплея ≤ 3,3 В.
Если Вы используете 5 В логику, то подключайте входы дисплея через делители:

Если Вы желаете использовать SD-карту, то выводы SD_CS, SD_MOSI, SD_MISO и SD_SCK необходимо подключить к Arduino по аппаратной шине SPI:

Если аппаратный вывод CS(SS) Arduino занят, то вывод SD_CS можно подключить к любому другому выводу Arduino, указав его номер в скетче (см пример в файле image_SD библиотеки UTFT).

Если Вы собираетесь использовать библиотеку UTFT для работы с другими дисплеями, то закомментируйте строку с названием Вашего дисплея в файле «memorysaver.h». А для экономии памяти, раскомментируйте остальные строки кода файла «memorysaver.h».

#1 Пример

Выводим на дисплей текст тремя базовыми шрифтами:

#2 Пример

Заливаем весь дисплей различными цветами:

#3 Пример

Рисуем различные графические элементы:

Базовые функции:

Все функции:

  • InitLCD([положение]); – Инициирует начало работы с дисплеем. Необязательный параметр может принимать одно из двух значений: PORTRAIT (вертикальная ориентация) или LANDSCAPE (горизонтальная ориентация — по умолчанию).
  • clrScr(); – Очищает дисплей, стирая всю отображаемую на дисплее информацию и заливая дисплей черным цветом.
  • fillScr(color); – Очищает дисплей, стирая всю отображаемую на дисплее информацию и заливая его указанным в качестве параметра цветом фона.
  • getDisplayXSize(); – Возвращает количество пикселей дисплея по горизонтали, число типа int.
  • getDisplayYSize(); – Возвращает количество пикселей дисплея по вертикали, число типа int.
  • setColor(color); – Выбор цвета для текста и фигур, выводимых после данной функции.
  • getColor(); – Возвращает установленный цвет для текста и фигур в формате RGB565, число типа word.
  • setBackColor(color); – Выбор цвета для фона текста, выводимого после данной функции.
  • getBackColor(); – Возвращает установленный цвет для фона текста в формате RGB565, число типа word.
  • setFont(fontName); – Выбор шрифта для текста выводимого после данной функции.
  • getFont(); – Возвращает указатель на выбранный шрифт.
  • getFontXsize(); – Возвращает количество пикселей в одном символе шрифта, по ширине.
  • getFontYsize(); – Возвращает количество пикселей в одном символе шрифта, по высоте.
  • print(str,x,y[,r]); – Вывод на дисплей строк или содержимого строковых переменных.
  • printNumI(int,x,y[,len[,sym]]); – Вывод на дисплей целого числа или содержимого целочисленной переменной.
  • printNumF(float,dec,x,y[,sym1[,len[,sym2]]]); – Вывод на дисплей вещественного числа или содержимого переменной вещественного типа
  • drawPixel(x,y); – Вывод на дисплей точки. Цвет точки определяется текущим значением цвета, устанавливаемым командой setColor().
  • drawLine(x1,y1,x2,y2); – Вывод на дисплей линии, заданной координатами двух точек.
  • drawRect(x1,y1,x2,y2); – Вывод на дисплей прямоугольника, противоположные углы которого заданы координатами двух точек.
  • drawRoundRect(x1,y1,x2,y2); – Вывод на дисплей прямоугольника со скругленными углами.
  • fillRect(x1,y1,x2,y2); – Вывод на дисплей закрашенного прямоугольника.
  • drawCircle(x,y,R); – Вывод на дисплей окружности, определяемую координатами центра и радиусом.
  • fillCircle(x,y,R); – Вывод на дисплей закрашенной окружности.
  • drawBitmap(x1,y1,x2,y2,data[,scale]); – Вывод на дисплей картинки из массива.
  • Для вывода на дисплей картинки из файла с SD-карты нужно вызвать функцию load(x1,y1,x2,y2,data); объекта библиотеки UTFT_SdRaw.
    Для работы функции load, нужно установить и подключить библиотеки: UTFT_SdRaw и SdFat.

Инициализация работы с дисплеем:

InitLCD(PORTRAIT); // инициализация (вертикальное положение)

Очистка экрана:

clrScr();
Очистка экрана с заливкой дисплея чёрным цветом
Параметр: Без параметров.
fillScr( color );
Очистка экрана с заливкой заданным цветом.

fillScr(VGA_RED); // красный цвет

Выбор цвета:

setColor(0,0,255); // синий цвет

setBackColor(2016); // зелёный цвет

Удобнее всего устанавливать цвет по его названию:
Полный перечень цветов: VGA_BLACK, VGA_WHITE, VGA_RED, VGA_GREEN, VGA_BLUE, VGA_SILVER, VGA_GRAY, VGA_MAROON, VGA_YELLOW, VGA_OLIVE, VGA_LIME, VGA_AQUA, VGA_TEAL, VGA_NAVY, VGA_FUCHSIA, VGA_PURPLE, VGA_TRANSPARENT.

Выбор шрифта:

setFont(SmallFont); // маленький шрифт

Вывод текста:

print(«iarduino», 50, 50); // текст «iarduino» горизонтально
print(«iarduino», 50, 50, 90); // текст «iarduino» вертикально

printNumI(2000,50,50); // результат: «2000»
printNumI(2000,50,50,0); // результат: «2000»
printNumI(2000,50,50,5); // результат: » 2000″
printNumI(2000,50,50,6,’0′); // результат: «002000»

printNumF(-234.3442,2,50,50); // результат «-234.34»
printNumF(-234.3442,3,50,50); // результат «-234.344»
printNumF(-234.3442,4,50,50,’*’); // результат «-234*3442»
printNumF(-234.3442,1,50,50,’,’,1); // результат «-234,3»
printNumF(-234.3442,1,50,50,’,’,7); // результат » -234,3″
printNumF(-234.3442,1,50,50,’,’,7,’0′); // результат «-0234,3»

STM Урок 7. HAL. LCD 20×4. 4-битный режим. Выводим информацию

Урок 7

HAL. LCD 20×4. 4-битный режим. Выводим информацию

Сегодня мы продолжим работать с дисплеем 20×4, с которым мы начали работать на прошлом занятии. Мы написали инициализацию и проверили работу кода на практике.

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

Для этого сначала пишем функцию для записи данных в дисплей, она немного будет отличаться от команд (только лишь лапкой rs )

void LCD_Data(uint8_t dt)

Еще напишем функцию очистки дисплея

Также, собственно, напишем функцию вывода символа на дисплей

void LCD_SendChar(char ch)

Сделаем ее видимой, написав прототип в lcd.h.

И попытаемся наконец вывести какой то символ в главной функции программы

Прошьем и посмотрим

Попробуем еще что то вывести на экран

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

void LCD_String(char* st)

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

Сначала объявим массив и проинициализируем

/* USER CODE BEGIN 1 */

char str[] = «Stm32F407VG»;

/* USER CODE END 1 */

Затем вызовем функцию, а посимвольный вывод пока закомментируем

Соберём код, прошьём контроллер и посмотрим результат

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

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

Для этого заглянем в даташит (открыв специализированный для LCD2004)

Мы видим там (на стр. 8), что строки имеют свои адреса в памяти DDRAM и все символы также:

А каждый символ будет смещением относительно начала строки.

Поняв это, пишем функцию позиционирования по столбцу и строке

void LCD_SetPos(uint8_t x, uint8_t y)

Не забываем про прототип.

Попробуем что-нибудь написать в другую позицию.

Изменим код в main.c следующим образом. Сначала объявим по другому (без инициализации) строковый массив

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

Затем изменим код вывода

sprintf(str, «ARM mc»);

Также наш дисплей должен уметь полностью очищаться. Для этого пишем функцию очистки.

Для нее также нужен будет прототип.

Попробуем после некоторой задержки очистить наш экран

sprintf(str, «ARM mc»);

Прошьем и посмотрим. В видеоверсии, прикреплённой внизу урока, это будет нагляднее, поэтому здесь не показываю.

Добавим переменную в main() и напоследок немного поприкалываемся

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

sprintf(str, «ARM mc»);

/* USER CODE END 2 */

Также добавим код в бесконечный цикл

/* USER CODE BEGIN WHILE */

LCD_SendChar((char) ((i/100)%10) + 0x30);

LCD_SendChar((char) ((i/10)%10) + 0x30);

LCD_SendChar((char) (i%10) + 0x30);

LCD_SendChar((char) (((i+250)/100)%10) + 0x30);

LCD_SendChar((char) (((i+250)/10)%10) + 0x30);

LCD_SendChar((char) ((i+250)%10) + 0x30);

LCD_SendChar((char) (((i+500)/100)%10) + 0x30);

LCD_SendChar((char) (((i+500)/10)%10) + 0x30);

LCD_SendChar((char) ((i+500)%10) + 0x30);

LCD_SendChar((char) (((i+750)/100)%10) + 0x30);

LCD_SendChar((char) (((i+750)/10)%10) + 0x30);

LCD_SendChar((char) ((i+750)%10) + 0x30);

/* USER CODE END WHILE */

Ну и уж совсем на посошок уберем надоедливую черную мигалку (или курсор). Для этого меняем только одну букву в инициализации

LCD_Command(0x28);//режим 4 бит, 2 линии (для нашего большого дисплея это 4 линии), шрифт 5х8

LCD_Command(0x28);//еще раз для верности

LCD_Command(0x0 C );//дисплей включаем (D=1), курсоры никакие не нужны

LCD_Command(0x02);//возврат курсора в нулевое положение

Вот что у нас получилось (соответственно, в видеоверсии смотреть лучше)

Отладочную плату и дисплей LCD 20×4 можно приобрести здесь:

Смотреть ВИДЕОУРОК

36 комментариев на “ STM Урок 7. HAL. LCD 20×4. 4-битный режим. Выводим информацию ”

Большое спасибо за урок! Мне, как начинающему, все понятно. Пошел «зашивать».

Значит не зря стараюсь.

Конечно не зря! Даже у меня получилось, хотя я и не программист, а электронщик и Ваш LCD – вторая программа после мигания светодиодами и очень нужна для серьезной работы, а времени и опыта что-то самому писать нет. Дальше буду осваивать ADC по вашим урокам. Заранее огромное спасибо!

С выводом 15 промахнулись, когда рисовали схему, и подключили к RS вместо VDD. И 330 ом многовато. Лучше 10 ом.

Уважаемый – Ваши уроки это супер! Спасибо большое за труд и старания!

Хотелось бы спросить:

В прошлом уроке ее небыло. Или я что-то не правильно понял?

Спасибо за оценку!
Да вроде должна быть, иначе как мы старшую тетраду передадим.

Добрый день. Спасибо за ответ. Я пока к практике не перешел (Сижу проводочки паяю ))))

На сколько я понял мы вызываем эту процедуру:

void LCD_WriteData(uint8_t dt)

поидее строка: LCD_WriteData(dt>>4); будет равно вот этому условию: if((dt&0x01)==1) else ? Если так – то почему не в таком виде: if(((dt >> 4)&0x01)==1) else ? Я еще не силен в СИ, в основном BASIC и ASSEMBLER(совсем чуть чуть). Спасибо заранее.

И еще хотелось бы спросить – а будет урок посвященный работе со встроенными RTC? Спасибо еще раз за громадную проделанную работу.

Добрый день. РАЗОБРАЛСЯ )))))))))) Почитал еще основные математические действия ) и все понял ). Я изначально не так понял эти строки:

Теперь стало все понятно )))) Еще раз спасибо за подробные уроки!

Здравствуйте! Для начала хочю сказать спасибо за Вашы уроки! Очень подробно все описываете, такого больше нигде не встречал!

Нужна Ваша помощь по одному вопросу.

Заказал я как-то из Китая дисплей 1602. Он пришел, я подпаял разъем для подключения контактов, подал питание и засветилась первая строка, все вроде как должно быть. Только вот после инициализации вместо того, чтобы символы показывать светится две строки заполненные прямоугольниками. Единственное что их немного хуже видно чем одну строку до инициализации. Пробовал подключать и от 5В, и от 3,3В, брал и Mega16 и STM32F030C8T6, результат тот же – две строки с прямоугольниками. Пробовал и инициализировать по разному, смотрел код инициализации на разных сайтах, в разных даташитах, ничего не получается. Похоже что бракованный пришел.

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

Так вопрос вот в чем: как считаете, это реально брак, или можно с ним еще что-то сделать?

Спасибо за оценку ресурса!

Скорее всего, всё-таки брак. Глюки программной части проявляются немного не так.

У меня был подобный дисплей, на котором я нечаянно перепутал полюса питания и он после этого вёл себя приблизительно так же. Только правда он половину своего экрана заполнял символами, а половину – закрашенными прямоугольниками. А вообще, чтобы точно вынести вердикт, что это не глюк прошивки, нужно подключить такой же, только заведомо годный, в смысле не по другому интерфейсу, а именно по параллельному.

Спасибо вам огромное за проделанный труд!Еще никто так подробно не разжевывал библиотеку НАL…хочется ещё каких нибудь уроков например по энкодеру,разным режимам ШИМ.Еще раз спасибо!

Дисплеи ST7735 и ST7789. Подключаем к ESP8266, выводим изображение без SD карты.

Недавно заказал с алиэкпресс интересный экран, достаточно маленького размера, всего 1.44 дюйма, но обладающий разрешением 240х240 пикселей на матрице IPS, и обладающий SPI контроллером ST7789, т.е. его можно подружить с библиотекой Adafruit. Появление таких качественных экранов по бросовой цене, могу объяснить только тем, что возможно их сделали огромную партию под какие-нибудь смарт-часы или похожие устройства.

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

Открываем пример graphictest, который появится у нас после добавления библиотеки, и видим много ifdef, для разных чипов, и вариантов подключений. Я эти куски сразу почистил, до лаконичных выводов, которые мне нужны. Собственно, какую-то часть менять не нужно, так как она завязана на аппаратный SPI

Тут я всё понял, когда посмотрел на выводы дисплея, ведь зашитая на спех программа ничего не отобразила на дисплее. Причину нашёл быстро, ведь я никуда не подключил вывод CS. Стоп, а где он?

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

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

Но там его не оказалось, и остался вариант сложнее – полностью отпаять шлейф экрана, что было не просто, ведь его легко порвать. Кстати теперь сам дисплей можно использовать в своих устройствах без этой синей площадки. Распаять его достаточно легко на свою плату, изготовленную ЛУТом например, шаг выводов позволяет.

Контакт этот я срезал ножом, что он не контактировал с контактом GND, это делать нужно тоже аккуратно.

Теперь запаиваем обратно шлейф матрицы, и к выводу CS припаиваем уже свой провод, который можно подключить в ESP8266.

Итоговая схема подключения дисплея на ST7789 (и ST7735) получилась такая

Ещё раз пройдёмся по коду из примера graphictest из библиотеки st7789 и st7735

Как я писал выше, я убрал все замены ifdef, и оставил выводы, которые точно буду использовать (выше в статье). ЗАтем закомментировал ненужный контроллер, и раскомментировал тот, что установлен в этом дисплее

Также раскомментировал строку, с разрешением, которое мне нужно. Остальные удалил

Вот теперь, при подключённом выводе CS демка сразу заработала. Значит нам доступны все функции библиотек adafruit_gfx. Скорость работы намного выше, чем у AVR.

Чтобы оценить качество экрана в полной мере, лучше вывести изображение, обычно это делается с micro-sd карты, но в самом экране её нет (хотя у adafruit вроде есть версии с флеш-слотом). Вспомнив, что у ESP8266 достаточно много собственной памяти для программ, решил попробовать записать изображение в память программы. Для этого можно воспользоваться ссылкой

Загружаем картинку нужного разрешения, и конвертируем в *.с файл. Далее, я чищу header этого файла, переименовываю в *.h, кладу в папку с проектом, и подключаю командой

Файл очень большой, и когда он лежит в проекте занимает много места. Каждый пиксель описывается в 16 битной цветовой гамме, и это конечно избыточно, замедляет вывод изображения. В самом файле картинки нас интересует переменная памяти программ, я назвал её DogBitmap

Теперь простой командой из библиотеки adafruit можно вывести её на экран

Где, первые два аргумента (0,0) – это стартовая позиция отрисовки, потом имя нашей переменной, и затем размеры изображения по ширине и высоте (240х240). Смотрим результат. Картинку я взял из известных стикеров Вконтакте.

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

Урок 7 — графическая библиотека для дисплея st7783

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

ЧТО ТАКОЕ И С ЧЕМ ЕГО ЕДЯТ!

Наблюдая за тем, как мой друг увлеченно работает с «Ардуино», сам решил освоиться с данными девайсами. Посмотрев разнообразие модулей, и перечень микроконтроллеров, которыми «заряжены» ардуино-боарды, удивился тем, что на них стоят Atmel-камни. Меня честно порадовало Arduino Mega2560 и особенно Arduino Due c микроконтроллером ATSAM… . Кстати, на руках оба девайса.
Так дошло получилось, что это первый TFT-экран с которым я начал работать. Размер небольшой – всего 480х320 3.2 дюйма + отсутствует сенсор, и конечно по сравнению с экранами на контроллере SSD1963 (4.3’, 5.0’, 7.0’) — он маленький. Использовать библиотеку UTFT не составило сложности, и потратив некоторое время по набиванию кода в среде arduino-IDE 1.6.0, я разобрался с основными механизмами по выводу графики и текста на экран. Понравился тот факт, что среда поддерживает С++, и что самое замечательное – библиотека UTFT (и остальные ее производные), написаны на С++. Это дает всю гибкость программирования.
Собственно что качается радиотехнической части дисплея, то он не сенсорный, имеет 16-разрядную шину данных и линии управления.

Так же на борту имеется слот для подключения флэш-карточки. Угол обзора довольно приличный — на 50-60 изображение не мутнеет.
Вобщем кратко обрисовал небольшое вступление и теперь перейдем к основному вопросу — как вывести кирилицу на экран используя библиотеку UTFT. Основная плата процессора при осуществлении доработки библиотеки — Arduino Mega2560.

РЕШЕНИЕ ЗАДАЧИ

Основная идея заключается в следующем:

1. Добавить в файл DefaultFonts.c (каталог UTFT) таблицу с символами и кирилическими буквами — имя массива BigFontRus (можно любое название).

2. Написать два массива в файле реализации UTFT.cpp: первый массив содержит символы и кирилические буквы, второй массив содержит десятичные числа, по которым собственно и будет извлекаться символ из таблицы символов BigFontRus.

3. Добавить функцию tftChar, в которой будет реализован основной механизм определения символа и буквы кирилицы с последующим выводом его на экран TFT.

Теперь по порядку разъясню что к чему. По каждому пункту буду расписывать более подробно насколько сам освоил данный материал. И так:

По пункту 1. имеем — вывод символом осуществляется соответственно из файла DefaultFonts.c, но можно и другой файл создать, например RusFont.c и поместить туда таблицу символов и букв — в любом случае необходимо в программе указать шрифт, а откуда он берется не имеет значение. Ну и есть нюанс — символы, т.е. байты символом в массиве расположены несколько по иному — символ разделен попалам и половинки развернуты. На рисунке видно о чем речь (размер символа 16х16):

Так что рисовать шрифты в таком виде обернется большой рутиной. Необходим софт, который позволит конвертировать «правильный символ» в перевернутый. Лично такую утилиту не видел, но при должном понимании ее можно сваять самому.

По пункту 2. имеем — два массива соответственно с символами и байтами. Код этих массивов имеет вид:

С символами все понятно. Что же за цифры во втором массиве и почему начинаются с 32 по 135? Ответ: в таблице символов указано смещение 0х20 и оно как раз 32. Соответственно символы начинаются с 32-й позиции. Но это не проблема, можно поменять смещение на 0х00 и переписать массив байтов начиная с 0 по 103. Решил не переделывать :). Как используются данные массивы разъясню ниже.

По пункту 3. имеем — собственно так сказать СЕРДЦЕ всего содеянного с библиотекой UTFT. В методе tftChar осуществляется механизм определения символа и вывод символа из таблицы на экран посредством штатного метода printChar. Реализация метода tftChar имеет вид:

Такую реализацию я уже делал в несколько простом исполнении в статье доработка библиотеки lcd.h среды CodeVisionAVR 3.12. Собственно эту идею я использовал и здесь, и в библиотеке LCD5110_Graph, но о ней будет другая статья. И так по порядку — метод tftChar принимает три параметра:

— Символ (с). Это тот самый кирилический символ, который необходимо вывести.
— х координату вывода символа.
— y координату вывода символа.

Вся работа выолняется в цикле While, условием выполнения которого является несовпадение поступившего символа с с элементом массива character_rus — таким образом осуществляется поиск символа в массиве. Соотвественно при работе цикла происходит инкремент счетчика s. Счетчик позволяет перемещаться по элементам двух массивов. Выглядит это таким образом — пока символ с не совпадает с символом из массива, цикл работает, счетчик s инкрементируется до тех пор, как только символ найдется и далее по счетчику находим байт, и отправляем его в метод printChar. Если символ не нашли, то соответственно счетчик достигает максимального значения, при котором цикл завершается и условие if не выполняется. С помощью счетчика i умножив на ширину символа мы задаем шаг вывода символов, т.к. ширина 16 пикселов, то соответственно через 16 и должны выводить, иначе будет визуальный дефект «слипших символов». И если вы вдруг решите сделать свой шрифт, скажем размером 32х32, то в таблице символов (DefaultFonts.c) необходимо задать размер символа во избежании проблем с выводом. И еще один момент — условие if помагает избавиться от отображения мусора, который меня долгое время мучил и я не понимал почему так происходит. Оператор if меня избавил от этой напасти!
Думаю покумекав можно разобраться что к чему 😉

Проверить символы (с выбраным шрифтом соответственно в основном скетче среды) в файле DefaultFonts.c можно таким образом:

Параметром являются числа, которыми являются позиции символов в таблице. Это числа от 32 по 135 при задании шрифта BigFontRus. И вообще, таким образом можно проверять любые таблицы с символами.

РЕШЕНИЕ ЕЩЕ ОДНОЙ ЗАДАЧИ. ВЫВОД СТРОК

Теперь самое интересное — как выводить строки при помощи указателя и собственно параметром метода? Для начала какие методы нужно дописать в классе UTFT в файле UTFT.h. Методы имеют вид:

Первый метод позволяет выводить строки из указателя, т.е. так —

char *dht = «Влажность,%» ;
//и далее собственно
g.textRus(dht, 0, 19);

Второй метод позволяет выводить строки с указанием в параметре, т.е. так —

g.textRus( «Напряжение,В» , 0, 19);

Третий метод позволяет выводить символы из массива символов, которые предварительно прописаны в основном скетче программного проекта, т.е. так —

sizeof(dht) — указываем размерность массива (параметр length). Этот метод можно вообще удалить, но я не стал, оставил для каких либо нужд. Вообще этот метод я реализовал решив, что другого способа вывода кирилицы не найдется, т.к. через указатель долгое время не получалось осуществить вывод — вместе с символами отображался «мусор». Поэтому очаявшись хотел поставить на указателях крест, применив данный метод, даже утилитку сваял в среде Visual Studio 2008 C# для создания массива символов:

Ну и конечно собственно методы вывода строк, о которых я писал выше имеют такой вид:

Метод void UTFT::textRus(char *st, int x, int y) принимает указатель на строку и все действо происходит в цикле, и пока не «попадется» символ нуль-терминатора каждый символ по инкременту указателя *st будет передаваться в метод tftChar. По окончанию цикла обнуляем счетчик i.

С методом void UTFT::textRus(String st, int x, int y) я особо не заморачивался и взял готовую реализацию из библиотеки.

На доработку библиотеки по выводу кирилицы я потратил где-то две недели, и когда мне все-таки удалось реализовать все «по-человечьи», я осознал, что мог это сделать за пару дней 🙂 «. мысля приходит опосля. «

Так выглядит физическая часть доработки. Качество фото конечно не лучшее.

Программирование дисплея на контроллере ST7920

Здравствуйте, я хочу рассказать о программировании дисплея на контроллере ST7920 с использованием ATtiny2313 контроллера.

Характеристики дисплея

Приблизительная цена: 15$
Размер дисплее вместе с платой: 93.0 (Длина) × 70.0(Ширина) × 13.50(Высота) мм
Размер видимой области: 70×38 мм.

Дисплей имеет 2 режима работы:

  • Графический
  • Текстовый

В текстовом режиме дисплей имеет 4 строки и 16 знакомест на строку
В графическом режиме разрешение: 128×64 пикселя.

3 режима подключения:

  1. Подключение по 8 битной шине
  2. Подключение по 4 битной шине
  3. Подключения по SPI (3 битной шине)

Имеются 2 режима работы:

  • Нормальный: потребление 450 мкА, 5 В
  • Спящий режим: потребление 30 мкА, 5 В

В данном посте я расскажу о:

  • Работе в текстовом режиме
  • Подключения и программирование по 8 битной шине
  • Подключения и программирование по SPI

Для того что бы подключить дисплей к контроллеру нам понадобится:

  1. Дисплей на контроллере ST7920
  2. 2 подстрочных резистора на 10 кОм.
  3. Для 8 битного режима резистор на 4.7 кОм (или больше)
  4. Контроллер ATtiny2313
  5. Источник питание на 5В.

Схема подключения

Подключение по 8 битной шине данных


Распиновка контактов:
GND — Земля
VCC — +5В
V0 — Настройка контрастности
RS — Определяет режим передачи данных (1 — это данные, 0 — это команда)
RW — Запись или чтения (1 — чтения, 0 — запись)
E — Строб
D0-D7 — Шина данных
PSB — Определяет какой протокол передачи данных будет использоваться ( 1 — 8/4 бит шина, 0 — SPI)
BLA — Анод подсветки (+)
BLK — Катод подсветки (-)

На схеме DB0-DB7 и PB0-PB7 не замкнуты, это 8 битная шина данных.
Реальное соединения таково:
DB0 — PB0
DB1 — PB1
DB2 — PB2
DB3 — PB3
DB4 — PB4
DB5 — PB5
DB6 — PB6
DB7 — PB7

Подключение по SPI


Распиновка контактов:
GND — Земля
VCC — +5В
V0 — Настройка контрастности
RS — (CS) Начало/окончание передачи данных (1 — начало, 0 — окончание)
RW — (SID) Шина данных
E — (SCLK) Строб
PSB — Определяет какой протокол передачи данных будет использоваться ( 1 — 8/4 бит шина, 0 — SPI)
BLA — Анод подсветки (+)
BLK — Катод подсветки (-)

Подстроечные резисторы

RP1 — Регулятор контрастности
RP2 — Регулятор яркости

Описание протоколов программирования дисплея

8 битный режим

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

Давайте рассмотрим пример того как производится инициализация для 8 битного режима.
Давайте рассмотрим пример того как производится инициализация:

  • Задержка в 50 мкс.
  • Отправляем команду установки 8 битного режима.
  • Задержка 120 мкс.
  • Отправляем команду включения дисплея ( в ней же указывается, включить ли курсор, и мигать ли курсором)
  • Задержка в 50 мкс.
  • Повторно отправляем функцию установки 8 битного режима
  • Задержка 120 мкс.
  • Отправляем команду отчистить экран
  • Задержка 20 мкс.
  • Устанавливаем ENTRY MODE (эта команда говорит о том в какую сторону сдвигать курсор после написания символа, нам соответственно нужно вправо)

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

Рассмотрим как отправить одну команду на дисплей в 8 битном режиме:

  • Устанавливаем низкий уровень E
  • Устанавливаем низкий уровень RS
  • Устанавливаем низкий уровень RW
  • Задержка 1 мкс.
  • Устанавливаем высокий уровень E
  • Отправляем в порт данных байт команды
  • Задержка 1 мкс.
  • Устанавливаем низкий уровень E
  • Задержка 50 мкс.

Для отправки одного байта данных выполняется абсолютно то же самое, только в начале устанавливается высокий
уровень RS.
RS = 0 Команда
RS = 1 Данные

Вот как отправляется один байт данных:

  • Устанавливаем низкий уровень E
  • Устанавливаем высокий уровень RS
  • Устанавливаем низкий уровень RW
  • Задержка 1 мкс.
  • Устанавливаем высокий уровень E
  • Отправляем в порт данных байт команды
  • Задержка 1 мкс.
  • Устанавливаем низкий уровень E
  • Задержка 50 мкс.

Давайте рассмотрим код отправки команды
Для начала установим константы что бы было удобнее:

Функция отправки команды:

Функция отправки данных:

В коде был использован макрос LCD8_MACRO_DELAY, вот его код

Теперь рассмотрим команды инициализации дисплея в текстовом, 8 битном режиме:

Команда FUNCTION SET: 0 0 1 DL 0 RE 0 0
DL:

  • Если установлено 1 то устанавливаем 8 бит передачу данных
  • Если установлено 0 то устанавливается 4 бита передача данных

RE:

  • Если установлено 1 то устанавливается набор расширенных команд
  • Если установлено 0 то устанавливается набор базовых команд

Следующая команда это DISPLAY STATUS: 0 0 0 0 1 D C B
D:

  • Если установлено 1 то дисплей включен
  • Если установлено 0 то дисплей выключен

С:

  • Если установлено 1 то курсор включен
  • Если установлено 0 то курсор выключен

B:

  • Если установлено 1 то курсор будет мигать
  • Если установлено 0 то курсор не будет мигать

Следующая команда простая CLEAR – отчистка экрана: 0 0 0 0 0 0 0 1

И последняя команда это ENTRY MODE SET – установка направления движения курсора: 0 0 0 0 0 1 I/D S

  • Если I/D = 1 то курсор сдвигается вправо
  • Если I/D = 0 то курсор сдвигается влево

На основе этих четырех команд можно написать функцию инициализации дисплея:

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

Режим SPI

Теперь о функции приема передачи команды/данных по SPI.
В этом режиме участвуют 2 линии:

  • SID это контакт передачи данных, на дисплее он же RW
  • SCLK – это линия строб, на дисплее он же E
  • CS – это начала/окончания передачи данных, на дисплее он же RS

В SPI режиме передача одной команды или 1 байта данных происходит при передачи 24 бит
Протокол передачи данных таков:

  • Устанавливаем высокий уровень CS
  • Передаем 4 единицы подряд
  • Передаем 1 бит RW – чтения или запись
  • Передаем 1 бит RS – Команда или данные
  • Передаем 0
  • Передаем 4 бита старшей половины байта данных
  • Передаем 4 нуля
  • Передаем 4 бита младшей половины байта данных
  • Передаем 4 нуля подряд
  • Устанавливаем низкий уровень CS

На этом передача одного байта завершена.

После каждого переданного бита делается строб, то есть:

  • Задержка 1 мкс.
  • Устанавливаем высокий уровень SCLK
  • Задержка 1 мкс.
  • Устанавливаем низкий уровень SCLK
  • Задержка 1 мкс.

Рассмотрим функцию передачи команды/данных в режиме SPI, но сперва объявим константы:

А теперь сама функция:

Текстовый режим

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

И на дисплее вы увидите букву A.

И так, теперь о том как устроенно адресное пространство в текстовом режиме:
Экран делится на 8 столбцов и 4 строки, в каждый столбец вы можете записать по 2 обычных символа или 1 иероглиф.
Адресное пространство находится от 0 до 31.

1 2 3 4 5 6 7
16 17 18 19 20 21 22 23
8 9 10 11 12 13 14 15
24 25 26 27 28 29 30 31

Как видите первая строчка это адреса от 0 до 7
Вторая же строчка от 16 до 23
Третья строчка от 8 до 15
То есть если вы напишете 16 букв подряд с адреса 0, то они будут в первой строчке,
но если вы напишите 17 символов, то последний символ будет не на второй строчке, а на третей!

Есть специальная команда установки адреса курсора: 1 AC6 AC5 AC4 AC3 AC2 AC1 AC0
С помощью этой команды можно поставить курсор в нужное место вписав за место AC0-AC6 адрес от 0 до 31.

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

И напоследок, для тех кто хочет использовать графический режим, есть такая статья: LCD 12864 на контроллере ST7920. Параллельный режим (8 бит)

Урок 7 — графическая библиотека для дисплея st7783

Библиотека TFT включена в среду разработки Arduino IDE, начиная с версии 1.0.5.

Данная библиотека позволяет Ардуино взаимодейстовать с модулем, содержащим TFT LCD-экран. Функции библиотеки значительно упрощают процесс вывода на экран различных фигур, линий, изображений и текста.

Библиотека Arduino TFT разработана на основе библиотек Adafruit GFX и Adafruit ST7735, и значительно расширяет их возможности. Библиотека GFX в основном содержит процедуры отрисовки графики, в том время, как ST7735 — функции для взаимодействия с TFT-экраном. Все дополнения библиотеки, касающиеся Ардуино, спроектированы таким образом, чтобы обеспечивать API-режим работы с экраном.

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

Многие методы библиотеки TFT, работающие с экраном и SD-картой памяти, опираются на функции библиотеки SPI. Поэтому, для нормальной работы программ, взаимодействующих с TFT-экраном, треубется объявление модуля SPI.h.

Использование библиотеки

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

Если на TFT-модуле планируется использование SD-карты памяти, то взаимодействовать с модулем необходимо только через аппаратный интерфейс SPI. Он используется во всех примерах к данной библиотеке.

На Arduino Uno при использовании аппаратного SPI в программе необходимо объявить номера выводов CS, DC и RESET. Выводы MOSI (11) и SCLK (13) заданы по умолчанию.

Для использования аппаратного SPI на Arduino Leonardo, необходимо объявить эти выводы следующим образом:

Для работы с TFT-экраном через программный интерфейс SPI можно использовать любые не занятые выводы. В этом случае, помимо CD, DC и RESET, в программе необходимо объявить номера выводов MOSI и SCLK:

Использование библиотеки TFT на Arduino Esplora

В Arduino Esplora предусмотрен отдельный разъем для подключения TFT-экрана, поэтому выводы, взаимодействующе с ним, заданы аппаратно и не подлежат изменению. В этом случае для работы с экраном необходимо использовать специальный класс EsploraTFT.

Сходство с языком Processing

Processing — это открытый язык программирования, используемый дизайнерами, художниками и студентами для создания графики на компьютере или в браузере. В библиотеке Arduino TFT процедуры вывода на экран текста и графических примитивов реализованы в стиле языка Processing, что существенно облегчает перенос кода между двумя средствами разработки.

Примеры

Все примеры работы с TFT-экраном можно условно разбить на две группы: программы для Arduino Esplora и программы для остальных плат, подобных Arduino Uno или Leonardo. Переносить код с одного устройства на другое довольно просто, имея под рукой описание библиотеки и ее функций.

  • Esplora TFT Bitmap Logo: считывание графического файла с карты памяти micro-SD и вывод его содержимого в произвольной области экрана.
  • Esplora TFT Color Picker: использование джойстика и слайдера для изменения цвета TFT-экрана.
  • Esplora TFT Etch a Sketch: реализация классической игры «Etch-a-Sketch» для Esplora.
  • Esplora TFT Graph: вывод показаний датчика света на TFT-экран в виде графика.
  • Esplora TFT Horizon: рисование линии искуственного горизонта по показаниям акселерометра.
  • Esplora TFT Pong: простая версия классической игры.
  • Esplora TFT Temperature: считывание температуры со встроенного датчика и вывод ее на экран.
  • TFT Bitmap Logo: считывание графичекого файла с карты памяти micro-SD и вывод его содержимого в произвольной области экрана.
  • TFT Display Text : считывание показаний датчика и вывод их на экран.
  • TFT Pong: реализация одноименной классической игры для Arduino
  • Etch a Sketch: реализация классической игры «Etch-a-Sketch» для Ардуино.
  • Color Picker: изменение цвета TFT-экрана с помощью трех датчиков.
  • Graph: вывод сопротивления переменного резистора на TFT-экран в виде графика.

Для получения дополнительной информации о модуле с TFT-экраном, см. страницу Начало работы и описание технических возможностей модуля.

  • TFT
  • EsploraTFT
  • begin()
  • background()
  • stroke()
  • noStroke()
  • fill()
  • noFill()
  • text()
  • setTextSize()
  • begin()
  • point()
  • line()
  • rect()
  • width()
  • height()
  • circle()
  • image()
  • loadImage()