1. 为什么需要桌面性能看板?
作为一个常年折腾硬件的玩家,我总喜欢在桌面上放些能实时显示电脑状态的小玩意儿。以前用AIDA64的悬浮窗,但总觉得不够酷——直到发现可以用STM32+OLED打造专属性能看板。这玩意儿不仅能实时显示CPU温度、内存占用,还能让桌面瞬间充满极客感。
传统软件监控的痛点在于:占用屏幕空间、依赖操作系统、视觉效果单一。而硬件看板的优势很明显:独立显示不遮挡内容、断电后立即恢复、自定义显示样式。我实测下来,0.96寸OLED在日光下依然清晰,STM32F103的功耗不到0.5W,整套方案成本不超过50元。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. AIDA64数据抓取实战
2.1 基础配置技巧
在AIDA64中配置LCD输出其实很简单,但有几个关键点容易踩坑。首先进入【文件】→【设置】→【LCD】,选择Pertelian作为设备类型——这个选项决定了数据包的格式。端口号要选STM32实际连接的COM口,屏幕尺寸建议选16x4(对应128x64的OLED)。
添加监控项时有个隐藏技巧:按住Ctrl键可以批量选择多个参数。我常用的配置组合是:
- 第一行:CPU占用率(Label设为"CPU")
- 第二行:内存使用量(Label设为"Mem")
- 第三行:CPU温度(Label设为"CTemp")
- 第四行:GPU温度(Label设为"GTemp")
注意一定要在Unit栏加上"@"符号,这个符号会作为数据包的结束标志,后续解析时会用到。
2.2 数据包格式解析
用串口调试工具抓包,会发现AIDA64发送的数据非常规律。每个数据包的结构如下:
| 字节位置 | 含义 | 示例值 |
|---|---|---|
| 0 | 起始标志 | 0xFE |
| 1 | 行号标识 | 0x80~0xD4 |
| 2~n-1 | 实际数据 | ASCII字符 |
| n | 结束标志 | 0x40 (@) |
比如第二行内存数据可能长这样:
FE C0 35 25 40 → 表示内存使用率35%
3. STM32状态机编程
3.1 串口接收优化方案
原始代码用了9个状态来处理数据包,其实可以用更优雅的方式实现。我的改进方案是定义结构体数组:
c复制typedef struct {
uint8_t lineID;
char* pBuffer;
} LineConfig;
LineConfig lines[] = {
{0x80, Serial_RxPacket_CPU},
{0xC0, Serial_RxPacket_Mem},
{0x94, Serial_RxPacket_CPUTemp},
{0xD4, Serial_RxPacket_GPUTemp}
};
这样中断处理函数可以简化为:
c复制void USART1_IRQHandler() {
static uint8_t state = 0;
static uint8_t currentLine = 0;
static uint8_t index = 0;
uint8_t data = USART_ReceiveData(USART1);
switch(state) {
case 0: // 等待起始位
if(data == 0xFE) state = 1;
break;
case 1: // 识别行号
for(int i=0; i<4; i++) {
if(data == lines[i].lineID) {
currentLine = i;
state = 2;
index = 0;
break;
}
}
break;
case 2: // 接收数据
if(data == 0x40) {
lines[currentLine].pBuffer[index] = '\0';
RxFlag = 1;
state = 0;
} else {
lines[currentLine].pBuffer[index++] = data;
}
break;
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
3.2 抗干扰处理
实际使用中可能会遇到数据错乱的问题,我总结了几个加固措施:
- 增加超时机制:如果500ms内没收到完整数据包,自动重置状态机
- 添加CRC校验:在AIDA64端用Lua脚本计算校验和
- 双缓冲设计:准备两个缓冲区交替使用,避免显示刷新时的数据撕裂
4. OLED显示优化技巧
4.1 界面布局设计
0.96寸OLED的分辨率是128x64,合理布局能让信息更清晰。我的设计方案是:
- 第1行:CPU状态 [██████░░░░] 60%
- 第2行:Mem 8.2/16GB
- 第3行:CPU 56°C GPU 72°C
- 第4行:时间戳 14:25:03
实现进度条效果的代码片段:
c复制void drawProgressBar(uint8_t row, uint8_t percent) {
OLED_DrawRectangle(30, row*16-1, 100, row*16+6);
uint8_t length = (100-30)*percent/100;
OLED_FillRectangle(30, row*16-1, 30+length, row*16+6);
}
4.2 刷新率优化
默认的I2C传输速度可能限制刷新率,可以通过这些方法提升:
- 将I2C时钟频率提升到400kHz
- 使用硬件I2C替代软件模拟
- 只刷新变化的部分区域
- 采用压缩的位图字体
实测优化后,全屏刷新速度从120ms提升到35ms,完全看不出闪烁。
5. 进阶改造思路
5.1 无线传输方案
如果觉得串口线太乱,可以改用ESP-01S WiFi模块:
- AIDA64通过TCP发送数据
- ESP8266接收后通过UART传给STM32
- 增加信号强度指示器
5.2 多屏联动
用CAN总线连接多个STM32,实现:
- 主屏显示性能数据
- 副屏显示网络流量
- 第三个屏显示硬盘状态
5.3 数据持久化
外接SPI Flash存储历史数据,实现:
- 温度曲线回放
- 峰值记录
- 异常报警
我在实际项目中发现,STM32的硬件SPI配合DMA传输,可以轻松实现每秒1000次的数据记录。
