news 2026/8/31 12:47:48

51单片机8音键电子琴DIY:从仿真到打板的完整制作指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
51单片机8音键电子琴DIY:从仿真到打板的完整制作指南

简介:这是一套面向电子设计初学者与单片机课程实践者的完整8音键电子琴DIY项目资源,聚焦51单片机系统开发与Proteus仿真调试全流程。资源包含Proteus仿真工程(.DSN/.PWI)、Keil C51源码(2个.c文件及配套.uvproj工程)、AD设计文件(原理图.SchDoc、PCB.PcbDoc及.PRJPCB工程)、BOM清单(.doc)、可烧录.hex文件及详细元件清单,覆盖从电路设计、代码编写、仿真验证到PCB落地的全链路环节。共19个文件,总大小仅101KB,轻量实用,便于快速导入学习。已有199人下载学习,适合课程设计、电子实训或毕业设计参考。用户可直接运行仿真观察8键弹奏、录音回放、内置乐曲播放等功能,深入理解AT89C52定时器驱动音阶、24C02掉电存储、LM386音频功放电路及功能按键逻辑设计等核心知识点。 这个DIY项目我前前后后做了好几版,从Proteus仿真到打板焊接都跑了一遍,过程中踩了不少坑。很多刚接触51单片机的朋友都问过我:学完定时器、外部中断之后,有没有一个既能练手、又有完整流程的题目?我的回答通常是——做一个8音键电子琴。它看似简单,只用到8个按键和一个发声元件,但涉及单片机最小系统、定时器精确延时、按键消抖、音阶频率计算,甚至还能延伸到PCB设计、BOM整理和生产文件输出。这篇文章就把整个制作过程,包括仿真图、源代码、AD原理图和PCB图的思路,以及我实测中遇到的问题,一次性整理清楚。

先说清楚这个项目能做什么。8音键电子琴,就是通过8个独立按键,让单片机输出对应音阶频率的方波,驱动蜂鸣器或扬声器发声,对应的音阶是1(do)、2(re)、3(mi)、4(fa)、5(sol)、6(la)、7(si)、1(高音do)。你按下哪个键,就响哪个音,松开就停。别小看这8个音,简单的儿歌、练习曲完全能弹出来。对于单片机入门者来说,它比单纯点灯有乐趣,又比做语音播报、显示菜单这种项目更容易跑通。适合大学生课程设计、电子竞赛热身,也适合想从仿真走向实物的DIY爱好者。

1. 项目概述与整体设计思路

1.1 8音键电子琴的核心功能与扩展方向

从功能上看,这个设备就是一个简单的音源发生器。单片机通过定时器产生指定频率的方波,这个方波经过驱动电路送到扬声器,就变成了人可以听到的蜂鸣声。频率越高,音调越高;频率越低,音调越低。要让8个按键对应8个不同音高,只需要在程序里预先存好一组“定时器初值”,按键按下时把对应初值装载进定时器,输出方波的频率就会跟着变。

这个项目虽然基础,但扩展方向很多。有的版本会加上录音和回放功能,把按键状态和时值存进RAM或EEPROM;有的加上数码管显示当前音名;还有的把8个按键改成16键甚至矩阵键盘,扩展音域。我建议先把手动演奏版本做出来,再考虑扩展,因为基础版本已经把51单片机最核心的定时器、中断、GPIO输入输出全用上了。

1.2 为什么选51单片机、Proteus仿真和Altium Designer这套组合

很多人会问:现在Arduino和STM32那么流行,为什么还要用51单片机?我的理由是:51单片机资料全、结构简单、定时器逻辑清楚,非常适合理解底层原理。Arduino封装太狠,你写一行 tone() 就能发声,但定时器怎么工作、初值怎么算,完全无感;STM32功能强,但库函数和寄存器配置对初学者是个不小的坎。51单片机正好卡在“能看到硬件细节”和“不至于过度复杂”之间。

Proteus(经常被人拼成protues)则是硬件仿真的利器。它可以在不买元件、不打板的情况下,把单片机程序烧进仿真芯片里跑,按键、扬声器、晶振这类东西都能模拟。这样做的好处很直接:程序逻辑对不对,电路连线有没有错,点一下运行就能看到结果。把硬件问题全部在软件里解决之后,再去做真实的PCB,成功率会高很多。

Altium Designer(简称AD)在电子设计领域用得非常多,从原理图绘制、PCB布局布线到BOM导出一步到位。标题里提到的AD原理图、PCB图、BOM,正是实际产品开发中必须输出的交付物。把这套流程走下来,等于提前体验了从研发到生产的完整链路。

1.3 系统模块划分与工作流程

整个系统可以拆成四个模块:电源、单片机最小系统、按键输入、发声输出。电源负责给单片机和外部电路供电,最小系统保证单片机能够正常启动运行,按键输入负责采集演奏者的操作,发声输出则由定时器控制的方波驱动扬声器。

工作流程很简单:单片机不断扫描P1口上的按键状态,一旦检测到某个按键被按下,就根据按键编号到音符表里查对应的定时器初值,然后启动定时器。定时器溢出时进入中断服务函数,翻转蜂鸣器引脚的电平,这样在引脚上就形成了连续方波,方波频率就是该音阶的频率。松开按键后,定时器停止,发声结束。

2. 核心硬件电路设计解析

2.1 单片机最小系统:复位、晶振和电源去耦

最小系统是一切单片机项目的地基。它由三部分构成:复位电路、晶振电路和电源去耦电容。复位电路通常采用“10k电阻加10uF电容”的结构:10k电阻把复位引脚RST拉低到地,保证正常工作时不复位;按键或电容在上电瞬间给RST提供一个高电平脉冲,让程序从头开始执行。晶振电路则是12MHz晶振配两个30pF负载电容,分别接到单片机的XTAL1和XTAL2引脚上,构成稳定的时钟源。电源去耦电容一般用10uF电解电容并联0.1uF陶瓷电容,放在单片机电源引脚附近,滤除低频和高频干扰。

很多人画原理图时容易忽略这几点:晶振离单片机越远,时钟波形越容易受到干扰;复位电容和电阻的位置搞错,板子会上电不复位;电源引脚直接接VCC,没有去耦电容,按键按下瞬间可能造成程序跑飞。以上这些问题在仿真里看不明显,但做成实物后就会暴露出来。我在第一版PCB里,就是把复位电容放得离RST脚太远,结果上电后单片机经常要手动复位才能工作,后来重新布局才解决。

2.2 按键输入电路的设计与消抖逻辑

8个琴键用的是8个独立轻触按键,一端接P1口,另一端接地。当按键按下时,对应引脚被拉低为低电平;松开后,引脚由内部上拉电阻恢复为高电平。这里可以直接使用51单片机P1口内部的弱上拉,不需要额外接上拉电阻,这也是选P1口做按键输入的原因之一。

按键有一个所有单片机项目都躲不开的问题:机械抖动。按键内部的金属触点接触瞬间会弹跳,电平不是干净地从高到低,而是会几次反复跳动。如果程序不去处理,可能出现按一次响两声、松手后声音断断续续的情况。处理办法分硬件和软件两种。硬件上可以在按键两端并联一个104瓷片电容,利用电容充放电把抖动吸收掉;软件上则在检测到按键按下后延时10ms再读一次,确认确实处于按下状态。这个项目我用的是软件延时消抖,因为不需要额外元件,代码也简单。

2.3 发声电路:从蜂鸣器到扬声器的驱动方式

发声部分是这个项目最容易翻车的地方,原因是很多初学者分不清“有源蜂鸣器”和“无源蜂鸣器”。有源蜂鸣器内部自带振荡源,通电就会响,频率固定,只能当报警器用,做电子琴发不出不同音高的音;无源蜂鸣器内部不带振荡源,需要外部给一定频率的方波才会响,所以电子琴必须用无源蜂鸣器或扬声器。

驱动电路上,单片机引脚驱动能力有限,直接推8Ω扬声器声音很小,甚至带不动。我常用的做法是加一个NPN三极管做电流放大:单片机P2.0引脚通过一个1k电阻接到S8050三极管基极,发射极接地,集电极接扬声器一端,扬声器另一端接VCC。三极管工作状态相当于一个开关,P2.0输出高电平,三极管导通,电流流过扬声器;P2.0输出低电平,三极管截止。方波在不断翻转时,扬声器线圈中流过变化的电流,就发出了对应频率的声音。

实际测试时,如果声音偏小,可以适当减小基极电阻,或者把扬声器换成带驱动板的喇叭模块;如果想获得更好的音质,可以再加一个LM386音频功放电路,输出几瓦的功率,效果会完全不一样。不过对基础版本来说,S8050驱动8Ω扬声器已经够用了。

2.4 AD原理图与PCB设计必须注意的几个点

在Altium Designer中画原理图,建议从Proteus仿真图的基础上改。元件放置要按模块分区:电源放左上角,单片机放中间,按键放右侧,发声电路放左下角。连线时优先使用网络标号而不是到处拉线,这样图面会非常清爽,也不容易连错。

转换成PCB之后,布局和布线是重头戏。晶振和两个30pF电容要紧紧挨着单片机的XTAL1/XTAL2引脚;10uF和0.1uF去耦电容要靠近单片机的VCC和GND脚;按键尽量放在板子边缘,方便安装外壳;扬声器接口放到板子一角,别和晶振靠太近。布线时先布电源和地,再布信号线。电源线宽度至少1mm,GND线尽量采用大面积覆铜;信号线可以细一些,但不要小于0.3mm,否则后焊容易断。

3. 软件设计:定时器、音符频率与按键程序

3.1 音阶频率和定时器初值的计算方法

要发声,先要知道每个音对应多少赫兹。标准C大调从中央C(C4)开始,do、re、mi、fa、sol、la、si、高音do(C5)的频率如下表:

音阶音名频率(Hz)
1(do)C4261.63
2(re)D4293.66
3(mi)E4329.63
4(fa)F4349.23
5(sol)G4392.00
6(la)A4440.00
7(si)B4493.88
1(高音do)C5523.25

51单片机用定时器T0方式1,也就是16位定时器。定时器每计数一次耗时一个机器周期,12MHz晶振下机器周期是1微秒。为了产生某个频率的方波,可以让引脚电平在半个周期翻转一次,方波的周期就是两次翻转的时间。定时器的初值计算公式为:

初值 = 65536 - (500000 ÷ 频率)

这里的500000是半周期微秒值,也就是1000000微秒除以2,再除以频率。举个例子:中央C,频率261.63Hz,500000除以261.63约等于1911,65536减去1911等于63625,换算成16进制就是0xF889。程序设计时先把每个音的音符初值算好,存成数组,按键按下时直接查表,不用在运行中做浮点运算。

我整理了一份12MHz晶振下的初值表,方便直接使用:

音阶频率(Hz)定时器初值
1(do)261.6363625
2(re)293.6663833
3(mi)329.6364019
4(fa)349.2364104
5(sol)392.0064260
6(la)440.0064400
7(si)493.8864524
1(高音do)523.2564580

注意,这里频率取的是自然音阶值,实际听感上已经足够准。如果要更精确,可以在代码里用浮点数重新计算,但没必要。51单片机定时器初值本身会有少量取整误差,频率越高误差占比越大,但8个音阶在可接受范围内。

3.2 定时器T0的初始化与中断处理

软件部分的核心是定时器。先把T0设置成方式1,即16位定时器模式。初始化时需要清空TH0和TL0,然后开启定时器0中断和总中断。定时器开始运行后,每从初值计数到65536溢出一次,就会触发中断,CPU自动跳转到中断服务函数。

中断服务函数里做的事情只有两件:重新把当前音符对应的初值赋给TH0和TL0,让下一次溢出时间依然准确;然后将发声引脚P2.0电平取反。这样每次中断翻转一次,引脚上的方波频率正好等于音符频率。有的初学者会把初值装载写在主函数里,而不在中断里更新,这样第一次发声正常,第二次周期就错了,音调会漂移。

#include <reg52.h> #define uchar unsigned char #define uint unsigned int sbit BEEP = P2^0; // 发声引脚 code uint tone_tab[8] = { 63625, 63833, 64019, 64104, 64260, 64400, 64524, 64580 }; uchar tone_index = 0; // 当前音阶索引 void Timer0_Init() { TMOD &= 0xF0; // 清空T0位 TMOD |= 0x01; // T0工作在方式1,16位定时器 TH0 = tone_tab[0] >> 8; TL0 = tone_tab[0] & 0xFF; ET0 = 1; // 允许T0中断 EA = 1; // 允许总中断 } void Timer0_ISR(void) interrupt 1 { TH0 = tone_tab[tone_index] >> 8; TL0 = tone_tab[tone_index] & 0xFF; BEEP = !BEEP; // 翻转波 }

3.3 按键扫描、消抖与主循环逻辑

主循环的任务是不断读取P1口的8个按键状态,判断当前按下的是哪一个,然后更新tone_index,开启或关闭定时器。我建议写一个独立的按键读取函数ReadKey,返回当前被按下的键号,如果没有按键按下,就返回一个无效值,比如8。

消抖的处理方式是:先读到键号,延时10ms,再读一次,如果两次一致,才认为是有效按键。这样机械抖动基本被过滤掉了。主循环里还有一个关键逻辑:按键全部松开时,必须关掉定时器,否则声音会一直响下去。因此每隔一段时间就调用ReadKey判断一次,无按键时将TR0置0,同时把BEEP引脚拉低。

void Delay10ms(void) { uchar i, j; i = 20; j = 113; do { while (--j); } while (--i); } uchar ReadKey(void) { uchar key = 8; // 默认无按键 P1 = 0xFF; if ((P1 & 0x01) == 0) key = 0; else if ((P1 & 0x02) == 0) key = 1; else if ((P1 & 0x04) == 0) key = 2; else if ((P1 & 0x08) == 0) key = 3; else if ((P1 & 0x10) == 0) key = 4; else if ((P1 & 0x20) == 0) key = 5; else if ((P1 & 0x40) == 0) key = 6; else if ((P1 & 0x80) == 0) key = 7; return key; } void main(void) { Timer0_Init(); while (1) { uchar key = ReadKey(); if (key < 8) { Delay10ms(); // 软件消抖 if (ReadKey() == key) { tone_index = key; TR0 = 1; // 启动定时器发声 } } else { TR0 = 0; BEEP = 0; } } }

这段代码我在Proteus仿真和实物上都跑过,直接可用。如果你需要旋律播放功能,可以把音符序列存储在一个数组里,配合另一个定时器产生节拍,按下“播放键”后自动扫描数组,依次修改tone_index,中间加延时作为音符时值。这个扩展并不复杂。

3.4 源代码组织与注释习惯

源代码可以放在一个main.c里,也可以拆成key.c、timer.c、music.c几个模块。我建议初学阶段先不要过度拆分,一个main.c加一个头文件就够了,重点是理解逻辑。函数命名要有意义,比如ReadKey、Delay10ms、Timer0_Init,而不是写f1、f2这种。注释要写“为什么”,不要写“是什么”。比如“65536 - 500000 / 频率”这一行,注释可以写“定时器初值,使中断周期为音符半周期”,比写“给TH0赋值”有价值得多。

4. Proteus仿真搭建与调试实录

4.1 Proteus工程的元件清单和选型

打开Proteus后,新建一个工程,在元件库里搜索并放置以下元件:AT89C51或AT89C52作为单片机;8个BUTTON按键;RES电阻;CAP电容;CAP-ELEC电解电容;CRYSTAL晶体振荡器;SPEAKER或SOUNDER作为发声元件;如果需要模拟三极管驱动电路,再加一个NPN三极管,例如2N2222。

这里要特别注意发声元件的选取。Proteus里有两种常用元件,一种叫BUZZER,另一种叫SOUNDER。BUZZER模拟的是有源蜂鸣器,只要加直流电压就会响,频率不可控,不适合本项目;SOUNDER模拟的是无源蜂鸣器/扬声器,需要外部信号驱动,才能发出可变音调的声音。所以在电子琴仿真里,一定要选择SOUNDER或者SPEAKER,并且要按照硬件电路那样,让P2.0通过电阻接到三极管基极,再驱动扬声器,这样仿真效果和实物最接近。

4.2 建好电路后如何加载程序并运行

电路连好后,双击单片机元件,在弹出的属性对话框中找到Program File项,点击旁边的文件夹图标,选择用Keil编译生成的HEX文件。同时把ClockFrequency设置成12MHz,和程序里的定时器计算保持一致。这一步经常有人忽略,默认频率可能是1MHz,结果仿真出的声音频率完全不对,听起来像蚊子叫。

设置完成后点击左下角的运行按钮,仿真就会开始。按下任意一个按键,听扬声器是否有对应音调的声音,同时观察P2.0引脚有没有红色脉冲。Proteus仿真里,引脚变红代表高电平,变蓝代表低电平,如果声音正常且引脚频率随按键改变,说明电路和程序都没问题。

4.3 仿真中最容易遇到的三类问题

第一类是按键按下后扬声器不响。先看P1口对应引脚有没有变蓝,如果引脚没变,说明按键连线有误或没接地;如果引脚变了但没声音,大概率是发声元件选错了,比如选了BUZZER。第二类是声音很尖或者很低。这种情况要检查单片机的时钟频率,确保仿真属性里设置的是12MHz。第三类是按下按键时响,但松开后仍然响几秒才停。这是主循环里没有及时关掉定时器导致的,检查程序里无按键分支是否把TR0清零,同时BEEP引脚有没有拉低。

我把这三个问题整理成表格,方便你排查:

现象可能原因处理办法
按键无反应按键未接地或引脚接错检查按键连线和网络标号
无声但有方波输出发声元件选成有源蜂鸣器换成SOUNDER或SPEAKER
音调偏高或偏低单片机仿真频率与代码不一致设置ClockFrequency为12MHz
松手后仍响未关闭定时器主循环无按键时TR0=0

5. 从仿真到实物:PCB设计与BOM清单

5.1 用Altium Designer重新绘制原理图的步骤

仿真通过之后,就可以在AD里画正式原理图了。不建议直接拿仿真图截图去画PCB,而是要在AD的元件库里重新放置元件。AT89C51或STC89C52在AD自带库中可能找不到,需要自己创建元件,或者从网上导入现成的原理图库和封装库。这个步骤看起来麻烦,但它能让你掌握“新建元件”的基本功,后面做什么项目都用得到。

放置元件后,按照仿真电路连线。连线时尽量使用网络标签,而不是把线拉得很长。电源和地可以用VCC、GND网络标签代替,这样原理图会更干净。检查无误后用菜单里的Design→Update PCB Document生成PCB文件。

5.2 PCB布局布线实操技巧

新生成的PCB上所有元件都会散落在一起,第一步是布局。布局的原则是先固定单片机的位置,再围绕它摆放外围元件。晶振和匹配电容要放在单片机第18、19引脚旁边,这是系统稳定性的关键;去耦电容要放在VCC引脚附近,越近越好;按键按行列排整齐,并且标注好对应的音阶,方便弹奏和焊接;扬声器接口放在板边,插接线方便。

布线时我习惯先布地线,再布电源线,最后布信号线。信号线可以细一点,但电源线尽量加宽,至少1mm。单片机底部可以考虑大面积覆铜接地,既能改善抗干扰,也能减少PCB腐蚀时的浪费。在Altium Designer里,覆铜操作就是Place→Polygon Pour,选择GND网络,画一个覆盖板框的多边形。覆铜后别忘了放置过孔连接上下层地。

5.3 BOM清单怎么整理才不容易漏件

BOM(Bill of Materials)就是物料清单,是生产采购和焊接时的重要依据。基本内容包括序号、元件名称、型号规格、封装、数量、位号、备注。整理BOM时,我建议按模块分块,比如电源部分、单片机部分、按键部分、发声部分,这样采购时不容易乱。

下面这个表格是我做这版电子琴时的BOM,可以直接参考:

序号元件名称型号/规格封装数量备注
1单片机STC89C52RCDIP-401可换AT89C51
2晶振12MHzHC-49S1与程序一致
3瓷片电容30pF08052晶振负载
4电解电容10uF/16V5x5mm1复位电路
5陶瓷电容0.1uF08051电源去耦
6电阻10k08051复位下拉
7电阻1k08051基极限流
8电阻10k08051基极下拉
9三极管S8050TO-921驱动扬声器
10扬声器8Ω/0.5W接线端子1发声输出
11轻触按键6x6mm插件8琴键
12电源座DC-005插件15V供电
13IC座DIP-40插件1方便更换芯片

注意封装一栏要和你画PCB时用的封装完全一致,否则焊接时会发现焊盘对不上。比如S8050有TO-92和SOT-23两种常见封装,画PCB之前就要想好买哪种。我用的是TO-92插件封装,焊接方便。

5.4 焊接、电源检查与实物调试

焊接顺序建议从低到高:先焊电阻、电容,再焊晶振、IC座,然后焊按键、三极管、扬声器接口,最后焊电源座和单片机。焊完之后不要急着上电,先用万用表测一下电源正负极之间有没有短路,很多新手焊完板子一上电就冒烟,十有八九是电源接线反了或虚焊。

上电后先用万用表测单片机VCC和GND之间电压,正常应该是5V左右。接着把程序烧录进去,用示波器或逻辑分析仪看P2.0引脚是否有方波输出。没有示波器的话,可以直接把扬声器接上试听,如果在按下按键时能听到对应音调,基本就成功了。如果某个按键不出声,用万用表蜂鸣档测按键两端在按下时是否导通,排除按键本身的问题。

6. 常见问题与排查技巧实录

6.1 按键不灵或者误触

按键不灵最常见的原因是软硬件都没有做消抖,其次就是按键引脚虚焊。我的建议是:焊接时把按键的四个引脚都吃透锡,焊完后用镊子轻摇一下,确保不松动。软件上,可以在ReadKey里加入两次读取一致才有效的逻辑。如果在实物上仍然出现误触,还可以在每个按键两端并联一个104电容,从硬件层面吸收抖动。

6.2 声音沙哑或音量忽大忽小

这个问题在仿真里几乎不会出现,实物上却很常见。一般是因为电源供电不稳定,或者扬声器驱动三极管工作在放大区而不是开关状态。检查三极管的基极电阻,1k电阻配合5V供电时,基极电流约为4mA,足以让S8050进入饱和导通状态。如果供电电压偏低,比如USB口供电只有4.5V,声音会明显发闷。这时可以换一个独立5V电源适配器,或者把电源线加粗、增加一个大电容。

6.3 音调和标准的琴不太一样

音调不准有三个原因:一是晶振频率不准确,比如用了11.0592MHz晶振但程序按12MHz计算初值;二是定时器初值取整误差在听感上放大了;三是扬声器本身频响特性导致某些频率听起来不够亮。第一个原因最需要排查,更换晶振后要确认程序和电路里标注的频率一致。如果只是偶尔一个音不准,可以微调tone_tab里对应的初值,比如把0xF889改成0xF888,实际听感满意即可。

6.4 上电后还没按键就自己响

这种情况通常是复位电路没正常工作,单片机没有从0000H开始执行程序,或者P2.0引脚上电默认状态导致三极管导通。先测复位引脚电压,正常工作时应该是低电平;如果一直高电平,说明复位电路接错,检查74HC? 大多数情况下是复位电容和电阻的位置关系不对。程序里也可以在main函数最开始加一句BEEP=0,确保上电瞬间扬声器不响,然后在初始化完外设后再进入主循环。

最后再分享一个小技巧。如果你打算做完仿真之后去打样PCB,一定要在打样前把板子的机械尺寸、固定螺丝孔和按键位置都规划好,别急着省钱拼板。我第一次做这块板子时,就是没留扬声器安装位,最后只能用扎带绑在板子边缘,虽然功能正常,但整个作品看起来就像半成品。按“先仿真、再画板、后打样”的顺序走,每一步都能查错,成功率会高很多。希望这篇完整记录能帮你顺利做出属于自己的8音键电子琴。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 12:40:52

GPU云的技术拐点:从调度优化到精细化运营的工程账

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/8/31 12:39:54

Zen Browser扩展完整指南:3步让你的浏览体验各归其位

Zen Browser扩展完整指南&#xff1a;3步让你的浏览体验各归其位 【免费下载链接】desktop Welcome to a calmer internet 项目地址: https://gitcode.com/GitHub_Trending/desktop70/desktop 你有没有过这种时刻&#xff1f;几十个标签页堆在侧边栏&#xff0c;想找的那…

作者头像 李华
网站建设 2026/8/31 12:39:51

游戏开发别写死参数!从0.1秒兜底到根因修复的正确姿势

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/8/31 12:39:20

基于Hermes Agent的五角色团队协作架构实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/8/31 12:38:48

爬虫先探测再抓取:ProbeScraper工具解析与实战

最近在 Hacker News 上看到一个很有意思的项目&#xff1a;Show HN: Scraper that probes a site before promising it works。一句话概括设计思路&#xff1a;在承诺“我能抓这个站”之前&#xff0c;先对目标站点做一次探测。这个思路看起来简单&#xff0c;但对做爬虫工程的…

作者头像 李华