Можно ли сделать несколько проектов для дисплеев контроллера
Для чего можно использовать несколько мониторов и как создать мультидисплейную конфигурацию с минимальными затратами.
Вопрос подключения нескольких и более мониторов к одному компьютеру волнует достаточно многих пользователей. Кому-то это нужно для работы, кому-то для игр, а у кого-то просто есть второй монитор и он думает как бы его можно было использовать с пользой.
В любом случае всех интересует как правильно соединить мониторы с ПК, какая для этого нужна видеокарта и разъемы, можно ли подключить один монитор к видеокарте, а другой к материнской плате, как одновременно подключить 4-8 мониторов или создать тонкошовную видеостену с не большим бюджетом.
3. Как подключить несколько мониторов к одному ПК
Подключение к компьютеру с современной видеокартой двух мониторов с различными интерфейсными разъемами обычно не вызывает проблем. Они просто подключаются каждый к своему разъему видеокарты, максимум что потребуется это докупить соответствующий кабель, если нужного нет в наличии.
Проблемы начинаются, когда на втором мониторе нет подходящего разъема. В некоторых случаях это можно решить переходником или специальным кабелем (DVI-HDMI, DP-HDMI и т.п.) – это самое простое и правильное решение.
Но, если на мониторе есть только устаревший разъем VGA (D-SUB), это может стать настоящей проблемой. Дело в том, что старые видеокарты имели выход DVI-I с возможностью подключение таких мониторов через переходник DVI-VGA.
На современных видеокартах используется разъем DVI-D, на который не выводится аналоговый сигнал VGA и нет соответствующих выходов для подключения такого переходника и подключить через него монитор невозможно. Да, есть специальные конвертеры (DVI-VGA, HDMI-VGA), но качество изображение при конвертации серьезно страдает (картинка становится мыльной, портится цветопередача), так что это плохое решение.
Однако, выход есть – если на вашей материнке имеется разъем VGA и в биосе есть возможность принудительно включить интегрированную графику процессора, то монитор можно подключить к этому разъему. После этого операционная система будет видеть две видеокарты и выводить изображение на оба монитора. Единственное что нужно будет сделать это обновить драйвера на встроенную графику, если система не сделает это автоматически.
Такое решение вполне подходит для любых рабочих задач, вы сможете создать как несколько отдельных рабочих столов, так и одно общее пространство. Однако, это плохо подходит для игр – если вам даже и удастся запустить игру на дискретной видеокарте, а изображение вывести на монитор подключенный к материнке (мне удавалось), работать это будет плохо и не очень стабильно (качество и производительность будут ниже, возможны лаги).
Если вы хотите подключить более двух мониторов, то учтите – самые дешевые видеокарты поддерживают подключение только 2 мониторов, большинство остальных 3 мониторов, несмотря на то, что у них может быть больше разъемов. Но и не забывайте, что один или несколько мониторов можно еще подключить к материнке (если она поддерживает одновременную работу дискретной и встроенной графики). Сколько мониторов поддерживает та или иная видеокарта или материнка смотрите в спецификации на сайте производителя.
Также существуют специальные мультидисплейные адаптеры, которые позволяют подключить к одному разъему ПК или ноутбуку несколько мониторов. Например, такие адаптеры производит Matrox – они не дешевые, но обеспечивают высокое качество картинки.
Только не перепутайте их с обычными видео сплиттерами, которые просто выводят одинаковую картинку на несколько мониторов.
Установка рабочей области.
Для того, чтобы выводить на дисплей графическую информацию, нужно задать область, с которой мы хотим работать. Для этого используются команды CASET и RASET, то есть установка начальных и конечных значений колонок (x) и рядов (y) пикселей дисплея. Разбираем подробно и наглядно:
Допустим мы хотим работать с областью размером 25 * 50 пикселей, расположенной в левом верхнем углу. Суммарно дисплей представляет из себя полотно 128*160 пикселей. Так что для достижения наших целей мы должны установить необходимые пределы командами CASET и RASET (псевдокод):
- CASET(0, 25)
- RASET(0, 50)
- Изменения после этих команд вступают в силу после выполнения команды RAMWR
- Далее можно отправлять данные для задания цвета пикселей.
Формат команд такой, рассмотрим на примере CASET:
Что означает, что начальные и конечные значения областей для каждой из команд задаются в виде 16-ти битных значений. В реальном коде по итогу получаем следующее:
2. Требования к соединяемым дисплеям
Желательно, чтобы все одновременно используемые дисплеи были максимально идентичными – имели одинаковый размер, разрешение, высоту, наклон, качество экрана, а также по возможности узкие рамки.
Также крайне желательно, чтобы у них было несколько различных современных цифровых разъемов (DVI, DP, HDMI), что расширит возможности их одновременного подключения к разным разъемам видеокарты и материнской платы.
Если вы хотите создать безрамочную или мультидисплейную систему, то мониторы должны иметь специальные крепления (типа VESA) для надежного соединения их между собой на кронштейне, который нужно выбрать заранее.
У некоторых производителей (например, DELL) есть дисплеи, поддерживающие технологию Multi-Stream Transport (MST) специально оптимизированные для создания мультидисплейных конфигураций. Они не только имеют тонкие рамки, но и могут подсоединятся к ПК всего одним кабелем DisplayPort (DP), а дальше соединяются между собой таким же кабелем через разъем DP. Т.е. к компьютеру подключается всего один кабель, что очень удобно и не требует дополнительных разъемов на видеокарте. К одному разъему видеокарты можно подключить до 4 дисплеев с разрешением Full HD (1920×1080, 1920×1200) или 2 дисплея с разрешением 2K (2560×1440, 2560×1600), чтобы общее разрешение всех мониторов не превышало 4K (3840×2160, 4096×2160). Это ограничение вызвано полосой пропускания стандарта DisplayPort v1.2.
Если вы хотите объединить два дисплея для игр, то хорошо если они будут иметь изогнутый экран, это улучшит восприятие и погружение в игру. Хотя в этом случае лучше приобрести один ультраширокий монитор. Исключение составляет случай, если у вас уже есть один хороший монитор и вы сможете докупить второй такой же.
Конечно, можно подключить и совершенно разные мониторы, но их использование может оказаться не комфортным. Лучше чтобы они стояли вровень, не отличались размером и цветопередачей. Впрочем, если они у вас уже есть – пробуйте, вы ничего не потеряете. Если же будете покупать второй монитор, то лучше последуйте нашим рекомендациям.
Установка рабочей области.
Для того, чтобы выводить на дисплей графическую информацию, нужно задать область, с которой мы хотим работать. Для этого используются команды CASET и RASET, то есть установка начальных и конечных значений колонок (x) и рядов (y) пикселей дисплея. Разбираем подробно и наглядно:
Допустим мы хотим работать с областью размером 25 * 50 пикселей, расположенной в левом верхнем углу. Суммарно дисплей представляет из себя полотно 128*160 пикселей. Так что для достижения наших целей мы должны установить необходимые пределы командами CASET и RASET (псевдокод):
- CASET(0, 25)
- RASET(0, 50)
- Изменения после этих команд вступают в силу после выполнения команды RAMWR
- Далее можно отправлять данные для задания цвета пикселей.
Формат команд такой, рассмотрим на примере CASET:
Что означает, что начальные и конечные значения областей для каждой из команд задаются в виде 16-ти битных значений. В реальном коде по итогу получаем следующее:
4. Нюансы создания мультидисплейных конфигураций
Во-первых, для создания конфигураций с 4-8 мониторами есть мониторы с поддержкой MST, о которых я уже говорил. Это отличный вариант, так как позволяет подключить одним кабелем к разъему DP на видеокарте или материнке до 4 мониторов с разрешением FHD. Таким образом к двум разъемам DP можно подключить до 8 мониторов. Недостатком такого решения может стать дороговизна самих мониторов.
Во-вторых, есть специальные видеокарты для создания мультидисплейных конфигураций с большим количеством разъемов. Например, видеокарты Matrox, которые могут иметь от 4 до 9 портов DP или HDMI.
Однако стоят они довольно дорого и подходят только для вывода изображений на дисплеи, производить на них какие-то расчеты или играть не получиться. Так что это больше решение для создания рабочего места обеспеченного трейдера.
Также подключение большого количества мониторов можно организовать с помощью профессиональных видеокарт nVidia из серий NVS или Quadro, модели начального уровня стоят в несколько раз дешевле.
Доступные профессиональные видеокарты есть у французской компании PNY, они оснащаются 3-8 портами miniDP или HDMI. Также в комплекте идут переходники miniDP-DP или miniDP-DVI. Дополнительным плюсом будет значительное ускорение рендеринга трехмерных моделей, если вы занимаетесь 3D-моделированием.
Более бюджетные дисплейные конфигурации можно построить на основе нескольких недорогих офисных или игровых видеокарт начального уровня. При наличии ATX материнки с достаточным количеством слотов PCI-E (x1-x16) можно установить до 4 самых дешевых офисных видеокарт, к каждой из которых можно подключить до 2 мониторов (так как больше они обычно не поддерживают).
При необходимости еще 2-3 монитора можно подключить к материнке (если она это позволяет). Таким образом можно создать конфигурацию до 11 мониторов.
Плюсом такого решения является дешевизна как первоначальной закупки, так и замены отдельной вышедшей из строя видеокарты, а также низкое энергопотребление, нагрев и уровень шума.
Недостатком является то, что использовать такие видеокарты можно только для вывода изображения на экран, ни о каких расчетах (3D рендеринге, монтаже видео) и играх речи быть не может, так как эти видеокарты слишком слабы и не поддерживают нужные технологии.
Другим решением является установка двух полноценных игровых видеокарт начального или среднего уровня (GTX 1050, 1050 Ti, 1060), каждая из которых поддерживает подключение 3 или 4 мониторов.
Таким образом потребуется только 2 слота PCI-E и вы получите подключение 6-11 мониторов (в зависимости от модели видеокарт и материнки) практически за те же деньги, плюс возможность гораздо быстрее монтировать видео и более-менее нормально играть. При этом энергопотребление, нагрев и уровень шума будут несколько выше, но незначительно и только под нагрузкой. Достаточно будет чуть более мощного блока питания и хорошей вентиляции в корпусе (которая все равно потребуется при установке 4 офисных видеокарт).
Формирование цветов.
На чем хочется немного подробнее остановиться, так это на схеме передачи цветов. Дисплей предлагает 3 варианта кодирования цвета:
- 12 битов на пиксель = 4 бита красный (R) + 4 бита зеленый (G) + 4 бита синий (B)
- 16 битов на пиксель = 5 битов красный (R) + 6 битов зеленый (G) + 5 битов синий (B)
- 18 битов на пиксель = 6 битов красный (R) + 6 битов зеленый (G) + 6 битов синий (B)
В этом базовом проекте я использую второй из этих вариантов. Настраивается данная опция в регистре ST7735 COLMOD, для 16-ти битного формата значение 0x05.
При таком режиме основные цвета будут закодированы так:
То есть получаем 16-ти битные значения:
Библиотека для работы с ST7735.
Давайте перейдем к созданию проекта. В STM32CubeMx настраиваем необходимую периферию, которую мы уже, в принципе, всю обсудили:
Тактовые частоты с учетом моего резонатора на 12 МГц такие:
А настройки SPI:
DMA в базовом проекте использовать не будем, но я обычно рекомендую не пренебрегать возможностями контроллера. И, соответственно, для перебрасывания больших объемов данных задействовать DMA.
Итак, меньше слов, больше дела, генерируем проект и сразу добавляем в него файлы для будущей библиотеки ST7735:
Начинаем с необходимых определений в файле st7735.h. Первым делом несколько цветов, чтобы наши тесты были более наглядными:
Второе в списке необходимых дел - выбор портов для взаимодействия с дисплеем:
Зафиксируем также размеры используемого дисплея. Для моего 128*160:
Далее в файле идут всяческие определения команд/регистров, полный код файлов и ссылку на готовый проект можно будет найти в конце статьи. А пока продолжаем с библиотекой. И далее наши конструктивные действия будут сосредоточены в файле st7735.c. Чтобы использовать hspi1 добавляем:
Начинаем последовательно с самого низкого уровня реализовывать необходимые функции. И первая из них - это отправка байта по интерфейсу SPI:
Контроллер ST7735 может ожидать от нас либо байт команды, либо байт данных. С точки зрения SPI в этих случаях все одинаково, отличается лишь уровень сигнала на D/C:
Содержание
Формирование цветов.
На чем хочется немного подробнее остановиться, так это на схеме передачи цветов. Дисплей предлагает 3 варианта кодирования цвета:
- 12 битов на пиксель = 4 бита красный (R) + 4 бита зеленый (G) + 4 бита синий (B)
- 16 битов на пиксель = 5 битов красный (R) + 6 битов зеленый (G) + 5 битов синий (B)
- 18 битов на пиксель = 6 битов красный (R) + 6 битов зеленый (G) + 6 битов синий (B)
В этом базовом проекте я использую второй из этих вариантов. Настраивается данная опция в регистре ST7735 COLMOD, для 16-ти битного формата значение 0x05.
При таком режиме основные цвета будут закодированы так:
То есть получаем 16-ти битные значения:
Отрисовка графических примитивов.
В качестве наглядного эксперимента будем выводить на дисплей основополагающую фигуру - прямоугольник. Задавать аргументами будем:
- cStart , rStart - координата левого верхнего угла
- cStop , rStop - координата правого нижнего угла
- color - цвет заливки
В целом, тут ничего нового:
- Устанавливаем рабочую область при помощи ST7735_SetColAddr() и ST7735_SetRowAddr()
- Далее та команда, о которой я упоминал - ST7735_SendCommand(ST7735_RAMWR)
- Рассчитываем размер области в пикселях
- Разбиваем 16 бит цветовой информации на байты и выдаем на SPI для каждого пикселя. Соответственно, цвета всех пикселей у нас будут одинаковыми, заливка сплошная и однородная.
Ну и все, запускаем тестирование. Для этого будем рисовать прямоугольники размером на весь дисплей разных цветов. В main.c в цикле while(1) добавляем (напоминаю, что полный код под спойлерами в конце статьи):
Само собой не забываем про инициализацию ST7735:
Компилируем и прошиваем. Результат выглядит следующим образом:
Добавляем соответствующий код. Причем его уже нет смысла вызывать из цикла, поэтому сразу после инициализации дисплея вызываем:
И полученный результат соответствует нашим планам:
Я изначально собирался описать еще процесс вывода изображения на этот дисплей, но и эта статья получилась гораздо длиннее, чем я планировал, и с выводом изображения есть свои нюансы, поэтому будет в ближайшие дни вторая часть, а на сегодня на этом заканчиваем 🤝
Демонстрация работы одновременно двух разных типов контроллеров МРРТ параллельно
В данном эксперименте участвуют МРРТ контроллеры: первый от сибконтакта, второй от панды. Контроллеры подключены параллельно друг к другу, подключены они от блока солнечных, которые заходят в дом и к аккумуляторам. Суть эксперимента: проверить возможность параллельной работы двух совершенно разных типов контроллеров МРРТ. Именно для этой цели и были установлены автоматы. Как ни странно, но при запуске и тестировании меня не покидало желание провести подобный эксперимент. И прочитав все защиты, которыми обладают данные МРРТ контроллеры, я решил рискнуть.
Не знаю как другим, но мне был интересен данный опыт, проверить так сказать защиты в работе, а заодно посмотреть смогут ли контроллеры работать параллельно. При этом СКЗ от сибконтакта изначально не поддерживает подобное подключение. Данный опыт я уже демонстрировал. При этом я напоминаю, что панда имеет гальвоническую развязку, о чем свидетельствует как развязка Дс преобразователя так и паспорт устройства.
Но в чем фишка, раз подобное уже было. А в том, что я случайно ну или осознано выключал при экспериментах не оба автомата, а один чтобы максимально быстро сравнивать данные.
И вот я их выключил, как на картинке и о чуда, оба контроллера работают, и заряжают АКБ.
И так через минут 10 срабатывает автомат и отключается панда. Если бы автомата не было, то данный контроллер мог выйти из строя или выбить плавкие предохранители. Пользы от автоматов при больших постоянных токах нет, они все нагреваются и резонируют в часть ДС или генерачии ключей. А также нагреваются и потери на них со временем будут большие. Пробовал ставить автоматы на постоянное напряжение, та же проблема. Отсюда делаем вывод. Если не уверены, ставьте автоматы и тестируйте с ними, если проблем в работе не замечено, то рекомендую ставить предохранительные автоматы, они в этом плане понадежнее, но не забывайте про дугу.
Давно в планах висит статья про подключение дисплея на базе популярного контроллера ST7735 к STM32. В общем-то, план был довольно долгосрочный. Но благодаря читателю блога, который поднял эту тему, принято решение кардинально ускорить данный процесс. Так что сегодня об этом и пойдет речь.
Так, задачей нашей будет сделать базовый проект, который позволит с минимальным порогом вхождения начать работу с любым дисплеем на базе ST7735. В дебри настроек погружаться не будем, пересказыванием даташита заниматься тоже, во главе угла - реальная польза от практической реализации. Вот кстати ссылка на подробнейшее pdf описание контроллера - ссылка.
Содержание
Подключение дисплея на базе ST7735.
Начинаем традиционно - с аппаратной части и подключения дисплея. У меня есть в наличии несколько десятков дисплеев, но преимущественно разрешением 128*160 пикселей. Такой и возьму:
Дисплей имеет 14-ти контактный шлейф для коммутации, его распиновка выглядит следующим образом:
- NC - Not Connected
- GND
- LED K - катод светодиодов подсветки
- LED A - анод светодиодов подсветки
- GND
- RST - сигнал сброса
- D/C - сигнал выбора передачи данных или команд
- SDA - SPI MOSI
- SCK - SPI SCK
- VCC - напряжение питания
- IOVCC - источник питания внутренних интерфейсов
- CS - Chip Select
- GND
- NC - Not Connected
К слову, в разных схемах/статьях/алиэкспрессах обозначение может незначительно, но отличаться. Например, сигнал D/C часто обозначают как RS.
Собрав по-быстрому, "на коленке", плату для подключения дисплея, получаем следующий вариант коммутации:
У меня выбранные ножки фиксированы разводкой платы, а так можно использовать, естественно, любые другие. На подсветку (LED K и LED A) я подключил 3.3 В напрямую (благо источник питания позволяет, потребление светодиодов подсветки на моем дисплее - в районе 40 мА на 3.3 В), то есть подсветка будет работать перманентно. А в обычных проектах я подключаю примерно так:
Соответственно, так мы имеем возможность, во-первых, отключить подсветку, когда требуется, а, во-вторых, управлять яркостью, подавая, например, ШИМ-сигнал разной скважности с микроконтроллера.
В качестве управляющего контроллера у меня STM32F103RE. Пока не забыл, немаловажный нюанс - у меня стоит на этой плате кварц на 12 МГц, можно сказать, что величина нестандартная, так как в подавляющем большинстве случаев используется 8 МГц, ну или реже - 16 МГц. Поэтому обратите на это внимание в настройках тактирования при портировании проекта на свое железо.
Для выдачи данных на дисплей используется интерфейс SPI, причем дисплей только принимает информацию, не передавая ничего в обратном направлении. Это мы учтем при инициализации периферии чуть ниже. Кроме того, потребуются три порта ввода-вывода для подключения линий Chip Select, Reset, D/C. Последняя нужна для информирования дисплея о том, являются ли передаваемые байты данными или командой. Но и с этим мы разберемся чуть позже - при написании библиотеки для работы с ST7735.
Инициализация дисплея.
Переходим к инициализации дисплея. Я приведу полный код из одного из своих проектов, его можно использовать в качестве отправной точки, изменив, либо дополнив в зависимости от собственных нужд. Кстати, контроллеры ST7735 бывают разных модификаций, и там могут быть отличия в процедуре конфигурирования. Если возникнут проблемы, пишите на форум, будем решать:
Содержание
1. Как можно использовать несколько мониторов
Пользователи в домашних условиях могут использовать несколько мониторов для следующих целей:
- работа в нескольких приложениях
- разработка программного обеспечения
- расширение рабочего пространства
- расширение игрового пространства
- просмотр видео на большом экране
- использование ПК для мониторинга в трейдинге
- использование ПК несколькими пользователями
Примером одновременной работы в нескольких приложениях может быть – открытый текстовый документ с данными на одном экране и перенос из него информации в другой формат (таблицу или базу данных).
Также довольно удобно использовать несколько дисплеев для разработки программного обеспечения и веб-проектов – на одном происходит работа с исходным кодом, на другом вы сразу же видите изменения.
Если вы работаете с большими чертежами или 3D-моделями, то за счет нескольких мониторов можно расширить рабочее пространство. Или можно просто на одном экране работать, а на другом следить за изменениями на сайтах или любой другой информацией.
С использованием нескольких мониторов для расширения поля зрения в играх не все однозначно. Во-первых, это серьезная дополнительная нагрузка на видеокарту из-за более высокого разрешения, поэтому она должна быть достаточно мощной. Во-вторых, вы будете видеть шов между дисплеями, что будет мало приятно.
Но, в принципе, если соединить несколько безрамочных дисплеев, последний недостаток можно сгладить. Особенно полезным расширение игрового пространства будет в авиа и гоночных симуляторах.
Но второй монитор в играх можно использовать и иначе. Например, играть в MMO RPG в несколько окон, или на одном играть, а на втором следить за торговцами, общаться в чате на форуме или держать открытой вкладку с полезной информацией о прокачке.
Что касается фильмов, то основной проблемой будут рамки между экранами, но при использовании безрамочных дисплеев можно создать настоящий домашний кинотеатр с огромным экраном. Хотя это вряд ли будет экономически оправдано, только если у вас уже есть один безрамочный дисплей и докупить второй. В противном случае проще и возможно дешевле будет купить большой телевизор. Исключение составляет тот случай, если вы будете использовать несколько экранов не только для просмотра видео, но также для работы и возможно для игр.
А вот в трейдинге выбора, пожалуй и нет, создание 4-8 дисплейной конфигурации является единственной возможностью, чтобы одновременно следить за основными трендами.
Тут весь вопрос в том как подключить мониторы – купить много дешевых видеокарт или несколько подороже, но с большим количеством разъемов или отдать предпочтение специализированному решению для мультидисплейных конфигураций. Об этом мы поговорим чуть позже.
Некоторые пользователи, у которых в силу ограничения бюджета или пространства, есть один компьютер на двоих, рассматривают возможность подключения второго монитора для одновременного использования ПК несколькими пользователями. Такое вполне возможно, но с некоторыми ограничениями, о чем мы также расскажем.
Подключение дисплея на базе ST7735.
Начинаем традиционно - с аппаратной части и подключения дисплея. У меня есть в наличии несколько десятков дисплеев, но преимущественно разрешением 128*160 пикселей. Такой и возьму:
Дисплей имеет 14-ти контактный шлейф для коммутации, его распиновка выглядит следующим образом:
- NC - Not Connected
- GND
- LED K - катод светодиодов подсветки
- LED A - анод светодиодов подсветки
- GND
- RST - сигнал сброса
- D/C - сигнал выбора передачи данных или команд
- SDA - SPI MOSI
- SCK - SPI SCK
- VCC - напряжение питания
- IOVCC - источник питания внутренних интерфейсов
- CS - Chip Select
- GND
- NC - Not Connected
К слову, в разных схемах/статьях/алиэкспрессах обозначение может незначительно, но отличаться. Например, сигнал D/C часто обозначают как RS.
Собрав по-быстрому, "на коленке", плату для подключения дисплея, получаем следующий вариант коммутации:
У меня выбранные ножки фиксированы разводкой платы, а так можно использовать, естественно, любые другие. На подсветку (LED K и LED A) я подключил 3.3 В напрямую (благо источник питания позволяет, потребление светодиодов подсветки на моем дисплее - в районе 40 мА на 3.3 В), то есть подсветка будет работать перманентно. А в обычных проектах я подключаю примерно так:
Соответственно, так мы имеем возможность, во-первых, отключить подсветку, когда требуется, а, во-вторых, управлять яркостью, подавая, например, ШИМ-сигнал разной скважности с микроконтроллера.
В качестве управляющего контроллера у меня STM32F103RE. Пока не забыл, немаловажный нюанс - у меня стоит на этой плате кварц на 12 МГц, можно сказать, что величина нестандартная, так как в подавляющем большинстве случаев используется 8 МГц, ну или реже - 16 МГц. Поэтому обратите на это внимание в настройках тактирования при портировании проекта на свое железо.
Для выдачи данных на дисплей используется интерфейс SPI, причем дисплей только принимает информацию, не передавая ничего в обратном направлении. Это мы учтем при инициализации периферии чуть ниже. Кроме того, потребуются три порта ввода-вывода для подключения линий Chip Select, Reset, D/C. Последняя нужна для информирования дисплея о том, являются ли передаваемые байты данными или командой. Но и с этим мы разберемся чуть позже - при написании библиотеки для работы с ST7735.
5. Какие видеокарты выбрать и в чем их отличие
В общем, если вам просто нужно вывести изображение на несколько мониторов (офис, трейдинг), то самый простой и бюджетный вариант это несколько самых дешевых офисных видеокарт, плюс использование видео разъемов материнской платы. Модель и производитель здесь не имеют особого значение, обратите только внимание на то сколько мониторов поддерживает видеокарта.
Если же вас хоть немного интересуют игры или видеомонтаж, то стоит отдать предпочтение игровым видеокартам начального или среднего класса. Что касается выбора между nVidia и AMD, то стоит учитывать несколько особенностей.
У видеокарт nVidia есть универсальные ядра CUDA, которые можно использовать в различных расчетах. Учтите это, если вы работаете с приложениями, которые могут использовать это преимущество.
У видеокарт AMD в свою очередь есть ограничение – при подключении нескольких мониторов, хотя бы один должен подключаться к разъему DisplayPort, у nVidia этого ограничения нет. Если вы не уверены, то лучше отдать предпочтение nVidia – это более универсальный вариант.
Если же у вас уже есть мощная видеокарта (или ноутбук), и не получается подключить несколько мониторов, то отличным решением будет использовать мультидисплейный адаптер. Он качественно выведет изображение на 2-3 экрана и позволит использовать всю мощь дискретной графики.
Если вы занимаетесь 3D-моделированием, то лучше построить систему на основе одной или двух профессиональных видеокарт, в зависимости от того сколько мониторов вы планируете подключать, сложности проектов и бюджета. Если проекты у вас не сложные, то дешевле будет купить 2 видеокарты начального уровня. Если же вы работаете с серьезными 3D-моделями, то лучше предпочесть одну более мощную видеокарту.
Ну и последний наиболее простой и надежный, но при этом и более затратный вариант – использование специализированной видеокарты для создания мультидисплейных инсталляций от Matrox. Если вы создаете стенд для наблюдений за различными процессами и бюджет позволяет, то почему бы и нет.
Библиотека для работы с ST7735.
Давайте перейдем к созданию проекта. В STM32CubeMx настраиваем необходимую периферию, которую мы уже, в принципе, всю обсудили:
Тактовые частоты с учетом моего резонатора на 12 МГц такие:
А настройки SPI:
DMA в базовом проекте использовать не будем, но я обычно рекомендую не пренебрегать возможностями контроллера. И, соответственно, для перебрасывания больших объемов данных задействовать DMA.
Итак, меньше слов, больше дела, генерируем проект и сразу добавляем в него файлы для будущей библиотеки ST7735:
Начинаем с необходимых определений в файле st7735.h. Первым делом несколько цветов, чтобы наши тесты были более наглядными:
Второе в списке необходимых дел - выбор портов для взаимодействия с дисплеем:
Зафиксируем также размеры используемого дисплея. Для моего 128*160:
Далее в файле идут всяческие определения команд/регистров, полный код файлов и ссылку на готовый проект можно будет найти в конце статьи. А пока продолжаем с библиотекой. И далее наши конструктивные действия будут сосредоточены в файле st7735.c. Чтобы использовать hspi1 добавляем:
Начинаем последовательно с самого низкого уровня реализовывать необходимые функции. И первая из них - это отправка байта по интерфейсу SPI:
Контроллер ST7735 может ожидать от нас либо байт команды, либо байт данных. С точки зрения SPI в этих случаях все одинаково, отличается лишь уровень сигнала на D/C:
Инициализация дисплея.
Переходим к инициализации дисплея. Я приведу полный код из одного из своих проектов, его можно использовать в качестве отправной точки, изменив, либо дополнив в зависимости от собственных нужд. Кстати, контроллеры ST7735 бывают разных модификаций, и там могут быть отличия в процедуре конфигурирования. Если возникнут проблемы, пишите на форум, будем решать:
Отрисовка графических примитивов.
В качестве наглядного эксперимента будем выводить на дисплей основополагающую фигуру - прямоугольник. Задавать аргументами будем:
- cStart , rStart - координата левого верхнего угла
- cStop , rStop - координата правого нижнего угла
- color - цвет заливки
В целом, тут ничего нового:
- Устанавливаем рабочую область при помощи ST7735_SetColAddr() и ST7735_SetRowAddr()
- Далее та команда, о которой я упоминал - ST7735_SendCommand(ST7735_RAMWR)
- Рассчитываем размер области в пикселях
- Разбиваем 16 бит цветовой информации на байты и выдаем на SPI для каждого пикселя. Соответственно, цвета всех пикселей у нас будут одинаковыми, заливка сплошная и однородная.
Ну и все, запускаем тестирование. Для этого будем рисовать прямоугольники размером на весь дисплей разных цветов. В main.c в цикле while(1) добавляем (напоминаю, что полный код под спойлерами в конце статьи):
Само собой не забываем про инициализацию ST7735:
Компилируем и прошиваем. Результат выглядит следующим образом:
Добавляем соответствующий код. Причем его уже нет смысла вызывать из цикла, поэтому сразу после инициализации дисплея вызываем:
И полученный результат соответствует нашим планам:
Я изначально собирался описать еще процесс вывода изображения на этот дисплей, но и эта статья получилась гораздо длиннее, чем я планировал, и с выводом изображения есть свои нюансы, поэтому будет в ближайшие дни вторая часть, а на сегодня на этом заканчиваем 🤝
6. Режимы работы нескольких дисплеев
Мониторы, подключенные к ПК, могут работать в нескольких режимах, самый простой из которых – дублирование экранов. При этом на все дисплеи выводится одинаковое изображение (как при подключении через сплиттер, но тогда оно еще и ухудшается в качестве). Этот режим обычно используется для вывода изображения на телевизор для просмотра видео или с ноутбука на монитор для работы на большом экране.
Второй режим – расширение рабочего стола, в нем все рабочее пространство равномерно делится на все подключенные дисплеи. При этом вы можете перетаскивать любое окно на нужный экран и расположить их как вам будет удобно. В этом режиме также можно растянуть одно окно на несколько экранов, что будет полезно при работе с большими проектами (проектирование, видеомонтаж), просмотра видео и в играх. В общем этот режим достаточно гибкий и позволит вам выводить изображение как угодно.
Все настройки (расположение, разрешение, режимы работы) мониторов находятся в оснастке «Параметры» на вкладке «Дисплей». Здесь можно менять расположение экранов простым перетаскиванием мышкой.
А чуть ниже можно выбирать параметры и режимы работы нескольких дисплеев, все делается очень просто и интуитивно.
Что касается одновременного использования компьютера несколькими пользователями, то это возможно, но с некоторыми ограничениями. Например, один пользователь может работать, играть, лазать по сайтам в интернете, а другой в это время смотреть кино онлайн. При этом возможно использования каждым пользователем не только монитора, но и своей мышки, клавиатуры и даже наушников (каждый будет слышать свой звук). Но такое применение ПК предполагает, что один из пользователей будет в пассивном режиме с редким использованием устройств ввода (мышки, клавиатуры), так как они работают синхронно.
Возможно, есть другие сценарии использования и возможности соединения дисплеев, если у вас есть такой опыт, поделитесь им в комментариях
Видеокарта Gigabyte GeForce GT 710 GV-N710D3-2GL
Видеокарта Asus GeForce GT 710 GT710-SL-1GD5
Видеокарта MSI GT 710 1GD3H LP
Железо
В-третьих, некоторые дисплейные модули и вовсе выше всяческих похвал –
2-4inch-TFT-LCD-module-touch-panel-SD-card-cage
За 18 баксов мы получаем полностью законченный дисплейный модуль, включающий в себя дисплей 320х240 с контроллером, на который есть полная документация (обратите внимание, на контроллеры дисплея от многих мобильных телефонов документацию найти очень проблематично), резистивный тачскрин с контроллером (то есть он уже подключен, можно сразу запрашивать координаты по SPI), удобный разъем, и – как бонусный довесок – слот под микро-SD.
Также на борту стоит повышающий преобразователь для питания подсветки.
Поэтому в данный момент, я, конечно, считаю дисплеи с е-бей наиболее удобным и правильным вариантом.
Наконец, последний вариант, который мне бы хотелось отметить, это вот такие занятные девайсы:
1-5-lcd-rechargeable-digital-usb-photo-frame-keychain
Это чудо китайских технологий представляет собой миниатюрную цифровую фото-рамку. Как выяснилось, несколько зарубежных энтузиастов уже копались в ее недрах, и выяснили, что строятся они на 6502-совместимом микроконтроллере ST2203U, прошивка коего фиксируется при производстве, поэтому нам он не интересен. Зато, менее чем за 200р мы получим 128х128 STN ЖК-дисплей (большинство из них построены на контроллере PCF8833), микросхему флеш-памяти, литий-ионный аккумулятор со схемой контроллера заряда и удобный корпус для своего девайса.
И все же, остановимся пока на первом варианте, то есть — дисплее от мобильного телефона.
Согласно информации, взятой с просторов интернета, из небольших цветных ЖК-дисплеев популярностью пользуются дисплеи от Nokia ХЗ и Siemens S(K)65. По первому дисплею довольно много информации, но сам он уступает дисплеям от сименса в качестве изображения, разрешении, а главное – во времени отклика, которое делает его почти непригодным для воспроизведения анимации. А нам с вами не интересно выводить статические картинки, так ведь? Второй дисплей, судя по данным из интернета, предоставляет нам разрешение в 132 х 176 пикселя и время отклика, достаточное, для вывода анимации. Впрочем, возможности сравнить эти два дисплея у меня, к сожалению, не было – т.к. у меня завалялся старый Siemens SK65, выбор был однозначно сделан в пользу него.
Первые грабли подстерегают нас при покупке самого дисплея. Дело в том, что сименс устанавливает в свои S65 дисплеи на контроллерах трех разных производителей, LS020xxx, LPH88xxxx, L2F50xxx.
Про третий я не слышал вообще ничего, на второй есть официальный даташит, но, похоже, этот контроллер намного менее распространен.
А вот первый, LS020xxx — это тот контроллер, который чаще всего стоит в мобильниках, и мой SK65 не оказался исключением.
Казалось бы – все замечательно, но тут кроется один неприятный факт: на контроллер даташита нет. Таким образом, разрабатывать придется без официального документа, в котором бы были описаны команды и регистры. Но не все так плохо – умельцы провели сеанс реверс-инжениринга и определили основы взаимодействия с дисплеем, и информации о нем в интернете очень немало.
Рассмотрим дисплей подробнее.
Дисплей LS020xxx
Первое, что бросается в глаза – весьма удобные контактные площадки, подпаяться к которым куда проще, чем к мелким разъемам на большинстве дисплеев. Правда, расположены они на гибко-жесткой печатной плате, которую, при неосторожном обращении, можно поплавить паяльником, так что при пайке ставим температуру паяльника поменьше.
Всего дисплей имеет 10 контактов:
- RS – сигнал переключения команда / данные
- RESET – сигнал сброса дисплея
- CS – сигнал выбора устройства SPI
- CLK – тактовый сигнал SPI
- DAT – сигнал MOSI SPI
- 2.9V и 1.8V – питание дисплея
- LED+, LED_GND – питание и земля цепи подсветки
- GND – земля дисплея.
На контакты LED+ и LED_GND подается питание подсветки дисплея, которое может составлять от 10 до 20 вольт. Это питание подается на 3 светодиода, ток через них регулируется схематикой контроллера, так что к ним безбоязненно можно подключить одну-две 9В батарейки без токоограничительных резисторов. Я подключил две последовательно включенные, слегка подсевшие, кроны, получив напряжение около 17В.
Контакты 1V8, 2V9 и GND обеспечивают питание схем дисплея. Что интересно, во многих схемах подключения можно увидеть пин 1V8 вообще никуда не подключенным. Во всех остальных схемах пины 1V8 и 2V9 соединены вместе и подключены к источнику 3.3В. Это подключение оказалось вполне работоспособным, поэтому так и поступим.
Пины CS, DAT, CLK являют нам тривиальный SPI интерфейс без ответного провода. Этот факт не может не радовать, т.к. даже на AVRках имеется в наличии аппаратный SPI-контроллер, а STMки и вовсе богаты на периферию подобного рода – в младших моделях этих контроллеров два, в старших – аж 4 штуки, поэтому один из SPI можно выделить всецело для общения с дисплеем.
Пины RS и RESET – два дополнительных управляющих сигнала для дисплея. Первый, находясь в активном уровне (лог 0) индицирует о том, что мы передаем дисплею команды, а в неактивном (лог 1) – данные. RESET, как следует из названия, предназначен для сброса контроллера.
Теперь нам требуется подключить дисплей к нашей отладочной плате при помощи макетки. Для этого мной был выбран шлейф с 10-контактным IDC-разъемом.
Свой тактический промах я понял когда уже подпаял шлейф – дело в том, что на макетке горизонтальные гнезда соединены между собой, поэтому ряды разъема оказываются закороченными. Как бы то ни было, другого разъема у меня все равно не было, так что пришлось вносить поправки в виде «ножек» из проволоки — т.к. макетка представляет собой три независимые секции, подключив разъем на границе секций удалось избежать замыкания.
Тем, кто будет повторять мои эксперименты все же советую взять однорядный 10-контактный разъем, проблем будет меньше. После того как шлейф обжат, его следует подпаять к контактам дисплея – напоминаю о том, что пленка, на которой расположены контакты, не очень любит длительное воздействие высокой температуры, так что стараемся паять быстро и четко.
После пайки размещаем разъем на макетной плате и начинаем соединять перемычками с контроллером. Пины питания подсветки сразу же отводим куда подальше, втыкаем туда разъем от кроны и забываем о них. У кого есть источник питания на 10-20В – еще лучше, не придется постоянно отключать батарейки в целях экономия энергии.
Далее соединям SPI-интерфейс. Отладочную плату в макетку удалось установить только свесив горизонтальные пины (по уже описанной причине перемыкания), которых, к счастью было немного. Однако среди них оказался интерфейс SPI2, так что в нашем распоряжении остался только первый. Впрочем, нас это не должно сильно расстроить, т.к. больше мы пока и не собираемся ничего к нему подключать. Поэтому соединяем CLK с пином PA7, DAT – с пином PA5. CS будем дергать ручками в соответствии с логикой работы, как и RS с RESETом – поэтому эти три сигнала выводим туда, куда нам удобно. Я выбрал пины PA2, PA3, PA4. В итоге у вас получится что-то вроде этого:
Кстати, небольшой оффтоп: после того, как я все подключил, я выдал тестовый 10КГц меандр на один из пинов. И вот что показал осциллограф:
Канал 2, обозначенный синим цветом, подключен к самому пину. А вот канал 1 (желтый), подключен к соседнему с ним выводу. Видите эти красивые экспоненты с амплитудой почти 100мВ? Все эти перемычки на макетке дают неслабую емкостную связь между пинами. Что характерно, если отладочную плату вытащить из макетки, влияние пракически отсутствует:
Поэтому проектируя устройство будьте бдительны: макетка вносит свою специфику, с котрой надо считаться. Высокочастотные схемы собрать на ней практически невозможно.
После подключения дисплея достаем мультиметр и внимательно проверяем сборку, прозванивая все сигналы, чтобы не грешить на прошивку когда у вас отойдет проводок.
Если все соединено правильно, запускаем Кейл и переходим к следующей части.
Как я уже упоминал, я вернулся к написанию статьи спустя много месяцев после, собственно, экспериментов с дисплеем, поэтому часть кода была потеряна. Но я постарался восстановить важные моменты по памяти. Впрочем, взаимодействие с дисплеем весьма тривиально и не должно вызвать затруднения.
Итак, на данный момент у нас должен быть полностью подключенный к макетной плате дисплей и запущенный Кейл с созданным проектом.
Начнем мы с простого вывода на экран картинки. Так как наша задача сейчас – разобраться с дисплеем, то не будем мудрствовать лукаво и прикручивать загрузку с карточек, чтение файловых систем и т.д. – просто разместим картинку в виде сырых 16-битных RGB-значений во флеш-памяти контроллера. Для этого рекомендую набросать на удобном вам языке программирования программку, которая переведет стандартный bmp-файл в запись вида
Так как разрешение нашего дисплея 132 х 176 пикселей, каждый из которых занимает 2 байта, полная картинка будет занимать в памяти 46464 байт, то есть чуть больше 45 Кб.
К счастью, 500 КБ флеша СТМки позволяют нам сохранить картинку в сыром виде, и даже не одну.
Теперь переходим к программированию дисплея. Больше всего это похоже на черную магию, потому что даташита на контроллер у нас нет, зато есть инструкции от тех, кто реверсил, в которых сразу дается «заклинание» в виде последовательности байт, без объяснения, почему она именно такая. Если вас не устраивает такой подход, то наилучшим выходом будет приобрести какой-нибудь из упомянутых мной дисплеев с е-бея, к которым идет полный комплект документации.
Итак, заклинания.
Дисплей инициализируется следующей последовательностью (очень чувствительной к паузам!):
- Подаем уровень лог 0 на линию RESET и удерживаем его около 5 мс
- Выдаем первое заклинание дисплею, представляющее собой вот такой блок байт:
После этого на дисплее должен возникнуть разноцветный мусор, означающий что инициализация прошла успешно.
Итак, попробуем это все реализовать, попутно вспомнив, как работать с периферией в СТМке.
Я решил заодно испробовать бит-бандинг, для чего сразу объявил три указателя:
Для тех кто не помнит об этой замечательной технике – бит-бандинг это очень полезная фича, представляющая собой мапирование каждого бита ИО-регистров и RAM в дворд где-то в адресном пространстве СТМки. Так как адресное пространство у нас 32-битное, то бишь 4 гигабайта, а реально задействовано намного меньше, разработчики решили потратить несколько метров, на то чтобы связать биты из ИО или RAM (bit-band alias region) с двордами в bit-band region.
Работает это просто – допустим, мы хотим управлять пином CS, который у нас соответствует PA2. Уровнем сигнала на нем управляет бит номер 2 регистра GPIOA->ODR.
Воспользуемся формулой из даташита:
bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)
bit_word_addr – это искомый адрес бит-банда, который требуется вычислить.
bit_band_base для нашего процессора, согласно даташиту, объявлен в хедере в виде
byte_offset – смещение до искомого регистра, в данном случае, до GPIOA->ODR, от начала bit-band alias region.
Так как адрес GPIOA->ODR равен 0x4001080С, а начало периферийного bit-band alias региона объявлено как
То смещение будет равно 0x4001080С-0x40000000 = 0x1080C
И наконец, номер интересующего нас бита равен 2. Собирая все это вместе получаем
*CS = 0x42000000 + (0x1080C)*32+2*4 = 0x42000000+210180+8=0x42210188
Теперь, записав отличное от нуля значение по этому адресу, мы установим связанный с этой ячейкой памяти бит в 1, записав нулевое – в 0.
Три блока байт у нас уже объявлены, проведем инициализацию периферии:
Тут все просто – Reset, CS, RS ставим на выход под управлением нашей программы,
CLK и MOSI – выход под управлением периферии, то есть, в данном случае, контроллера SPI.
SPI настраиваем на частоту Fclk/8 и посылку данных 16-битными вордами вместо байт.
Также следует описать функции задержки и синхронной посылки по SPI, которые, в силу их тривиальности, приводить тут не буду, за исключением прототипов:
Реализация их предельно проста – задержка реализована обычным циклом, синхронная посылка по SPI – выводом посылаемого байта в регистр данных SPI (SPI1->DR=Data;) и ожиданием в цикле до тех пор, пока не пропадет флаг SPI_SR_BSY из статуса SPI1->SR.
Далее выполняем нашу магическую последовательность:
Теперь пришла пора выучить новые заклинания. Итак:
Команда – вывод графической информации на экран, где байт OR обозначает ориентацию экрана при выводе и может быть равен 0х04 в случае горизонтальной и 0х00 в случае вертикальной – именно в этом направлении будут заполняться пиксели. Байты ХХ и YY обозначают позицию нижнего левого угла прямоугольника. Верхний правый угол всегда будет равен пикселю (175, 131).
После следует подавать байты графической информации в том формате, на который был инициализирован дисплей. В данном случае – 16-битные ворды вида 5-6-5 (R-G-B)
Для вывода информации в ограниченную область, команда используется в несколько модифицированном виде:
, где X1, Y1 – координаты нижнего левого угла области вывода, X2, Y2 – координаты верхнего правого угла.
Таким образом, заливка всего экрана черным цветом будет выглядеть вот так:
Ну а теперь выведем, наконец, нашу картинку!
Если все сделано правильно, то мы должны получить вот такой результат:
Зеркально отраженный морпех как бы говорит нам: помни о порядке вывода пикселей!
Заканчивать работу с дисплеем рекомендуют не простым отключением питания, а следующей последовательностью команд:
На этом, в принципе, можно было бы и закончить, но на самом деле, впереди нас ждет самое интересное!
Использование особенностей архитектуры STM32F1xx для оптимизации вывода изображения на экран
- Память-память
- Память-периферия
- Периферия-Память.
Здесь мы настраиваем адрес, по которому будут записаны данные (он равен адресу регистра данных SPI), устанавливаем количество 16-битных слов для передачи, равное 1560 (мои кадры по размеру составляют 30х52 пикселя), средний приоритет передачи,
размер приемника и источника – в данном случае, и тот и другой – 16 бит, направление передачи (из памяти в периферию), устанавливаем автоинкремент указателя на память, и включаем DMA.
После нам следует подготовить несколько кадров в таком же формате, что и описанный раньше const uint16_t Picture[].
Для этого я подготовил 12 хедеров frame01.h … frame12.h, и объединил данные из них в
Также введем переменную-счетчик кадров
Осталось совсем немного – в инициализации настраиваем системный таймер на нужную нам частоту смены кадров,
Осталось описать обработчик прерывания таймера:
Здесь мы вычисляем номер нашего следующего кадра, после чего отключаем DMA-передачу на время. Это необходимо, чтобы передать дисплею команды на вывод графики.
В данном случае выводятся небольшие картинки, не во весь экран, т.к. попросту не хватает памяти контроллера. Если же прикрутить сюда чтение с какой-нибудь SD-карточки, то вполне можно крутить полноэкранное видео.
После того, как команды переданы, мы настраиваем адрес источника графики – один из фреймов, указатели на который хранятся в Video[], устанавливаем размер передаваемого блока и включаем DMA.
Все! Теперь наша программа тратит на вывод графики не более нескольких десятков тактов каждые 50 мс, те самые, что идут на обработку прерывания по таймеру – после того как прерывание будет обработано, DMA начинает передачу данных в регистр SPI без нашего участия! Таким образом мы можем совершенно спокойно заниматься своими делами в основном цикле, готовить следующий кадр, или обсчитывать какие-нибудь объекты, не заботясь о выводе графики.
Если все сделано правильно, получаем следующее:
Заключение
Чего же мы достигли?
Прежде всего, мы научились работать с такой интересной периферией, как цветной графический дисплей. Это уже само по себе неплохо и может пригодиться в проектах.
Но главное – мы научились использовать блок DMA, который открывает широчайшие возможности, по сравнению с софтварной передачей данных на контроллерах, не имеющих такого блока.
Что касается дисплеев, то я хотел бы добавить следующее: на e-bay я нашел отладочную плату, которую без вопросов назову отличным и необходимым инструментом разработчика на STM32. Продается она тут:Mini-STM32
За 45 баксов мы получаем невероятно удобный и мощный инструмент, в который входит микроконтроллер STM32F103VET, с аппаратным USB, контроллером статической памяти, в разы облегчающем работу с дисплеем и аппаратным контроллером SD-карт. Собственно дисплей, с разрешением 320х240 и установленным на нем резистивным тач-скрином, контроллером тач-скрина, буст-конвертером для питания подсветки. Вся необходимая обвязка для USB. RS-232 с конвертером. И батарейка, питающая бек-ап регистры контроллера.
Также, по дополнительному запросу, за 28 долларов в заказ добавят удобный программатор, клон J-LINKа, который, по моим ощущениям, намного стабильнее чем тот, что встроен в отладочную за 300р.
В общем, настоятельно рекомендую всем, кто собирается заниматься STMками приобрести комплект из этой отладочной платы и программатора. Последующие статьи я буду писать уже с использованием Mini-STM32 как основного инструмента.
Так как в данный момент по работе я разбираюсь с весьма занятными радио-модулями, то следующая статья, вероятнее всего будет про них.
Давно в планах висит статья про подключение дисплея на базе популярного контроллера ST7735 к STM32. В общем-то, план был довольно долгосрочный. Но благодаря читателю блога, который поднял эту тему, принято решение кардинально ускорить данный процесс. Так что сегодня об этом и пойдет речь.
Так, задачей нашей будет сделать базовый проект, который позволит с минимальным порогом вхождения начать работу с любым дисплеем на базе ST7735. В дебри настроек погружаться не будем, пересказыванием даташита заниматься тоже, во главе угла - реальная польза от практической реализации. Вот кстати ссылка на подробнейшее pdf описание контроллера - ссылка.
Читайте также: