Наконец то руки дошли и до VGA.
Глобальная идея такова — выбираете разрешение, которое нужно отрисовать, для себя я выбрал 800х600 72Hz. Далее ищем характеристики выбранного разрешения, хорошо гуглится по фразе «pixel clock vga».
Line: 1040 px Front porch 56 Sync pulse 120 Back porch 64 Visible area 600 Front porch 37 Sync pulse 6 Back porch 23 Whole frame 666 |
Почему я выбрал именно такое разрешение? Потому что проверял на своей платке, о которой писал в прошлом посте. Так как там стоит CPLD EPM570 на нем нет PLL, поэтому пришлось исходить из того, что pixel clock (скорость отрисовки пикселя) будет равен тактовой частоте генератора. Если посмотреть на список стандартных разрешений и генераторов, которые можно свободно купить, то 50МГц более всего подходит.
Рисуется линия сама по себе достаточно просто, исходно на ногах h_sync и v_sync логическая единица. Вся линия 1040 пикселей, из них видимая часть 800. Поэтому нужно завести счетчик, который увеличиваем каждый тик генератора. От нуля до 800 рисуем все что нам нужно, просто выставляя на ногах RGB напряжение. В моем случае можно было получить только максимальную яркость одного канала, т.е. смешивая их можно получить максимум 8битное изображение, но если поставить ЦАП и изменяя напряжение от 0 до 0.7В можно менять яркость канала.
Начиная с 800 пикселя нужно выждать front porch, т.е. тупо ничего не делать в течение 56px, а затем в течение 120px нужно прижать к земле ногу h_sync. Затем снова поднять и 64 пикселя потупить. Все линия отрисована. Переходим к следующей и так пока не будет отрисовано 600 строк. Начиная с 600 тупим 37 строк, затем 6 строк v_sync и потом еще 23 тупежа. Все кадр отрисован. Естественно если вы выберете другое разрешение, то все цифры у вас будут другими, но общая суть не поменяется.
Схема подключения простая: сигналы RGB, т.е. 1, 2, 3 пин подключаем через резистор 270 Ом, при логическом уровне 3.3В. Пины 5, 6, 7, 8, 10 на землю 13 — hsync, 14 — vsync, т.е. от CPLD понадобится 5 ножек.
Мне не хотелось заморачиваться, поэтому для теста отрисовываем 200 строк красного, 200 зеленого и 200 синего. Если придумаете, что то лучше, то милости просим)
module vga_tst(clk, v_sync, h_sync, vga_r, vga_g, vga_b); input clk; reg [11:0]h_cnt; output reg h_sync; reg [10:0]v_cnt; output reg v_sync; reg h_en; reg v_en; output reg vga_r; output reg vga_g; output reg vga_b; //блок синхронизации always @ (posedge clk) begin if ((h_cnt > 855) && (h_cnt < 976)) h_sync <= 0; else h_sync <= 1; if ((v_cnt > 637) && (v_cnt < 643)) v_sync <= 0; else v_sync <= 1; end //Увеличение счетчиков по горизонтали и вертикали always @ (posedge clk) begin if(h_cnt > 1039) begin h_cnt <= 0; if(v_cnt > 665) v_cnt <= 0; else v_cnt <= v_cnt + 1'b1; end else h_cnt <= h_cnt + 1'b1; end //Разрешаем/запрещаем отрисовку вне видимой зоны always @ (posedge clk) begin if(v_cnt < 599) v_en <= 1'b1; else v_en <= 1'b0; if(h_cnt < 799) h_en <= 1'b1; else h_en <= 1'b0; end //отрисовка линий always @ (posedge clk) begin if((v_en == 1) && (h_en == 1)) begin if(v_cnt < 200) // красная vga_r <= 1; else vga_r <= 0; if(v_cnt > 200 && v_cnt < 400) vga_g <= 1; // зеленая else vga_g <= 0; if(v_cnt > 400 && v_cnt < 600) vga_b <= 1; // синяя else vga_b <= 0; else begin vga_r <= 0; vga_g <= 0; vga_b <= 0; end end endmodule |
Самая долгожданная статья. Автор, респект тебе!!! теперь пора мне учиться работать с ПЛИС))
Спасибо большое !Побольше бы проектов с ПЛИС!!