- PVSM.RU - https://www.pvsm.ru -
Продолжаем серию публикаций, посвященных использованию среды ARM mbed для создания прототипа измерительного устройства.
Напомню, что речь идет о разработке устройства с сенсорным экраном, которое служит для высокоскоростного измерения температуры и относительной влажности. Самое интересное в этой истории — подход к созданию встроенного ПО. Для написания программы используется онлайн IDE mbed, позволяющая создавать железонезависимый код, который одинаково работает на отладочных платах от SiLabs, Atmel, Wiznet, STM32, NXP и других производителей.
Сегодня начинаем работать с выводом картинки на TFT-дисплей.
Содержание цикла публикаций:
Вторая часть под катом.
В прошлой статье [1] был дан краткий обзор использованных аппаратных модулей, в том числе сенсорного TFT-дисплея — модуля от компании Riverdi, который состоит из дисплея и встроенного графического контроллера FT800 от FTDI. Сегодня мы рассмотрим общие вопросы работы с таким модулем и «подружим» его с отладочной платой.
Поскольку для написания ПО используется исключительно онлайн IDE mbed, получившаяся программа должна без проблем запуститься на отладочных платах SLSTK3400A от SiLabs, ATSAMD21-XPRO от Atmel и WIZwiki-W7500P от Wiznet.
Для управления графическим контроллером используются команды трех типов:
Все функции для взаимодействия с TFT-дисплеем состоят из приема и передачи таких команд. Компания FTDI предоставляет библиотеку, в которой реализованы все операции, поддерживаемые графическим контроллером. Это несколько десятков функций различной сложности, которые, тем не менее, всегда состоят их базовых функций — приема и передачи по SPI инструкций Host command, Host Memory Read и Host Memory Write.
В общем случае для начала работы с дисплеем требуется адаптировать под используемый хост-контроллер те функции библиотеки FTDI, которые обращаются к периферийным устройствам управляющего контроллера. Это настройка интерфейса SPI, а также функции чтения и записи по SPI данных заданного формата. После того, как железозависимые функции изменены в соответствии с особенностями хост-контроллера, можно начинать использовать все возможности библиотек и примеров от FTDI.
О том, где скачать библиотеку и примеры для модулей FT800, о том как адаптировать библиотеку под целевой хост-микроконтроллер и как использовать доступные функции для практических задач, можно узнать из материалов от производителя и из статей моего коллеги Сергея Долгушина:
В случае разработки программы в mbed задача упрощается ещё сильнее — поскольку написанный в mbed код сам по себе является железонезависимыми, то даже базовые функции библиотеки FTDI становятся универсальными. Таким образом, для управлением дисплеем с отладочных плат от разных производителей можно использовать одну и ту же mbed-библиотеку без внесения каких-либо изменений.
Сигналы intr и pd могут быть реализованы на любых свободных цифровых линиях хост-контроллера.
Для большинства TFT-модулей Riverdi подключение модуля к управляющему контроллеру производится через плоский шлейф. Для подключения шлейфа к отладочным платам предлагается плата-переходник Break Out Board 20. При её использовании нужно обратить внимание на то, что кроме линии питания VDD, на плате отдельно выведено питание подсветки дисплея — сигнал BLVDD. Для работы с дисплеем питание должно подаваться и на VDD, и на BLVDD, поэтому есть смысл сразу объединить линии и подавать питание только на VDD.
С землями GND и BLGND такой фокус не требуется.
Интерфейс SPI хост-процессора всегда является мастером и работает в режиме “mode 0” с передачей старшего бита первым (MSB first). Максимальная рабочая частота интерфейса — 30 МГц, однако до окончания процедуры инициализации частота не должна быть задана выше 11 МГц.
Инициализация графического контроллера состоит в последовательном выполнении следующих операций.
Сначала сигнал PD переводится на 20 мс в низкий уровень, а затем ещё на 20 мс в высокий уровень. Таким образом графический контроллер переходит в режим готовности (Standby). После этого на контроллер FTDI подается несколько команд группы Host command: командой ACTIVE (0x00) контроллер переводится в активный режим, командой CORERST (0x68) сбрасываются значения всех регистров и логических цепей, далее командой CLKEXT (0x44) выбирается тактирование от внешнего источника, а после этого выбирается рабочая частота контроллера — 48 или 36 МГц командой CLK48M (0x62) или CLK36M (0x61) соответственно.
Конечно, возможны и другие сценарии настройки контроллера FT800, но чаще всего процедура выглядит именно так.
Если инициализация графического контроллера прошла успешно, то в регистре REG_ID графического контроллера устанавливается значение 0x7C. После проверки этого контрольного значения можно увеличить скорость SPI.
Последним подготовительным этапом является настройка параметров TFT-дисплея. Суть процедуры — запись в определенные регистры графического контроллера параметров конкретного TFT-дисплея. Мы один раз объясняем графическому контроллеру к какому именно дисплею он подключен, а потом используем универсальные библиотечные функции.
После настроек на дисплей выводится пустой экран. Далее, при необходимости, проводятся настройка сенсорного ввода и аудиоканала. Все эти процедуры многократно описаны производителем, поэтому, наверное, не нуждаются в пояснениях.
Дисплей-лист начинается с записи в графический контроллер команды CMD_DLSTART и заканчивается записью команды DISPLAY(). Отображение дисплей-листа происходит по записи стандартного значения в регистр REG_DLSWAP.
В теле дисплей-листа может находиться до 2048 инструкций. Все они представляют собой простые команды вроде задания цвета объектов и отрисовки графических примитивов — линий, прямоугольников, точек и т.д.
Графический контроллер FTDI состоит из нескольких узлов, среди которых основной процессор, дополнительный графический сопроцессор, аудиосопроцессор и т.д. За выполнение простых команд дисплей-листа отвечает основной процессор FT800, однако микросхемы FTDI позволяют работать и с более сложными объектами — виджетами. Виджеты — это кнопки, слайдеры, шкалы, градиенты, текстовые строки, числа и так далее. Несмотря на то что отрисовка виджетов осуществляется сопроцессором, при формировании дисплей-листа можно вперемешку вызывать простые базовые функции и функции отрисовки виджетов.
Среди mbed-разработчиков уже нашелся человек, имевший дело с графическим контроллером FT800. Этот самый человек, Peter Drescher, благополучно адаптировал для mbed библиотеку от FTDI, снабдил её примером использования и фотографиями. Спасибо, Peter!
Чтобы использовать библиотеку в своем проекте, кликаем на на Import library на посвященной FT800 странице [10], попадаем в свой компилятор и выбираем проект, к которому библиотека будет подключена. Разумеется, для всех этих телодвижений нужно предварительно зарегистрироваться на developer.mbed.org.
Для использования библиотеки FT800 нужно подключить к своему main.cpp файл FT_Platform.h и объявить новый объект TFT класса FT800, также как мы объявляли объект pc класса Serial в программе из предыдущей статьи. Аргументами при объявлении объекта служат выводы платы, на которых доступны линии интерфейса SPI и сигналы PD и INT. Поскольку я буду запускать программу на трех разных платах, сразу расписываю распиновку для всех трех случаев:
#include "mbed.h"
#include "FT_Platform.h"
// SLSTK3400A
FT800 TFT (PE10, PE11, PE12, PE13, PB11, PD4); // mosi, miso, sck, ss, int, pd
// WIZwiki-W7500P
//FT800 TFT (D11, D12, D13, D10, D9, D8); // mosi, miso, sck, ss, int, pd
// ATSAMD21-XPRO
//FT800 TFT (PA18, PA16, PA19, PA17, PA20, PA21); // mosi, miso, sck, ss, int, pd
Сам конструктор класса FT800 лежит в файле FT_Gpu_Hal.cpp [11]
FT800::FT800(PinName mosi, PinName miso, PinName sck, PinName ss, PinName intr, PinName pd):
_spi(mosi, miso, sck),
_ss(ss),
_pd(pd),
_f800_isr(InterruptIn(intr))
{
_spi.format(8,0); // 8 bit spi mode 0
_spi.frequency(2000000); // start with 10 Mhz SPI clock
_ss = 1; // cs high
_pd = 1; // PD high
Bootup();
}
В конструктор класса FT800 уже включена вся процедура инициализации TFT-модуля — настройка интерфейса SPI и вызов функции Bootup(), которая описывает подачу 20-милисекундного импульса на линию PD, отправку нужной последовательности Host-команд, проверку REG_ID графического контроллера, дальнейшее задание частоты SPI в 20 МГц, а также настройка параметров TFT-дисплея.
Смотреть код можно здесь [11] (листать в конец страницы).
Важно отметить, что дефайны для параметров TFT-дисплея задаются в файле FT_LCD_Type.h [12], где по умолчанию прописаны параметры дисплея стандарта WQVGA с разрешением 480 на 272.
Вы поймете что дисплей правильно подключен и корректно инициализирован, если после отработки конструктора загорелся белый экран, в любом другом случае нужно искать ошибку. Если же всё сделано правильно, можно начинать формировать первый дисплей-лист.
Приведу пример простой программы для вывода на экран счетчика секунд, круглых часов и ещё нескольких объектов.
Единственный дисплей-лист будет состоять из следующих операций:
1. Начало дисплей-листа, установка белого цвета как цвета по умолчанию:
TFT.DLstart();
TFT.DL(CLEAR_COLOR_RGB(255, 255, 255));
TFT.DL(CLEAR(1, 1, 1));
2. Установка черного цвета, вывод двух текстовых строк:
TFT.DL(COLOR_RGB(0, 0, 0));
TFT.Text(11, 15, 30, 0, "Demo-project for habrahabr.ru");
TFT.Text(13, 15 + 40, 28, 0, "Using FT800 library");
3. Установка темно-зеленого цвета, вывод графического примитива «Прямоугольник»:
TFT.DL(COLOR_RGB(9, 35, 5));
TFT.DL(BEGIN(RECTS));
TFT.DL(VERTEX2II(11, 105, 0, 0));
TFT.DL(VERTEX2II(11 + 275, 105 + 100, 0, 0));
4. Установка белого цвета, вывод текста и числа секунд:
TFT.DL(COLOR_RGB(255, 255, 255));
TFT.Text(11 + 10, 105 + 10, 29, 0, "Number of seconds:");
TFT.Number(11 + 10, 105 + 10 + 30, 31, 0, seconds);
5. Вывод одного из поддерживаемых на FT800 виджетов — часов:
TFT.Clock(390, 105 + 70, 70, 0, 4, 20, (seconds % 60), 0);
6. Установка черного цвета, вывод текстовой строки:
TFT.DL(COLOR_RGB(0, 0, 0));
TFT.Text(11, 240, 28, 0, "e-mail: xk@efo.ru");
7. Вывод графического примитива «Прямая линия»:
TFT.DL(BEGIN(LINES));
TFT.DL(LINE_WIDTH(8));
TFT.DL(VERTEX2II(11, 15 + 40 + 30, 0, 0));
TFT.DL(VERTEX2II(460, 15 + 40 + 30, 0, 0));
8. Конец дисплей-листа, загрузка картинки на дисплей:
TFT.DL(DISPLAY());
TFT.Swap();
Обращаю внимание, что команды TFT.DL() — это описанные выше простые команды дисплей-листа, а команды TFT.Text(), TFT.Number() и TFT.Clock() — это инструкции сопроцессора.
TFT.Ft_Gpu_CoCmd_Dlstart(); TFT.Ft_App_WrCoCmd_Buffer(CLEAR_COLOR_RGB(255, 255, 255)); TFT.Ft_App_WrCoCmd_Buffer(CLEAR(1, 1, 1)); TFT.Ft_App_WrCoCmd_Buffer(BEGIN(LINES)); TFT.Ft_App_WrCoCmd_Buffer(DISPLAY()); |
TFT.DLstart(); TFT.DL(CLEAR_COLOR_RGB(255, 255, 255)); TFT.DL(CLEAR(1, 1, 1)); TFT.DL(BEGIN(LINES)); TFT.DL(DISPLAY()); |
Я использую второй вариант, однако у использования длинных названий функций есть неоспоримое преимущество: освоившись в таких именах вам будет гораздо легче использовать примеры от производителя и утилиты для автоматической генерации кода от FTDI.
#include "mbed.h"
Serial pc(USBTX, USBRX);
Ticker timeKeeping;
volatile uint64_t seconds = 0;
void secondsCallback(void) {
pc.printf("Number of seconds: %xrn", seconds);
seconds ++;
}
int main() {
timeKeeping.attach(&secondsCallback, 1.0f);
while(1) {}
}
Вносим соответствующие изменения — подключаем библиотеку FT800, объявляем объект класса FT800 и вы бесконечном цикле вызываем функцию, формирующую описанный выше дисплей-лист.
#include "mbed.h"
#include "FT_Platform.h"
FT800 TFT (PE10, PE11, PE12, PE13, PB11, PD4); // mosi, miso, sck, ss, int, pd [SLSTK3400A]
//FT800 TFT (D11, D12, D13, D10, D9, D8); // mosi, miso, sck, ss, int, pd [WIZwiki-W7500P]
//FT800 TFT (PA18, PA16, PA19, PA17, PA20, PA21); // mosi, miso, sck, ss, int, pd [ATSAMD21-XPRO]
Ticker timeKeeping;
volatile uint64_t seconds = 0;
/***********************************************************************************************************************/
void secondsCallback(void)
{
seconds ++;
}
/***********************************************************************************************************************/
/* Construct the screen and downloasd it to the TFT */
void drawTimeScreen(void)
{
TFT.DLstart();
TFT.DL(CLEAR_COLOR_RGB(255, 255, 255));
TFT.DL(CLEAR(1, 1, 1));
TFT.DL(COLOR_RGB(0, 0, 0));
TFT.Text(11, 15, 30, 0, "Demo-project for habrahabr.ru");
TFT.Text(13, 15 + 40, 28, 0, "Using FT800 library");
TFT.DL(COLOR_RGB(9, 35, 5));
TFT.DL(BEGIN(RECTS));
TFT.DL(VERTEX2II(11, 105, 0, 0));
TFT.DL(VERTEX2II(11 + 275, 105 + 100, 0, 0));
TFT.DL(COLOR_RGB(255, 255, 255));
TFT.Text(11 + 10, 105 + 10, 29, 0, "Number of seconds:");
TFT.Number(11 + 10, 105 + 10 + 30, 31, 0, seconds);
TFT.Clock(390, 105 + 70, 70, 0, 4, 20, (seconds % 60), 0);
TFT.DL(COLOR_RGB(0, 0, 0));
TFT.Text(11, 240, 28, 0, "e-mail: xk@efo.ru");
TFT.DL(BEGIN(LINES));
TFT.DL(LINE_WIDTH(8));
TFT.DL(VERTEX2II(11, 15 + 40 + 30, 0, 0));
TFT.DL(VERTEX2II(460, 15 + 40 + 30, 0, 0));
TFT.DL(DISPLAY());
TFT.Swap();
}
/***********************************************************************************************************************/
int main()
{
timeKeeping.attach(&secondsCallback, 1.0f);
while(1) {
drawTimeScreen();
}
}
Проект доступен по ссылке [15].
Чтобы получить файл прошивки для трех разных отладочных плат нужно, как и в прошлый раз [16], изменить целевую платформу в правом верхнем углу окна компилятора, а также изменить названия линий ввода-вывода. Вуаля — программа компилируется и работает на всех трех платах.
В следующей статье будет описан процесс создания и подключения к нашему проекту библиотеки для датчика температуры и относительной влажности HYT-271. Будем потихоньку приближаться к полноценному приложению, работа которого продемонстрирована на видео.
Автор: ЭФО
Источник [17]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie-mikrokontrollerov/191013
Ссылки в тексте:
[1] Обзор использованных программных и аппаратных решений.: https://habrahabr.ru/company/efo/blog/308440/
[2] ссылке: http://www.ftdichip.com/Products/ICs/FT800.html
[3] Графический контроллер FT800 для управления TFT-дисплеями: http://mymcu.ru/storage/content/articles/FTDI/EVE.pdf
[4] Графический контроллер FT800. Программные средства разработки и отладки.: http://mymcu.ru/articles/graficheskiy-kontroller-ft800-programmnie-sredstva-razrabotki-i-otladki.html
[5] Начинаем работать с графическим контроллером FT800 FTDI: http://mymcu.ru/storage/content/articles/FTDI/ApN_EFO_FT800.pdf
[6] Графический контроллер EVE FT800 FTDI. Работа с пользовательскими шрифтами, кнопками и сенсорным экраном.: http://mymcu.ru/storage/content/articles/FTDI/ApNote_002_FT800.pdf
[7] Графический контроллер EVE FT800 FTDI и микроконтроллер SAMD21 Atmel. Работаем с графическими изображениями.: http://mymcu.ru/storage/content/devtools/FTDI/FT800_SAMD21.pdf
[8] Графический контроллер EVE FT800 FTDI и микроконтроллер SAMD21 Atmel.: http://mymcu.ru/storage/content/files/ftdi/FT800_SAMD21_p2.pdf
[9] Графический контроллер FT800. Вывод на экран изображения стрелочного индикатора: http://mymcu.ru/storage/content/articles/FTDI/APP_EFO_FT800_Indikator.pdf
[10] посвященной FT800 странице: https://developer.mbed.org/components/EVE-FT800/
[11] FT_Gpu_Hal.cpp: https://developer.mbed.org/users/dreschpe/code/FT800_2/file/16e22c789f7d/FT_Gpu_Hal.cpp
[12] FT_LCD_Type.h: https://developer.mbed.org/users/dreschpe/code/FT800_2/file/16e22c789f7d/FT_LCD_Type.h
[13] FT800 : https://developer.mbed.org/users/dreschpe/code/FT800/
[14] FT800_2: https://developer.mbed.org/users/dreschpe/code/FT800_2/
[15] ссылке: https://developer.mbed.org/users/Ksenia/code/FT800_demo_for_habr/
[16] в прошлый раз: https://habrahabr.ru/company/efo/blog/308440/#example
[17] Источник: https://habrahabr.ru/post/309918/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.