И отново за VGA интерфейса

Оригиналът е на yamifa_1234, който споделя богатия си опит в тази сфера

2
1166

Бих искал да споделя собствения си опит при извеждането на изображение на монитор чрез VGA интерфейса. Разбирам, че тази задача е решавана многократно, от различни хора и на различно оборудване. Но има още много какво да се каже.

На етажерката събира прах подобна на показаната по-долу платка за отстраняване на грешки, на която няма нищо друго освен FPGA и SDRAM (разбира се, без да броим бутоните, светодиодите и т.н.).

И отново за VGA интерфейса

Налагаше се да направя проект за извеждане на изображение на монитор от платка, която няма подобен интерфейс и се налага да избирам между HDMI, DVI и VGA. Имах идея за проект, в който трябваше да извеждам изображение на монитор; бих казал, че неразделна част от проекта е извеждането на монитора. Тъй като на платката няма интерфейс, трябваше да избирам между HDMI, DVI и VGA. Предварително ще кажа, че макар интерфейсите да са различни, те по същество осигуряват едно и също нещо: три цветни линии (червена, синя, зелена) и два сигнала за синхронизация – синхронизация по редове и синхронизация по кадри.

Преглед на вариантите

HDMI

И отново за VGA интерфейса

След като прочетох за този интерфейс, се оказа, че той е сериен, което означава, че ако вземете резолюция на екрана 640×480 пиксела при кадрова честота 60Hz, изходната честота на пикселите е около 25MHz, а след серийния модул – всичките 250MHz. Освен това този интерфейс изисква TMDS модул, а аз изобщо не исках да се занимавам с него, така че на този етап разглеждането на този интерфейс бе спряно.

DVI

И отново за VGA интерфейса

Този интерфейс има няколко режима. Двата основни са цифров (DVI-D) и аналогов (DVI-A). Аналоговата опция по принцип е същата като опцията VGA, затова ще бъде разгледана по-късно. В рамките на този интерфейс, както и при HDMI, има LVDS линии, които също налагат използването на сериализатор и енкодер. Затова по същите причини (мързел) ще пропусна и този интерфейс.

VGA

И отново за VGA интерфейса

Вероятно най-опростеният и най-старият интерфейс (също и част от DVI-A). За да се изведе изображение, трябва да се генерират три нива на цвят (червен, син, зелен) и два синхронизиращи сигнала (прогресивен и кадър по кадър). И в този основен вариант вече могат да се получат 8 различни цвята. На изображението по-горе е показано разположението на изводите на интерфейса VGA при свързване към FPGA и предложения китайски модул с VGA. На входа на модула има три 8-битови цветови шини и два синхронизиращи сигнала (модулът има два чипа с повторители на сигнала и масив от резистори за формиране на нивото). Естествено, китайският модул е красив и удивителен, но аз тръгнах по друг път – реших да сглобя всичко сам.

Реализацията

След като прочетох няколко статии в интернет по темата за извеждане на изображението на монитора, забелязах редица основни особености:

  • VGA интерфейсът има стандарт за изхода (очевидно е, но все пак). Всеки режим има своя собствена продължителност на невидимите части на полето, честота на извеждане на пикселите и полярността на синхронизиращите сигнали. Така например за разделителна способност 640×480 полярността на тактовите сигнали 60Hz и 100Hz е различна
  • В много статии се набляга, че невидимите зони отдясно и отляво на работната зона трябва да бъдат ясно разделени.

И отново за VGA интерфейса

И отново за VGA интерфейса

Този метод е малко труден за разбиране и реализация, затова реших да използвам друго представяне:

И отново за VGA интерфейса

Активната област се премества в горния ляв ъгъл, а полетата се показват отдясно и отдолу.

  • Друг основен момент е, че нивото на RGB сигналите е 0,7 V при входно съпротивление 75 Ω, но това разбрах по-късно
Житейски опит № 1

Въз основа на разположението на изводите (показано по-горе) могат да се използват 8 различни цвята. Реших да използвам разделителна способност 640×480 с честота на кадрите 60Hz, като според стандарта е ясно, че общата площ е 800×525 пиксела. Алгоритъмът за извеждане е изключително опростен, с два вертикални и хоризонтални брояча. Линиите се изчертават хоризонтално линия по линия (това е добре известен факт) и докато броячите са в рамките на работната област (640×480) – изображението се извежда.

Ако по отношение на алгоритъма всичко е ясно, в стандарта се посочва и честотата на пикселите. Тя е 25,175 MHz. На този етап вече започва да се усеща болка. В много примери за проекти с PLL на Altera е било възможно да се генерира широк диапазон от честоти, но в моя случай PLL бе ограничен и не искаше да даде това, което ми трябваше. Чрез болка и страдание поставих двата PLL последователно и получих 25,185 MHz. Като цяло допустимата грешка не е много голяма – около 0,04% (на този етап си помислих, че честотата трябва да е точно както казва стандартът, иначе картината ще е плаваща или изобщо няма да се синхронизира). Но както се оказа, не бях прав…).

В крайна сметка получих заветните осем ивици:

И отново за VGA интерфейса

Докато си играех, установих, че въпреки че стандартът VGA има сигнали за синхронизация, без които картината не се извежда (проверих по-късно…), а и никак не е добре картината да завършва с черна лента. Веднага се разваля синхронизацията и мониторът я счита за невидима област и я скрива, оставяйки само 7 ленти. След като прочетох по темата и зададох неудобни въпроси на различни хора, се оказа, че някои монитори се синхронизират и по един от цветовете.

Житейски опит № 2

Осемте цвята не ми бяха достатъчни и като цяло нямах достатъчно ивици на монитора. Но тъй като свързах интерфейса директно, в крайна сметка получих еднобитов цвят. След известно обмисляне реших да разширя диапазона с помощта на ШИМ. Вдигнах честотата на модула до 100,74 MHz и се опитах да формирам RGB сигнали с различни ширини на импулсите.

И отново за VGA интерфейса

Мониторът се оказа по-умен от мен. Първия път той успя да се адаптира към моя ШИМ и създаде същата гладка картина като първия път, когато го пуснах без използване на ШИМ. Но след редица насилствени мерки мониторът все пак реагира само че за съжаление не получих цветен градиент. Получих накъсани ивици. На изображението се опитах да направя 4 ленти с различна широчина на импулса. Първата лента е без ШИМ, втората е с 25%, третата – с 50%, а четвъртата – със 75%. След като се поразрових в този вариант, осъзнах, че ще трябва да направя един нормален ЦАП.

Житейски опит № 3

От института знаех, че има ЦАП на резистори, и че това е най-бързият ЦАП; с недостатъка, че е необходимо резисторите да бъдат подбрани възможно най-прецизно, като резултатът зависи от тази прецизност. В моя случай точността не е важна, най-важното е да изглежда вярно. Схемата на ЦАП от типа R-2R е добре известна в интернет и изглежда по следния начин:

И отново за VGA интерфейса

Взех поялник и комплект резистори 1 КΩ и 2 КΩ и се заех с работата. Направих 5-битов ЦАП. Резултатът е следният:

И отново за VGA интерфейса

След като свързах няколко кабела, го стартирах:

И отново за VGA интерфейса

Снимката е направена в пълен мрак. Отне ми известно време да се сетя да изгася осветлението и не осъзнах какво съм направил погрешно. Когато проверих запояването с мултицет, видях, че напрежението в ЦАП-а се променя, ако на входа приложа различна стойност. Тогава забелязах, че мониторът не е равномерно черен, а сякаш е разделен на сектори, и тогава изключих светлината. Отново започнах да задавам серии от въпроси, които ме накараха да се почувствам най-неудобно, защото разбирам темата и защо не се бях сетил за това сам, не знам. А проблемът беше в това, че съпротивлението на приемника (в монитора за всеки RGB ред) беше 75 Ω, а аз свързах ЦАП със съпротивление повече от 2 КΩ. В резултат на това генерираното напрежение в приемника не надхвърляше 123mV (в най-добрия случай), докато на мен ми бяха необходими 700mV.

Отново отворих браузъра, за да проуча въпроса – какъв ЦАП ми трябва, за може изображението да отговаря на очакваното от мен. Едни от вариантите бе същият R2R ЦАП, но с резистори с много по-малко съпротивление – от около 70-150 Ω. Вторият вариант не с паралелно свързани резистори. Ето я схемата:

И отново за VGA интерфейса

Този метод се използва в много платки за дебъгване, като например платката Altera. Естествено, без да се замислям много, направих подобен ЦАП с 5 бита на цвят:

И отново за VGA интерфейса

И като резултат се получи първият адекватен резултат:

И отново за VGA интерфейса

На фигурата са показани 32786 нюанса (всеки цвят – син, зелен и червен – има 32 нива на яркостта).

И отново за VGA интерфейса

Житейски опит № 4

Сега остава нищо работа – само да настроим механизма за извеждане на изображението от буфера на паметта. Свързах чип SDRAM памет и описах автоматизма, който го запълва с кадър с градиент, подобен на тези по-горе. Описах и автоматичната процедура, която чете кадъра от паметта и го изпраща към модула с VGA изход. Като цяло всичко проработи от първия път (е, знаете какво имам предвид – нищо не работи от първия път). Но тук трябва да се разбере, че всичко се получи без изпиляване на нервите.

Като цяло изображението си е там, то е статично, което е индикация, че се актуализира правилно в паметта, и не е плаващо, така че прочитането е адекватно. Но ако се вгледате внимателно, ще видите вълнообразни линии по границата на градиентите.

Тук трябва да се разбере, че проектът ми вече се е разраснал – добавих SDRAM контролер, няколко автомата, FIFO, обработка на бутони и мигане на светлини (като част от дебъгването), както и ChipScope. Тоест, когато описвах VGA модула отделно, нямаше нищо допълнително и границите бяха равни, но ето че се това чудо се появи – и имам нова купчина въпроси.

След дълга дискусия по темата бе изразена идеята, че е необходимо да се премахнат двата последователно свързани PLL-а. Първо, платката е китайска и е малко вероятно осцилаторът с честота 50 MHz да дава идеални стойности. Освен това самият PLL внася допълнително трептене, а като се има предвид, че има два PLL модула, ефектът на трептене става много по-забележим.

В този момент изгубих представа откъде да взема 25,175 MHz (които стандартът изисква), след като PLL-ът не може да го осигури. В отчаянието си предприех отчаяната стъпка (според мен) да настроя изходната честота на пикселите на 25 MHz (използвайки един PLL) при 640×480@60Hz. В крайна сметка всичко започна да работи, приятно и гладко. За пореден път осъзнах, че мониторът е много по-умен, отколкото си мислех!).

След това описах UART интерфейса, написах програма на QT за зареждане на изображението чрез UART на FPGA и успях да заредя първия си миньон там!) Ето го миньона:

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

Кодът

Модулът чете 16 бита данни от FIFO, конфигуриран в режим AXI-Stream. От които долните 15 бита са RGB, а горните 16 бита се използват за синхронизиране на кадъра между модулите. Само в случай, че има загуба на данни или някаква повреда, модулът за VGA интерфейса извършва синхронизация по старшия бит. Той се вдига в края на кадъра, като се изпълнява нещо като своеобразен last.. Модулът реализира VGA формат 640×480@60 Hz по индустриален стандарт (тактова честота на пикселите 25,175 MHz). За да се адаптира към други режими, е необходимо да се определят полярността на синхронизиращите импулси и размерът на изходната област.

АбонаментВсичко важно от света на технологиите, директно в пощата ти.

С абонирането приемате нашите Условия и Политика за поверителност. Може да се отпишете с един клик по всяко време.


Коментирайте статията в нашите Форуми. За да научите първи най-важното, харесайте страницата ни във Facebook, и ни последвайте в Google Новини, TikTok, Telegram и Viber или изтеглете приложението на Kaldata.com за Android, iPhone, Huawei, Google Chrome, Microsoft Edge и Opera!

2 Коментара
стари
нови оценка