Что такое код imagepolygon


imagepolygon

imagepolygon — Draws a polygon

Описание

imagepolygon() creates a polygon in the given image.

Список параметров

Ресурс изображения, полученный одной из функций создания изображений, например, такой как imagecreatetruecolor() .

An array containing the polygon’s vertices, e.g.:

points[0] = x0
points[1] = y0
points[2] = x1
points[3] = y1

Total number of points (vertices).

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

Примеры

Пример #1 imagepolygon() example

// Create a blank image
$image = imagecreatetruecolor ( 400 , 300 );

// Allocate a color for the polygon
$col_poly = imagecolorallocate ( $image , 255 , 255 , 255 );

// Draw the polygon
imagepolygon ( $image , array(
0 , 0 ,
100 , 200 ,
300 , 200
),
3 ,
$col_poly );

// Output the picture to the browser
header ( ‘Content-type: image/png’ );

imagepng ( $image );
imagedestroy ( $image );
?>

Результатом выполнения данного примера будет что-то подобное:

Смотрите также

  • imagecreate() — Create a new palette based image
  • imagecreatetruecolor() — Create a new true color image

imagepolygon — Рисование многоугольника

(PHP 4, PHP 5, PHP 7)

imagepolygon — Рисование многоугольника

Описание

imagepolygon() создает многоугольник в изображении image .

Список параметров

Ресурс изображения, полученный одной из функций создания изображений, например, такой как imagecreatetruecolor() .

Массив вершин многоугольника:

points[0] = x0
points[1] = y0
points[2] = x1
points[3] = y1

Общее число точек (вершин).

Идентификатор цвета созданный функцией imagecolorallocate() .

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

Примеры

Пример #1 Пример использования imagepolygon()

// Создание пустого изображения
$image = imagecreatetruecolor ( 400 , 300 );

// Создание цвета полигона
$col_poly = imagecolorallocate ( $image , 255 , 255 , 255 );

// Рисование многоугольника
imagepolygon ( $image , array(
0 , 0 ,
100 , 200 ,
300 , 200
),
3 ,
$col_poly );

// Вывод картинки в броузер
header ( ‘Content-type: image/png’ );

imagepng ( $image );
imagedestroy ( $image );
?>

Результатом выполнения данного примера будет что-то подобное:

Смотрите также

  • imagecreate() — Создание нового палитрового изображения
  • imagecreatetruecolor() — Создание нового полноцветного изображения

Imagepolygon

Php функции


Php скрипты


imagepolygon

(PHP 3, PHP 4, PHP 5)

imagepolygon — Draw a polygon

Description

bool imagepolygon ( resource image, array points, int num_points, int color )

imagepolygon() creates a polygon in image >array containing the polygon’s vertices, i.e. points [ 0 ] = x0, points [ 1 ] = y0, points [ 2 ] = x1, points [ 3 ] = y1, etc. num_points is the total number of points (vertices).

Пример 1. imagepolygon() example

// create a blank image
$image = imagecreatetruecolor ( 400 , 300 );

// fill the background color
$bg = imagecolorallocate ( $image , 0 , 0 , 0 );

// choose a color for the polygon
$col_poly = imagecolorallocate ( $image , 255 , 255 , 255 );

// draw the polygon
imagepolygon ( $image ,
array (
0 , 0 ,
100 , 200 ,
300 , 200
),
3 ,
$col_poly );

// output the picture
header ( «Content-type: image/png» );
imagepng ( $image );

User Contributed Notes

glowell at flash dot net
18-Nov-2005 02:43

Something to be aware of, ImagePolygon appears to convert the array of points passed to it from whatever format they may have been in originally into integers. This means if you pass it an array of floats (after running a rotation routine for example) the floats will be changed to integers INSIDE THE ORIGINAL ARRAY.

An extreme example: if for some reason you had an unit-sized polygon pt-array ( -1 for easy scaling purpose for instance) and for some reason your code calls imagepolygon on it (why? it’d only be a dot anyway) the array would be unusable after that (all either 1s, 0s or -1s). Scaling a unit-sized array , drawing it and then scaling it again will also may have a different result than expected.

Obviously, if the array in its original state is important to your code, it should use a copy of the original array for this call. If your code draws the same polygon multiple times but resizes it for different cases, you should have each size be created off an original template rather than adjusting a single polygon array.
jsnell at networkninja dot com
18-Feb-2001 06:07

Here are some handy routines for rotation and translation of polygons. Scaling could be added easily as well.

$new_x = $x * cos( $angle ) — $y * sin( $angle );
$new_y = $x * sin( $angle ) + $y * cos( $angle );
$x = $new_x + $about_x + $shift_x ;
$y = $new_y + $about_y + $shift_y ;
>

function translate_poly( $point_array , $angle , $about_x , $about_y , $shift_x , $shift_y )
<
$translated_poly = Array ();
while (count( $point_array ) > 1)
<
$temp_x = array_shift ( $point_array );
$temp_y = array_shift ( $point_array );
translate_point( $temp_x , $temp_y , $angle , $about_x , $about_y , $shift_x , $shift_y );
array_push ( $translated_poly , $temp_x );
array_push ( $translated_poly , $temp_y );
>
return $translated_poly ;
>

Что такое код imagepolygon

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

Для рисования полигона используется функция imagepolygon.

image — идентификатор изображения;
points — массив точек;
num_points — количество точек в полигоне;
color — цвет.

Массив точек содержит X и Y координату каждой точки. Таким образом, для трех точек, массив содержит шесть элементов: Array( X1, Y1, X2, Y2, X3, Y3)

Пример 25. Вывод самого простого полигона (треугольник):

Полигоны очень удобно использовать при работе с векторной графикой. Я использовал полигоны для отрисовки карты мира на сайте http://top.novgorod.ru. Файлы с контурами стран я создавал в Adobe Photoshop с помощью «Paths» и экспортировал их встроенным плагином «Export Paths to Illustrator».

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

Пример 26. Чтение файла Adobe Illustrator и вывод полигона:

imagepolygon

imagepolygon — Draws a polygon

Описание

imagepolygon() creates a polygon in the given image.

Список параметров

Ресурс изображения, полученный одной из функций создания изображений, например, такой как imagecreatetruecolor() .

An array containing the polygon’s vertices, e.g.:

points[0] = x0
points[1] = y0
points[2] = x1
points[3] = y1

Total number of points (vertices).

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

Примеры

Пример #1 imagepolygon() example

// Create a blank image
$image = imagecreatetruecolor ( 400 , 300 );

// Allocate a color for the polygon
$col_poly = imagecolorallocate ( $image , 255 , 255 , 255 );

// Draw the polygon
imagepolygon ( $image , array(
0 , 0 ,
100 , 200 ,
300 , 200
),
3 ,
$col_poly );

// Output the picture to the browser
header ( ‘Content-type: image/png’ );

imagepng ( $image );
imagedestroy ( $image );
?>

Результатом выполнения данного примера будет что-то подобное:

Смотрите также

  • imagecreate() — Create a new palette based image
  • imagecreatetruecolor() — Create a new true color image

Что такое код imagepolygon

Краткое описание:
Преобразование файлов изображений из одного формата в другой.

Вы хотите открывать файлы Photoshop PSD, TIFF, PCX, PBM или файлы изображений других редких форматов на своём Android-устройстве? Теперь, благодаря Image Converter, это возможно. И, самое главное, вы сможете сохранить их в JPEG, PNG и других, привычных для себя форматах файлов.

Image Converter — лучшее приложение для преобразования форматов файлов изображений прямо на вашем устройстве.

Функции:
— Изменение размеров изображений
— Обработка нескольких файлов
— Сохранение в нескольких разных форматах
— Обрезка изображений
— Поворот изображений

Все операции выполняются оффлайн и на вашем устройстве. Ни одно из ваших изображений не будет передано на какой-либо сервер.

Image Converter умеет «читать» файлы изображений следующих форматов:
AAI, ART, ARW, AVI, AVS, BPG, BMP, BMP2, BMP3, CALS, CGM, CIN, CMYK, CMYKA, CRW, CUR, CUT, DCM, DCR, DCX, DDS, DIB, DJVU, DNG, DOT, DPX, EMF, EPDF, EPI, FAX, FIG, FITS, FPX, GIF, GIF87, GPLT, GRAY, HDR, HPGL, HRZ, HTML, ICO, INLINE, JBIG, JNG, JP2, JPT, J2C, J2K, JPEG, JPG, JXR, MAN, MAT, MIFF, MONO, MNG, M2V, MPEG, MPC, MPR, MRW, MSL, MTV, MVG, ORF, OTB, P7, PALM, CLIPBOARD, PBM, PCD, PCDS, PCX, PDB, PEF, PFA, PFB, PFM, PGM, PICON, PICT, PIX, PNG, PNG8, PNG00, PNG24, PNG32, PNG48, PNG64, PNM, PPM, PS, PS2, PS3, PSB, PSD, PTIF, PWP, RAD, RAF, RGB, RGBA, RFG, RLA, RLE, SCT, SFW, SGI, SUN, TGA, TIFF, TIF, TIM, TTF, TXT, UYVY, VICAR, VIFF, WBMP, WDP, WEBP, WMF, WPG, X, XBM, XCF, XPM, X3F, YCBCR, YCBCRA, YUV. Вы также можете попробовать загрузить файлы и других форматов.

Image Converter умеет преобразовать файлы в следующие форматы:
JPG, JPEG, PNG, BMP, GIF, JP2, PDF, TIF, TIFF, WEBP, PSD, TGA, AI, HTML, TXT, JPC, AVS, CMYK, DCX, DIB, GIF87, GRAY, MNG, MTV, NETSCAPE, PBM, PCX, PGM, PICT, PNM, PPM, RGB, RGBA, SGI, SUN, UIL, UYVY, VIFF, XPM, YUV, PAM, RAS, HDR, FITS, DDS, PAL, H, SVG, EPS, AAI, ART, CIN, CIP, DPX, FAX, HRZ, INFO, MAT, MONO, MPC, OTB, PALM, PCD, PCL, PDB, PS, PS2, PS3, VICAR, WBMP, XBM, YCBCR, BMP2, BMP3, CMYKA, EPS2, EPS3, J2C, PCDS, PFM, PICON, PNG8, PNG24, PNG32, PSB, PTIF, YCBCRA, SHTML.

Image Converter НЕ умеет «читать» следующие форматы:
cr2, raw, pdf, eps, exr, ras, iff, pgf, svg, nef.

Удобный файловый браузер и понятный интерфейс Image Converter дают доступ ко всем вашим файлам/изображениям, позволяют открывать изображения из вашей библиотеки фотографий и получать файлы из других приложений, например, вложения электронной почты.
Все преобразованные изображения доступны внутри приложения и могут быть автоматически сохранены в вашей библиотеке фотографий, если имеют один из следующих форматов:
jpg, jpeg, png, bmp, gif, (webp Android 4.0+).
Внутри этого приложения вы можете передавать любые из преобразованных изображений через другие приложения, такие как электронная почта и социальные сети. Ваши исходные файлы изображений останутся в целости и сохранности и изменениям не подвергнутся.

ОБРАТИТЕ ВНИМАНИЕ: преобразование будет работать, только если у Вас достаточно оперативной памяти.

Требуется Android: 4.4+ (4.0+ до v.5.60)
Русский интерфейс: Да

Снова GD: imagepolygon — как обеспечить склаживание?

myarh

Новичок

Снова GD: imagepolygon — как обеспечить склаживание?

Хочется у imagepolygon добиться такого же сглаживания бордюра, как например у imagettftext .

Пробовал imagesetbrush (хотел вывести градиентную кисточку, и потом уже ей рисовать) — все выходит все равно гадко и несглаженно.

Может еще какие варианты есть? Если кто то с этим сталкивался — помогите пожалуйста.

Неужели поможет только рисование в два раза большей величине и уменьшение imagecopyresampled?

Я так хочу верить, что есть есче решения.

imageantialias конечно помогает (не сочтите меня за совсем уж тупого) но у моего хостера версия 2.0.15
под такой версией imageantialias не поддерживается

imagepolygon

(PHP 4, PHP 5, PHP 7)

imagepolygon — Рисование многоугольника

Описание

imagepolygon() создает многоугольник в изображении image .

Список параметров

Ресурс изображения, полученный одной из функций создания изображений, например, такой как imagecreatetruecolor() .

Массив вершин многоугольника:

points[0] = x0
points[1] = y0
points[2] = x1
points[3] = y1

Общее число точек (вершин).

Идентификатор цвета созданный функцией imagecolorallocate() .

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

Примеры

Пример #1 Пример использования imagepolygon()

// Создание пустого изображения
$image = imagecreatetruecolor ( 400 , 300 );

// Создание цвета полигона
$col_poly = imagecolorallocate ( $image , 255 , 255 , 255 );

// Рисование многоугольника
imagepolygon ( $image , array(
0 , 0 ,
100 , 200 ,
300 , 200
),
3 ,
$col_poly );

// Вывод картинки в броузер
header ( ‘Content-type: image/png’ );

imagepng ( $image );
imagedestroy ( $image );
?>

Результатом выполнения данного примера будет что-то подобное:

Смотрите также

  • imagefilledpolygon() — Рисование закрашенного многоугольника
  • imageopenpolygon() — Draws an open polygon
  • imagecreate() — Создание нового палитрового изображения
  • imagecreatetruecolor() — Создание нового полноцветного изображения

Что такое код imagepolygon

imagepolygon — рисует многоугольник.

Описание

int imagepolygon (resource image, array points, int num_points, int col)

imagepolygon() создаёт многоугольник на изображении.
points это PHP-массив, содержащий вершины полигона, т.е. points[0] = x0, points[1] = y0, points[2] = x1, points[3] = y1, etc.
num_points это общее количество вершин.


Назад Оглавление Вперёд
imagepng Вверх imagepsbbox

Материалы, которые находятся на этой страничке, любезно предоставлены Игорем Ивановым

Запускаем дисплей на STM32 через LTDC… на регистрах

Приветствую! Недавно для проекта потребовалось запустить дисплей, который имел интерфейс LVDS. Для реализации задачи был выбран контроллер STM32F746, т.к. я с ним уже достаточно много работал и у него есть модуль LTDC, который позволяет работать напрямую с дисплеем без контроллера. В данном случае контроллер реализован уже внутри микроконтроллера. Так же не последним доводом было то, что на данном камне есть отладка STM32F746-Disco, которая у меня была под рукой, а значит я мог начинать работу над проектом не дожидаясь пока ко мне приедет плата, компоненты и прочее.

Сегодня я расскажу как запустить модуль LTDC, работая с регистрами (CMSIS). HAL и прочие библиотеки не люблю и не использую по религиозным убеждениям, но в этом и интерес. Вы увидите, что поднимать сложную периферию на регистрах так же просто, как и обычный SPI. Интересно? Тогда поехали!

1. Немного о LTDC

Данный модуль периферии по своей сути является контроллером, который обычно стоит на стороне дисплея, например, SSD1963 и ему подобные. Если посмотрим на структуру LTDC, то увидим, что физически это параллельная шина на 24 бита + аппаратный ускоритель графики + массив данных в ОЗУ, который является по факту буфером дисплея (frame buffer).

На выходе мы имеем обычную параллельную шину, которая в себе содержит 24 бита цвета (по 8 бит на цвет модели RGB), линии синхронизации, линия включения/отключения дисплея и pixel clock. Последний по факту является сигналом тактирования по которому загружаются пиксели в дисплей, то есть если частота у нас 9.5 МГц, то за 1 секунду мы можем загружать 9.5 млн. пикселей. Это в теории разумеется, на практике цифры несколько скромнее из-за таймингов и прочего.

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

2. А что нам нужно сделать?

Микроконтроллеры от ST обрели популярность не зря, важнейшим требованием к любым электронным компонентов — это документация, а с ней все хорошо. Сайт конечно ужасный, но на всю документацию я оставлю ссылки. Производитель избавляет нас от мучений и изобретения велосипеда, поэтому на странице 520 в reference manual RM0385 черным по белому расписано по шагам, что нам надо сделать:

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

  • Включить тактирование модуля LTDC
  • Настроить систему тактирования и частоту вывода данных (pixel clock)
  • Настроить порты ввода-вывода (GPIO) на работу с LTDC
  • Настроить тайминги для нашей модели дисплея
  • Настроить полярность сигналов. Уже сделано по умолчанию
  • Указать цвет фона дисплея. Его пока не увидим, можно оставить «по нулям»
  • Настроить реальный размер видимой зоны дисплея для конкретного слоя
  • Выбрать формат цвета: ARGB8888, RGB 888, RGB565 и т.д.
  • Указать адрес массива, который будет выступать в роли frame buffer-а
  • Указать количество данных в одной линии (длину по ширине)
  • Указать количество линий (высота дисплея)
  • Включить слой с которым мы работаем
  • Включить модуль LTDC

Страшно? И мне было страшно, а там оказалось работы на 20 минут со всеми разбирательствами. Задача есть, план расписан и остается его всего лишь выполнить.

3. Настройка системы тактирования

Первым пунктом нам необходимо подать тактовый сигнал на модуль LTDC, это делается записью в регистр RCC:

Далее необходимо настроить частоту тактирования от внешнего кварца (HSE) на частоту 216 МГц, то есть на максимальную. Первым шагом включаем источник тактирования от кварцевого резонатора и ждем флага готовности:

Теперь настраиваем задержку для flash памяти контроллера, т.к. она не умеет работать на частоте ядра. Ее значение как и остальные данные берутся из reference manual:

Теперь для получения искомой частоты я разделю 25 МГц со входа на 25 и получу 1 МГц. Далее просто в PLL умножаю на 432, т.к. в дальнейшем есть делитель частоты с минимальным значением /2 и на него нужно подать удвоенную частоту. После этого подключаем вход PLL к нашему кварцевому резонатору (HSE):

Теперь включаем PLL и ждем флага готовности:

В качестве источника системной частоты назначаем выход нашего PLL и ждем флага готовности:

На этом общая настройка тактирования заканчивается и мы переходим к настройке тактовой частоты (PLLSAI) для нашего дисплея (pixel clock). Сигнал для PLLSAI согласно даташиту берется после делителя /25, то есть на входе мы имеем 1 МГц. Нам нужно получить частоту около 9.5 МГц, для этого частоту 1 МГц умножаем на 192, а затем с помощью двух делителей на 5 и на 4 получаем искомое значение PLLSAI = 1 МГц * 192 / 5 /4 = 9,6 МГц:

Финальным шагом мы включаем PLLSAI для дисплея и ждем флага готовности к работе:

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

4. Настройка портов ввода-вывода (GPIO)

С настройкой gpio все очень просто — у нас все ноги шины LTDC должны быть настроены как альтернативный выход и на высокую частоту. Для этого в reference manual на странице 201 у нас есть вот такая подсказка:

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

Как видите логика таблицы простейшая: находим нужную нам функцию, в нашем случае LTDC B0, далее смотрим на каком GPIO она находится (PE4, например) и наверху смотрим номер альтернативной функции, который будем использоваться для настройки (AF14 у нас). Чтобы настроить наш вывод как push-pull выход с альтернативной функцией LTDC B0 нам нужно написать следующий код:

Я привел пример для вывода PE4, который соответствует выводу B0 на шине LTDC, то есть это нулевой бит синего цвета. Для всех остальных выводов настройка идентична, отдельного внимания заслуживают лишь 2 вывода, один из готовых включает дисплей, а другой его подстветку. Настраиваются они как обычный выход push-pull, который все используют для мигания светодиодом. Выглядит настройка вот так:

Данная настройка для вывода PK3, который включает и выключает нашу подсветку. Его кстати можно еще и ШИМовать, чтобы плавно регулировать яркость. Для PI12, который включает дисплей (DISP) все аналогично. Скорость на этих 2-х выводах по умолчанию низкая, т.к. каких-то высокочастотных действий от них не требуется.

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

5. Тайминги и их настройка

Тайминги с физический точки зрения представляют из себя обычные задержки. Думаю вы ни раз наблюдали различные извращения типа delay(1), когда смотрели примеры кода на дисплеи с контроллерами SPI/I2C на подобии ILI9341. Там задержка нужна для того, чтобы контроллер, например, успел принять команду, выполнить ее и затем уже что-то делать с данными. В случае с LTDC все примерно так же, только городить костыли мы не будем да и не зачем — наш микроконтроллер сам аппаратно умеет формировать необходимые тайминги. Зачем они нужны на дисплее, где нет контроллера? Да элементарно чтобы после заполнения первой линии пикселей перейти на следующую линию и вернуться в ее начало. Это связано с технологией производства дисплеев, а следовательно у каждой конкретной модели дисплея тайминги могут быть свои.

Чтобы узнать какие значения нам понадобятся идем на сайт ST и смотрим схему отладочной платы STM32F746-Disco. Там мы можем увидеть, что используется дисплей RK043FN48H-CT672B и документация на него доступна, например, тут. Нас больше всего интересует таблица на странице 13 в разделе 7.3.1:

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

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

Тут есть интересная особенность. Тайминг Pulse Width, который именуется у нас DISPLAY_HSYNC, имеет значение в таблице только для частоты pixel clock в 5 МГц, а для 9 и 12 МГц его нет. Данный тайминг необходимо подобрать под свой дисплей, у меня это значение получилось 30, когда в примерах от ST оно было иное. При первом запуске если у вас будет ошибка с его настройкой, то изображение будет сдвинуто или влево или вправо. Если вправо — уменьшаем тайминг, если влево — увеличиваем. По факту он влияет на начало координаты видимой зоны, в чем мы дальше и убедимся. Просто имейте ввиду, а помочь осмыслить весь этот абзац поможет следующая картинка со страницы 24 нашего AN4861:

Тут удобна небольшая абстракция. У нас есть 2 зоны дисплея: видимая и общая. Видимая зона имеет размеры с заявленным разрешением 480 на 272 пикселя, а общая зона — это видимая + наши тайминги, которых по 3 на каждую сторону. Так же стоит понимать (это уже не абстракция), что один системный тик равен 1 пикселю, поэтому общая зона имеет размер 480 пикселей + HSYNC + HBP + HFP.

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

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

Откуда собственно эта «шпаргалка» взялась… Во-первых, похожую «формулу» вы видели пару абзацев до этого. Во-вторых, идем на страницу 56 нашего AN4861:

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

Теперь пришла пора написать код, который эти тайминги настроит. В «шпаргалке» указаны бита регистра в которые писать, например, TOTALH и после знака равно формула, дающая на выходе некое число. Понятно? Тогда пишем:

А на этом с таймингами все! В данном разделе можно еще разве, что настроить цвет фона. У меня он по умолчанию черный, поэтому записан нулем. Если вы хотите изменить цвет фонового слоя (background), то можете после равно записать любое значение, например, 0xFFFFFFFF и залить все белым:

Есть в reference manual-е замечательная иллюстрация, которая наглядно демонстрирует, что у нас имеется по сути 3 слоя: background, layer 1 и layer 2. Фоновый слой «кастрирован» и умеет лишь заливаться одним конкретным цветом, но тоже бывает невероятно полезен при реализации дизайн будущего GUI. Так же данная иллюстрация наглядно демонстрирует приоритет слоев из чего следует, что мы увидим цвет заливки на background, только когда на остальные слои или пустые или прозрачные.

В качестве примера покажу одну из страниц проекта, где в процессе реализации шаблона background был залит один цветом и контроллер перерисовывал не страницу целиком, а только отдельные сектора, что позволяло получать около 50-60 фпс при множестве других задач:

6. Финальная часть настройки LTDC

Настройки LTDC делятся на 2 раздела: первые являются общими для всего модуля LTDC и находятся в группе регистров LTDC, а вторые настраивают один из двух слоев и находятся в группе LTDC_Layer1 и LTDC_Layer2.

Общие настройки мы выполнили в предыдущем пункте, к ним относится настройка таймингов, фонового слоя. Теперь переходим к настройке слоев и по нашему списку необходимо реальный размер видимой зоны слоя, который описывается в виде 4-х координат (x0, y0, x1, y2), позволяющие получить размеры прямоугольника. Размер видимого слоя может быть меньше разрешения дисплея, никто не мешает сделать размер слоя 100 на 100 пикселей. Для настройки размера видимой зоны напишем следующий код:

Как видите тут все просто как и с таймингами. Начальные точки (x0, y0) видимой зоны состоят из суммы двух таймингов: HSYNC + HBP и VSYNC + VBP. Для вычисления координат конечной точки (x1, y1) к данным значения просто добавляется ширина и высота в пикселях.

Теперь необходимо настроить формат принимаемых данных. Максимальное качество получается при использовании формата ARGB8888, но при этом мы получаем и максимальный объем занимаемой памяти. Один пиксель занимаем 32 бита или 4 байта, а значит весь экран занимает 4*480*272 = 522 240 байт, то есть половину flash-памяти нашего не самого слабого контроллера. Пугаться не стоит — подключение внешней SDRAM и Flash-памяти по QSPI решают проблемы с памятью и ограничений на данный формат нет, радуемся хорошему качеству. Если вы хотите сэкономить место или у вас дисплей не поддерживает формат 24 бита, то для этого используются более подходящие модели, например, RGB565. Очень популярный формат как для дисплеев, так и для камер, а главное при его использовании 1 пиксель занимаем всего 5+6+5 = 16 бит или 2 байта. Соответственно объем памяти, занимаемый слоем, будет в 2 раза меньше. По умолчанию в контроллере уже настроен формат ARGB8888 и имеет следующий вид:

Если вам нужен другой формат, отличный от ARGB8888, то идем на страницы 533 и 534 в reference manual-е и выбираем нужный формат из предложенного списка:

Теперь создадим массив и передадим его адрес в LTDC, он превратится во frame buffer и будет являться «отражением» нашего слоя. Например, вам нужно 1-й пиксель в 1-й строке залить белым цветом, для этого вам достаточно записать значение цвета (0xFFFFFFFF) в первый элемент этого массива. Надо залить 1-й пиксель во 2-й строке? Тогда тоже значение цвета запишем в элемент с номером (480+1). 480 — сделает перенос строки, дальше добавляет номер в нужной нам строке.

Выглядит это настройка вот так:

По хорошему следует после настройки LTDC настроить еще и SDRAM, чтобы убрать модификатор const и получить frame buffer именно в ОЗУ, т.к. собственной ОЗУ МК не хватает даже на один слой при 4 байтах. Хотя это не помешает протестировать правильность настройки периферии.

Далее необходимо указать значение альфа-слоя, то есть прозрачность для нашего слоя Layer2, для этого записываем значение от 0 до 255, где 0 — полностью прозрачный слой, 255 — полностью непрозрачный, то есть 100% видимый:

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

Осталось два последних шага, а именно включение слоя №2 и самого модуля периферии LTDC. Для этого записываем соответствующие биты:

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

7. Немного о работе с LTDC

Вся работа с дисплеем сводится теперь лишь к записи данных в массив imageLayer2, он имеет размер 480 на 272 элемента, что полностью соответствует нашему разрешению и намекает на простую истину — 1 элемент массива = 1 пиксель на дисплее.

Я в качестве примера записал в массив картинку, которую преобразовал на в программе LCD Image Converter, но на деле вряд ли ваши задачи ограничатся этим. Есть два пути: использование готового GUI и написание его собственноручно. Для относительно простых задач типа вывода текста, построение графиков и подобное советую написать свой GUI, это займет немного времени и даст вам полное понимание его работы. Когда же задача большая и сложная, а времени на разработку своего GUI нет, то советую обратить внимание на готовые решения, например, uGFX и ему подобные.

Символы текста, линии и прочие элементы по своей сути являются массивами пикселей, соответственно для их реализации вам самостоятельно нужно реализовать логику, но начать стоит с самой базовой функции — «вывод пикселя». Она должна принимать 3 аргумента: координату по Х, координату по Y и соответственно цвет в который данный пиксель окрашивается. Выглядеть это может например так:

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

Как видите реализация даже сложной периферии на регистрах (CMSIS) является не сложной задачей, вам достаточно понять как оно работает внутри. Конечно нынче модно разрабатывать встроенное ПО без понимания происходящего, но это тупиковый путь, если вы планируете стать инженером, а не…

Если сравнить полученный код с решением на HAL или SPL, то можно заметить, что код написанный на регистрах более компактный. Добавив где нужно пару комментариев и обернув в функции мы получаем читаемость как минимум не хуже, чем у HAL/SPL, а если вспомнив, что reference manual документирует именно регистры, то работа с использованием CMSIS является более удобной.

1) Проект с исходниками в TrueSTUDIO можно скачать тут

2) Для тех, кому удобнее посмотреть на GitHub

3) Утилиту для конвертации изображения в код LCD Image Converter скачиваем тут

Илон Маск рекомендует:  Глава 1 введение в сферу персональных компьютеров
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL