zoologist 发表于 2024-11-30 13:47:56

基于FireBeetle 2 实现 VGA视频输出

之前有使用FireBeetle(ESP32)实现过 VGA 输出,这次基于 FireBeetle 2 ESP32-S3 的板卡来实现 VGA 的输出。首先进行电路的设计,其中的Hsync和Vsync分别使用 IO1 和 IO2,颜色则通过 R-2R 来实现:PCB 设计如下:3D预览如下:
途中的USB母头是预留给外部供电的,比如,VGA-HDMI转接器通常需要外部供电,这种情况下可以从这个端口取电。焊接之后插入FireBeetle 2 的板子(注意USB接口方向和 VGA接口方向相反):

接下来使用来自 https://github.com/spikepavel/ESP32-S3-VGA的库
运行如下代码#include "VGA.h"
#include <FONT_9x16.h>

VGA vga;

int scale = 2;

void setup()
{
//                   r,r,r,r,r,g,g, g, g, g, g,   b, b, b, b, b,   h,v
const PinConfig pins(4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,1,2);
        Mode mode = Mode::MODE_640x480x60;
       
        if(!vga.init(pins, mode, 8, 3)) while(1) delay(1);
       
        vga.start();

        for(int y = 0; y < 480; y++)
                for(int x = 0; x < 640; x++)
                        vga.dotdit(x, y, x, y, 255-x);

        vga.setFont(FONT_9x16);
        vga.start();
       
        delay(5000);
}

void loop()
{
vga.clear(0);
delay(1000);
for(int count = 0; count < 100000; count++)
vga.dot(rand()%640, rand()%480, rand()%255);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 10000; count++)
vga.line(rand()%640, rand()%480, rand()%640, rand()%480, rand()%255);
vga.clear(0);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 10000; count++)
vga.tri(rand()%640, rand()%480, rand()%640, rand()%480, rand()%640, rand()%480, rand()%255);
vga.clear(0);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 1000; count++)
vga.fillTri(rand()%640, rand()%480, rand()%640, rand()%480, rand()%640, rand()%480, rand()%255);
vga.clear(0);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 10000; count++)
vga.rect(rand()%640, rand()%480, rand()%640, rand()%480, rand()%255);
vga.clear(0);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 1000; count++)
vga.fillRect(rand()%640, rand()%480, rand()%640, rand()%480, rand()%255);
vga.clear(0);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 10000; count++)
vga.circle(rand()%640, rand()%480, rand()%100, rand()%255);
vga.clear(0);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 5000; count++)
vga.fillCircle(rand()%640, rand()%480, rand()%50, rand()%255);
vga.clear(0);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 10000; count++)
vga.ellipse(rand()%640, rand()%480, rand()%100, rand()%100, rand()%255);
vga.clear(0);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 1000; count++)
vga.fillEllipse(rand()%640, rand()%480, rand()%100, rand()%100, rand()%255);
vga.clear(0);
delay(1000);

vga.clear(0);
delay(1000);
for(int count = 0; count < 100000; count++)
vga.mouse(rand()%640, rand()%480);
vga.clear(0);
delay(1000);

for(int count = 0; count < 1000; count++)
{
        static int c = 0;
        static int d = 1;
        c += d;
        if (c == 0 || c == 255)
                d = -d;

        char text[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0
                                  };
       
        for (int i = 0; i < 256; i++)
                text = 33 + (i + (c >> 2));
        vga.setCursor(8, 48);
        vga.setTextColor(vga.rgb(c, 255 - c, 255), vga.rgb(0, c / 2, 127 - c / 2));
        vga.print(text);
        vga.setCursor(8, 148);
        vga.print(text);
        vga.setCursor(8, 248);
        vga.print(text);
        vga.setCursor(8, 348);
        vga.print(text);
}
delay(4000);
}

实践测试发现,这个板卡在不同显示器上会有兼容性问题,可能和选择的分辨率有关系。工作的测试视频https://www.bilibili.com/video/BV1yrzjY4EmG/?share_source=copy_web&vd_source=5ca375392c3dd819bfc37d4672cb6d54



























页: [1]
查看完整版本: 基于FireBeetle 2 实现 VGA视频输出