2025年2月更新,Step to UEFI 文章索引:
Windows 11安装时创建本地账户的方法
在安装界面输入如下命令
start ms-cxh:localonly
具体操作可以参考如下视频:
Step to Memory 000 内存常识
作为一名BIOS工程师,内存是无法回避的问题。最近在看一些内存的知识,忽然发现如果想理解现在的设计,那么必须去阅读过去的设计,这样才能知道为什么设计成今天的样子。而这一段让我想起来那一句名言:“He who controls the past controls the future.”
这一系列文章将从个人视角尝试介绍和理解x86 消费级内存相关知识。
首篇献给 《PC 内存的秘密》系列文章。需要注意的是这篇文章发表于2007年,其中一些知识已经发生了变化,在对应的位置我会标记出来。
《PC 内存的秘密 第一部分》原文来自 https://www.bit-tech.net/reviews/tech/memory/the_secrets_of_pc_memory_part_1/1/
第一章 基础知识
前言
作者:Richard Swinburne
Ryan Leng 是计算机系统领域的独立技术顾问和审计师,为公司提供硬件、软件、网络、安全、IT 政策制定和培训方面的服务。
他最初接受的是计算机科学和经济学方面的培训,之后从事了许多领域的工作,包括计算机硬件集成、软件设计和工程、监控系统、广告、多媒体制作、用户界面工程和图形设计。不久前,
Ryan 带着他尚未出版的关于 DDR 技术的书籍与bit-tech
进行了接触,我们读到这本书时,对其深度和对细节的关注以及能够以易于理解的方式传达复杂的想法印象深刻。 无论您是否精通内存技术知识,对于 PC 架构的基本部分来说,这仍然是一本有趣的读物。我们将他的工作分成几个部分,我们在此处发布的第一部分涵盖了基础知识。此处发布的信息仅仅是一份更大文档的摘录。
Ryan 解释道:“本文旨在与大家分享我关于内存技术的知识和经验,尤其是我广泛使用过的双倍数据速率 (DDR) RAM。本文讨论了许多主题,包括代际差异、趋势、DDR 信号管理技术、系统优化策略、内存兼容性问题和购买注意事项。
我还希望帮助解释一些内存相关技术,这些技术可能在某些在线社区和“技术”网站中解释得模糊或不正确。为了使本文更易于理解,最重要的是,更容易让普通读者理解,我删除了许多细节和高度技术性的信息。
本文开始于研究华硕、升技、映泰、友通、海盗船、金士顿、威刚等产品的严重 DDR2 内存兼容性问题(800MHz 及以上)。DDR 内存技术的不确定性不断增加,内存系统设计人员一直都知道这一点,并且发现缓解和解决这些问题越来越具有挑战性。
为什么这对普通用户和爱好者很重要? RAM 稳定性问题和超频限制是相辅相成无法分割的。【最简单的理解是:如果你手上的6400Mhz内存,通过某种稳定的超频设置可以稳定的跑在8533Mhz, 那么对于供应商来说就会打上8533Mhz的标签进行出售了】。了解如何测试和解决兼容性问题可以帮助提高用户对 RAM 超频的了解。”
我们感谢 Ryan 为我们带来他的专业材料,并祝愿他未来一切顺利。
基础知识
管理内存技术标准的行业机构是联合电子设备工程委员会 (JEDEC)。近年来,该机构更名为“JEDEC 固态技术协会”。JEDEC 是更大的半导体工程标准化机构电子工业联盟 (EIA) 的一部分。EIA 是一个代表电子行业所有领域的行业协会。
您现在使用的计算机的所有制造商都是 EIA 和 JEDEC 的成员。自 1958 年以来,JEDEC 一直是固态行业标准的领先开发者。在过去 15 年中,DRAM 性能提高了 4,000%。然而,设计仍然相对简单,这是有意为之。RAM技术最基本的方面是需要持续供电才能保留数据,这个过程称为自刷新。因为现在的工业已经对现有基础设施进行了大量的投资,因此成本的考量一直推动着内存系统的设计。大部分复杂性被特意放在内存控制器中。这一切努力使得 DRAM 的产量相对较高,价格也相当便宜。消费产品的主要目标往往是向市场提供尽可能便宜的产品,以最大限度地提高普及率,而不是提供技术上更优越但是需要颠覆大量设计的产品。
根据MOSAID 公司的 Graham Allan 和 Jody Defazio 表示:“目前的市场领导者 是DDR2方案,它提供供应安全、高存储容量、低成本和合理的通道带宽,但插槽并不方便且需要非常复杂的控制器才能让它工作起来。”为了便于分辨,SDRAM 将被表示为“SDR”,第一代 DDR SDRAM 将用“DDR1”表示,这里的“DDR”是 “Double-Data Rate standard”的缩写,表示双倍数据速率标准相关的内存技术系列。
测量
在讨论内存时,我们无法逃避诸如时钟周期、时序、每秒兆比特 (Mbps) 和兆赫 (MHz) 等术语。它们都是相关的,用于解释不同情况下内存系统的速度概念。

通常使用兆字节 (MB) 和千兆字节 (GB) 来描述存储容量。带宽和速度有着不同的测量单位,他们都是我们描述系统性能的方式,不仅限于内存,还应用于计算机的其他部分。需要注意的是,上述单位在作为存储单位时,我们通常以1024为单位。比如,1K表示 1024字节。
一个用于说明发送的数据量(Bits),通常以给定时间段内的单位(每秒位数)计算。另一个用于测量数据流动的速度(Hz)。“流”越快,一秒钟内可以承载更多的数据单位。在讨论内存系统的速度时,这两个通常互换使用。
高级用户会注意到一个称为时钟周期(CK 或 tCK)的测量单位用于描述内存延迟。它们是内存操作状态更改期间的必要延迟,其中延迟越短内存性能越好,速度越快。此外,时钟周期可以转换为纳秒 (ns)。比如,当前时钟频率是1000Hz,对应着一个时钟的周期就是 1/1000秒。10个时钟周期就是 10*(1/1000)秒。
使用“公路”的概念来理解
内存路径类似于道路。带宽(每秒比特数)类似于道路某一部分在给定时间内可以处理的最大汽车数量,这个值与可用车道的宽度或数量直接相关。
频率(Hz)相当于对这些汽车施加的最大速度限制。更高的速度限制将允许更多车辆以更快的速度行驶。但是,这个可能会导致更频繁的发生碰撞。内存延迟可以被认为是这些道路上有交通信号灯的路口。它们会造成延迟以避免车辆碰撞。缩短等待时间将增加车辆流量,但前提是它们已经准备好并有足够的时间移动。
Windows 驱动 SYS/INF/CAT的功能与用途
1.SYS 文件(驱动程序核心文件)
SYS 文件是驱动程序的核心二进制文件,包含硬件设备与操作系统交互的代码逻辑。例如,当用户插入新硬件时,系统会调用对应的 SYS 文件实现设备初始化、中断处理和数据传输等功能。
- 功能:直接控制硬件设备,提供操作系统与硬件之间的接口。
- 生成方式:通过编译驱动程序源代码(如 C/C++)生成,编译时会根据目标系统架构(如 32 位或 64 位)生成对应的文件。
2.INF 文件(安装信息文件)
INF 文件是文本格式的配置文件,指导 Windows 如何安装驱动程序。其内容包含设备标识、文件复制路径、注册表项修改等信息。
- 功能:定义设备与驱动程序的匹配规则(如硬件 ID、兼容 ID)。
- 指定需要复制的文件(如 SYS、DLL)及其目标路径。配置注册表、服务启动参数等系统设置。
示例结构:
Inf
[Version]
Signature="$WINDOWS NT$"
Class=SampleDriver
[Manufacturer]
%Manufacturer%=MyCompany
[MyCompany.NT]
%DeviceName%=DriverInstall, HardwareID\VEN_1234
3.CAT 文件(安全目录文件)
CAT 文件是经过数字签名的安全目录文件,用于验证驱动程序的完整性和合法性。
- 功能:包含驱动程序文件的哈希值列表,确保文件未被篡改。
- 支持 Windows 的驱动程序强制签名验证(尤其在 64 位系统中)。
三者的协作流程
- 系统检测到新硬件时,根据硬件 ID 匹配 INF 文件。
- 按照 INF 文件的指示复制 SYS 文件到系统目录并配置注册表。
- 通过 CAT 文件验证驱动签名,确保安全后完成安装。
上述回答来自 CSDN
ESP32 PSRAM 测试程序
一个测试 PSRAM 的程序
int n_elements = 1000;
unsigned char * acc_data_all;
void setup(){
delay(3000);
Serial.begin(115200);
acc_data_all = (unsigned char *) ps_malloc (n_elements * sizeof (unsigned char));
if(psramInit()){
Serial.println("\nPSRAM is correctly initialized");
}else{
Serial.println("PSRAM not available");
}
memcpy(acc_data_all,"www.lab-z.com",14);
}
void loop() {
Serial.println((char*)&acc_data_all[0]);
delay(1000);
}
当使用 DFRobot FireBeetle 2 ESP32-S3 时,需要如下设置:

VirtualBox Windows 11 的 DSDT
最近在 VirtualBox 上进行ACPI 方面的试验,经过努力 Dump 出来 DSDT 的 ASL ,然后手工加入了一个自定义设备:
//LABZ_Debug_Start
Device (LABZ)
{
Name (_HID, EisaId ("LAB33D6") /* Intel Virtual Buttons Device */) // _HID: Hardware ID
Method (_STA, 0, Serialized) // _STA: Status
{
Return (0x0F)
}
}
//LABZ_Debug_End
有需要的朋友可以基于这个版本修改增加你需要的功能:
CH32V305 使用 UART3 的例子
根据 Ch32V307 的 “USART_Printf:串口打印调试例程” 修改而来。对于Ch32V305来说,UART3 在电路图如下位置:

Arduino 代码如下:
void zUSART_Printf_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
}
void OutUart(char *buf, int size)
{
for(int i = 0; i < size; i++)
{
while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
USART_SendData(USART3, *buf++);
}
}
void setup() {
zUSART_Printf_Init(115200);
}
void loop() {
char sMsg[]="www.lab-z.com";
OutUart(sMsg,sizeof(sMsg));
delay(1000);
}

// USART3 缓冲区最大长度
#define RXBUFFER3SIZE 100
// USART3 缓冲区
u8 RxBuffer3[RXBUFFER3SIZE];
// USART3 缓冲区内数据长度
volatile u8 RxCnt3 = 0;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
/*********************************************************************
@fn USARTx_CFG
@brief Initializes the USART2 & USART3 peripheral.
@return none
*/
void USARTx_CFG(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
USART_InitTypeDef USART_InitStructure = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* USART3 TX-->B.10 RX-->B.11 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART3, &USART_InitStructure);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART3, ENABLE);
}
void setup() {
// 这次的测试是从 USART3 接收,然后将收到的数据从 USART1 送出
Serial.begin(115200);
Serial.println("Start");
USARTx_CFG();
Serial.println("Init Done");
}
void loop() {
if (RxCnt3!=0) {
for (int i=0;i<RxCnt3;i++) {
Serial.write(RxBuffer3[i]);
}
RxCnt3=0;
}
delay(1000);
}
/*********************************************************************
* @fn USART3_IRQHandler
*
* @brief This function handles USART3 global interrupt request.
*
* @return none
*/
void USART3_IRQHandler(void)
{
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
RxBuffer3[RxCnt3++] = USART_ReceiveData(USART3);
}
}

Offline 安装 .Net3.5
1.挂载一个 Windows 镜像
2. CMD 窗口运行如下命令:
Dism /online /enable-feature /featurename:NetFX3 /All /Source:D:\sources\sxs /LimitAccess
关闭Chrom禁止加载本地文件的方法
在调试 JavaScript 的时候,默认情况下是无法加载本地的图片或者其他文件的。这样对于调试造成了一定困扰,一种给解决方法是启动一个本地的Http Server 然后即可调试;此外还可以通过关闭浏览器的安全设置来实现。根据【参考1】,可以在命令行下运行如下命令:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --user-data-dir="C:\temp" --disable-web-security
在新开的窗口中打开你的 html 文件即可。
参考:
2025上海慕尼黑电子展参观记
2025年4月15日,慕尼黑上海电子展在上海新国际博览中心如期举行。

展览位于地铁花木路出口,我在上午十点到达的,提前已经注册好,查验二维码,刷身份证直接进入参观。

门口矗立着各家的广告牌,有 DigiKey 的,还有 TI 的。

还有WCH “含蓄”的广告牌。

含蓄之处在于特别强调了一款成本只要0.58的RISC-V 2.4G无线MCU/SoC,相信因为带有无线功能,可玩性会较高。

第一站去的是位于W5 展馆517展位的JLC嘉立创&中信华的展台。嘉立创集团在本次展会有2个展台,一个位于W5展馆,这是连接器、开关、线束线缆展区以及PCB展区;另外一个是位于N2展馆的619展台。前者属于嘉立创EDA和PCB部门,后者是立创商城部门。嘉立创集团打通了EDA到零售,对于我这样的DIY用户非常友好,使用EDA 设计可避免元件尺寸不合适导致无法使用的问题(这种问题在插接元件上经常会遇到,比如,同样都是USB插头,固定引脚的位置往往差别很大)。

近期立创商城正在进行招商,有兴趣的朋友可以联系他们看看能否成为他们的供应商共同成长。

第二站,前往了位于N5 展馆(半导体展区&人工智能联合展区) 509 的沁恒微的展台。这次带来的主要展品是各种基于RISC-V的MCU和SoC产品,融合了USB/蓝牙/以太网多种接口;此外还有很多Type-C 接口的设备,比如,桥接隔离设计,USB3.0 Hub,双 Type-C 显示设备等等。有USB和 Type-C 特殊设计需求的朋友不妨前往参观,并且可以和现场工作人员进行沟通。

ST展台前依然人头攒动,但是因为价格向上波动的可能,在选型时工程师需要三思。相同的性能可以考虑从国产MCU中进行选择。

一博科技,在去年的文章中介绍过,能够提供从PCB设计到制造一条龙服务的企业。我们是他的客户,多次与他们合作生产研发用途的笔记本主板。

一条龙的服务,能够帮助客户节省成本,缩短研发验证周期。特别的,如果你有更换 x86 SoC的需求也可以联系他们。比如,手上是 ES 的 SoC,拿到 QS SOC之后,可以找他们进行更换。方便后续的测试。

本次展览还看到 JBC 的展台,这是非常优秀的焊接品牌,很多大厂选择他们的设备作为焊接、修理的专业设备。

这是焊接台:

这是小型锡炉:

德州仪器(TI),在模拟领域仍然是庞然大物,地位暂时无人能够撼动:

作为BIOS工程师,少不了和 GigaDevice打交道,它家的SPINOR 芯片经过了时间的检验是很多主板厂商的首选。这次他们带来了车规级的 SPI NOR Flash 产品,使用 45-55nm工艺。

此外还有DDR3L、DDR4、LPDDR4X的产品(消费级)展示。和现场工作人员咨询得知,目前还没有DDR5系列产品。

作为经常DIY的玩家,我更倾向于国内厂商,因为沟通更加便利。比如,如果你要咨询 AD产品,遇到的第一个问题就是他们会先和你“盘道”,问你从哪里购买的元件,然后就以购买厂商不是许可供应商为由拒绝你。

高云是这几年出现的国产FPGA厂商

从拿到的手册来看,他家产品线日渐丰富,现场展示的有视频桥接芯片:

这次看到了 Murata(村田) 的展位,知道这个品牌的原因是这家公司为使用他们无源器件的客户提供了EMC免费测试服务。我们之前使用过他们这个服务,预约之后即可前往他们的公司进行测试。虽然他们不会提供标准的认证,但是这种EMC测试服务能够帮助客户节省金钱和时间。

除了无源器件,展会上Murata还带来了一些特别的产品,比如下面的透明ID标签:

有兴趣的朋友可以关注一下:


广州市星翼电子科技有限公司(正点原子)也过来参加本次展会:

展示了他们设计生产的很多设备:

这一款是目前最强的逻辑分析仪DL32(USB3.0接口,现场询价在一千左右),工作人员推荐个人用户选择更有性价比的DL16:

上海冠显光电(TDO)是专注于显示设备的公司,专注于0.32”至55”显示产品研发,能够提供显示屏以及转接芯片等等设备和方案。

MPS 这个品牌我多次在B站笔记本电脑维修大佬的口中听到:

展会上也有很多小型参展商,比如,下面这一家初看我还以为是做游戏手柄的,实际上是工业手柄。

如此多造型各异的手柄让我有着改装游戏的冲动:


在深圳鹈鹕科技(www.sztihu.com)的摊位现场看到了这种 POGOPIN 连接器。后面可以考虑这种连接器制作下载线以及充电头。

展会将会从4月15日到17日,有兴趣的朋友仍然有机会前往参观。
基于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[i] = 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);
}
实践测试发现,这个板卡在不同显示器上会有兼容性问题,可能和选择的分辨率及其参数有关系。
工作的测试视频【FireBeelte 2 ESP32-S3 VGA 输出测试】 https://www.bilibili.com/video/BV1yrzjY4EmG/?share_source=copy_web&vd_source=5ca375392c3dd819bfc37d4672cb6d54