1. 项目缘起:从芯片到电路板的探索之旅
作为一名硬件爱好者,我总觉得亲手搭建一个完整的计算机系统,是件特别有成就感的事。不是用现成的树莓派或者Arduino,而是从最基础的微处理器开始,自己设计电路、焊接元件、编写引导程序,看着它从一堆零件变成能运行代码的机器。这次,我选择了经典的6502微处理器作为核心,目标是打造一块属于自己的单板计算机原型。6502这颗芯片,在上世纪七八十年代可是个人电脑革命的功臣,Apple II、Commodore 64、任天堂红白机里都有它的身影。选择它,一方面是情怀,另一方面也是因为它结构相对简单,外围电路清晰,非常适合作为学习计算机体系结构和硬件设计的入门项目。
这个项目的核心,就是设计并制作一块印刷电路板,也就是PCB。我把这个阶段称为“原型验证”,目标不是做出一个完美、功能齐全的最终产品,而是验证核心电路设计的正确性。这包括了CPU能否正常上电、时钟信号是否稳定、内存和I/O地址能否被正确访问。所以,我设计了第一版PCB,并把它送去打样。当收到这块绿色的、还带着新鲜松香味的板子时,心情是既兴奋又忐忑的。兴奋的是想法变成了实物,忐忑的是不知道有多少隐藏的“坑”在等着我。这篇文章,就是记录我对这块“PCB Rev 1.0”进行全方位测试的完整过程,从最基础的通断测试,到复杂的逻辑功能验证,希望能给同样想踏入自制计算机领域的朋友们一份详细的“避坑指南”。
2. 开箱与目视检查:第一道安全防线
拿到PCB板子,千万别急着上电。第一步必须是仔细的目视检查,这能帮你排除至少30%的低级错误。我把板子放在明亮的灯光下,用放大镜或者手机微距镜头,从以下几个角度进行了全面审视:
2.1 丝印与焊盘对齐度检查
首先看丝印层,也就是板子上白色的文字和图形。检查所有元器件的位号(如R1、C2、U3)是否清晰可辨,有没有被焊盘盖住或者严重偏移。更重要的是,检查元器件的封装图形(那个白色的外框)是否和实际的焊盘完美对齐。如果封装画大了或者画小了,焊接时就会对不准,轻则焊接困难,重则导致器件引脚虚焊。我这次就发现一个0402封装的电阻,其丝印框比实际焊盘小了一圈,虽然不影响焊接,但说明PCB设计软件里的封装库需要校准。
2.2 走线完整性检查
接着,沿着所有主要的电源线和信号线走一遍,用眼睛“走”一遍电路。重点检查有没有明显的“鼠咬”(Dangling Line),即走线画了一半突然断掉;有没有不该连在一起的地方因为走线过近而几乎短路(特别是电源和地之间);过孔是否都被正确覆盖(没有出现未盖油的“破孔”)。对于数据总线、地址总线这类多根并行线,观察它们的走线是否大致等长、平滑,避免在拐角处出现尖锐的直角,那可能会在高频下引起信号反射问题。
2.3 焊盘与过孔质量
检查所有焊盘,特别是贴片元件的小焊盘,是否完整、光滑,有没有缺损或污染。过孔则要观察其孔壁是否光滑,孔内是否被阻焊油墨堵塞。如果过孔被堵,你的元件引脚就无法穿过板子焊接在背面。我用手电筒从背面照射,检查每一个过孔是否透光,确保其畅通。
2.4 板子尺寸与定位孔
最后,用卡尺测量一下板子的实际尺寸,是否与设计文件一致。检查所有的安装定位孔位置和孔径是否正确。这一步对于需要装进外壳的板子至关重要。我的这块原型板尺寸完全吻合,四个角的定位孔位置精准,为后续的安装测试打下了好基础。
注意:目视检查时,最好将实际的PCB和你的PCB设计软件(如KiCad, Eagle)中的Gerber文件预览图进行对比,更容易发现差异。一个小小的疏忽,比如丝印层错位,可能预示着底层更严重的对齐问题。
3. 基础电气测试:确保生命线畅通
目检通过后,下一步是更客观的电气测试。在没有焊接任何元件之前,对空板进行测试,可以确保PCB本身的制造质量没有问题。
3.1 电源与地网络短路测试
这是上电前绝对必须做的一步。将万用表调到蜂鸣档或电阻档,测量板子上所有电源网络(比如VCC、+5V)和所有地网络(GND)之间的电阻。正常情况下,电阻应该是无穷大(开路)。如果蜂鸣器响了或者电阻值很小(比如几欧姆),说明电源和地之间短路了,一旦上电就会直接烧毁电源或芯片。我分别测试了+5V主电源对地、3.3V(如果有)对地,确认都是开路状态。
3.2 各网络内部连通性测试
根据电路原理图,用万用表的蜂鸣档,逐一测试每一个电气网络内部的连通性。例如,CPU的VCC引脚应该和所有去耦电容的VCC端、电源输入端的VCC都是连通的。地址线A0从CPU引脚出发,连接到RAM、ROM芯片的对应引脚,这条通路也应该是连通的。这个过程比较繁琐,但能有效发现PCB内部可能存在的“开路”故障,比如某段走线因腐蚀不良而断开,或者过孔不通。
3.3 绝缘测试
在确保电源和地没短路、各网络内部连通后,还要抽查一些本不该相连的网络之间是否绝缘良好。比如,检查相邻的两条数据线D0和D1之间,在板子未焊接的情况下电阻是否足够大(通常兆欧级以上)。这可以排除因PCB加工缺陷(如铜箔毛刺)导致的潜在短路风险。
3.4 我的实测情况与发现
在测试我的6502板子时,大部分网络连通性良好。但发现了一个有趣的问题:我设计了一个用于未来扩展的“用户IO”排针,其中有一个引脚在原理图上定义为+5V,但在PCB布局时,我不小心将其网络名称改错了,导致它实际上没有连接到主电源网络。万用表测试显示它是孤立的。幸亏在焊接前发现了这个问题,我可以用一根飞线在焊接时手动纠正。如果没发现,等芯片焊上,那个IO口将永远无法工作,排查起来会困难得多。教训就是:PCB布局完成后,一定要用设计软件的DRC(设计规则检查)和ERC(电气规则检查)功能,并且最好生成网络表(Netlist),与原理图的网络表进行对比,确保百分之百一致。
4. 焊接与元件装配:从图纸到实物的关键一跃
基础测试通过,就可以开始焊接了。对于这种多芯片、多连线的数字电路板,焊接顺序和技巧很有讲究。
4.1 焊接顺序策略
我采用的策略是“先低后高,先简后繁,先电源后信号”:
- 电源相关器件:首先焊接电源插座、电源滤波的大电容、稳压芯片(如7805)。焊接完后,可以单独给电源部分上电,测试输出电压是否正常(+5V是否精准稳定)。这是后续所有工作的基础。
- 被动元件:接着焊接电阻、电容、晶振、按键、LED等无源或简单有源器件。LED焊接时注意极性,可以用万用表的二极管档快速测试。
- 芯片插座:强烈建议为所有集成电路(IC)使用插座,特别是昂贵的CPU和存储器。先焊接插座,这样即使芯片损坏或需要更换,也不会对PCB造成热损伤。焊接DIP(双列直插)插座时,先固定对角线的两个引脚,确保插座贴紧板子且没有翘起,然后再焊接其余引脚。
- 最后插装IC:在所有焊接完成,并再次检查没有短路、虚焊后,再将芯片插入插座。注意芯片的方向,缺口或圆点标记要对准插座上的标记。
4.2 焊接过程中的实时检查
不要等全部焊完再检查。每焊接完一小部分区域(比如CPU及其周边电路),就停下来用放大镜检查一下:
- 焊点质量:是否呈光滑的圆锥形?有没有冷焊(表面粗糙)、虚焊(焊料未浸润引脚和焊盘)或桥接(相邻引脚被焊锡短路)?
- 残留物:是否有过多的松香残留?虽然免洗焊锡膏通常不用清理,但过多的残留可能会在潮湿环境下导致轻微漏电。我用洗板水和硬毛刷对焊接区域进行了局部清洁。
- 器件方向:再次确认二极管、电解电容、芯片的方向是否正确。
4.3 针对6502系统的特殊注意点
- 时钟电路:6502需要一个外部时钟信号。我使用了一个简单的石英晶体振荡器模块(有源晶振),它自带振荡电路,输出稳定的方波。焊接时要确保其输出脚正确连接到6502的PHI2(时钟输入)引脚。也可以用无源晶体加两个电容配合芯片内部振荡器,但稳定性不如有源模块。
- 复位电路:6502的RESET引脚是低电平有效。我设计了一个简单的RC复位电路(一个电阻从VCC拉到RESET,一个电容从RESET到地),并在RESET引脚上连接了一个手动复位按钮到地。确保上电时,电容充电能使RESET引脚保持足够长时间的低电平,让CPU完成初始化。
- 总线管理:在初始测试阶段,数据总线和地址总线是“浮空”的。为了避免因引脚浮空输入导致芯片状态不确定或额外功耗,我临时在数据总线上拉了8个10kΩ的上拉电阻到VCC。这不是最终方案,但有助于初始调试。
5. 上电与静态测试:聆听板子的“心跳”
所有元件焊接完毕并经过仔细检查后,就可以进行第一次上电了。这是一个紧张的时刻。
5.1 预上电检查
上电前,再做一次快速检查:
- 用万用表确认电源输入端正负极没有接反。
- 确认供电电压设置正确(我的板子是5V)。
- 准备一个可调限流电源,将电流限制设在一个较低的值(比如100mA)。这样即使有短路,也能避免灾难性后果。
- 手不要离开电源开关,准备随时断电。
5.2 上电瞬间观察
接通电源,同时观察:
- 限流电源的电流读数:正常情况,空载或静态下,整板电流应该很小(几十毫安以内)。如果电流瞬间飙升并触发限流,说明存在短路,立即断电。
- 板子上的LED:如果有电源指示灯,它应该亮起。
- 芯片温度:快速用手背(敏感度更高)轻触主要芯片(CPU, RAM, ROM),感觉是否有异常发热。微温是正常的,但如果某个芯片迅速烫手,立即断电。
- 异常声音或气味:听是否有电容啸叫或芯片异响,闻是否有焦糊味。
我的板子上电后,电源指示灯正常点亮,限流电源显示电流约45mA,属于正常范围。主要芯片无明显发热。第一关通过!
5.3 关键点电压测量
在静态(CPU未执行程序)下,用万用表测量关键点的电压:
- 各芯片VCC引脚:确保都是稳定的+4.8V到+5.2V之间。
- 复位引脚电压:测量6502的RESET引脚。由于RC电路,上电后这里应该是高电平(接近VCC)。按下复位按钮时,应变为低电平(接近0V),松开后缓慢回升至高电平。
- 时钟引脚电压:测量6502的PHI2引脚。我用的是有源晶振,应该能看到一个大约2.5V左右的平均电压(因为方波),用示波器看则是标准的方波。用万用表交流电压档也能测到一个非零的电压值,表明有时钟信号。
- 总线电压:测量地址总线和数据总线的一些引脚。由于总线上拉了电阻,数据总线应该都是高电平(接近VCC)。地址总线在复位期间的状态取决于CPU设计,但通常也会处于某种确定的静态电平。
这些测量结果都符合预期,说明电源、复位、时钟这三个最基本的子系统工作正常。板子有了“心跳”和“呼吸”。
6. 动态功能测试:让CPU“跑”起来
静态测试正常,说明硬件基础没问题。接下来就要让CPU真正开始工作,执行指令。这是最核心也最具挑战性的部分。
6.1 最小系统与测试固件
为了让测试尽可能简单,我首先构建一个“最小系统”:只有CPU、时钟、复位电路,以及一块存储测试程序的ROM。RAM暂时可以不接,因为第一个测试程序可以非常简单,不需要变量空间。我选择使用一块EEPROM(如AT28C64)作为ROM,因为它可以用编程器反复擦写,方便调试。
我写了一个最简单的6502汇编测试程序,其功能就是“死循环”。为什么是死循环?因为这样CPU的地址总线会输出一个稳定的、可预测的地址序列(程序计数器PC在循环),方便我们观察。程序如下:
.org $8000 ; 假设ROM映射在地址$8000开始的地方 START: JMP START ; 无限跳转到自身这个程序编译后只有3个字节:4C 00 80(JMP指令的操作码和地址)。将其烧录到EEPROM的起始位置。
6.2 逻辑分析仪抓取总线活动
这是调试数字系统的“神器”。我将逻辑分析仪的探头连接到6502的地址总线(A0-A15)、数据总线(D0-D7)以及控制信号线(如PHI2时钟、R/W读写信号)。
- 给板子上电。
- 触发逻辑分析仪,设置为在PHI2时钟的上升沿或下降沿采样。
- 按下并释放复位按钮。
观察逻辑分析仪捕获到的波形。我们应该看到:
- 复位后:地址总线应该从复位向量地址(6502的复位向量在$FFFC-$FFFD)开始变化。由于我的ROM在$8000,我需要确保硬件上,当CPU读取$FFFC和$FFFD时,实际读到的是$00和$80(即跳转到$8000)。这涉及到地址译码电路的设计。
- 进入循环:一旦CPU从$8000开始取指,我们应该看到地址总线在$8000, $8001, $8002, $8000... 之间循环,数据总线上则对应出现
4C,00,80这三个数据。R/W信号线应该一直保持高电平(读状态)。
6.3 实际测试中遇到的问题与解决
在我的第一次测试中,逻辑分析仪显示地址总线在乱跳,并没有稳定在$8000附近,数据总线也是杂乱无章。这说明CPU没有正确执行我的程序。排查步骤如下:
- 检查复位向量:首先怀疑地址译码。我用逻辑分析仪单独抓取当地址总线为$FFFC和$FFFD时,ROM芯片的片选信号(/CE)和输出使能信号(/OE)是否被激活(变低电平)。结果发现,我的地址译码逻辑(使用简单的门电路或GAL)在高端地址区($F000-$FFFF)没有正确产生ROM片选。原因是地址译码器的某个输入引脚虚焊。补焊后,问题依旧,但波形有变化。
- 检查时钟质量:用示波器代替万用表,仔细观察PHI2时钟引脚。发现方波虽然频率正确,但上升沿和下降沿有严重的振铃(过冲和回冲)。这是因为时钟信号线太长,且末端没有匹配。我在时钟输出端串联了一个33欧姆的小电阻,振铃现象大大减轻。
- 检查电源纹波:用示波器探头(切换到交流耦合)测量CPU VCC引脚上的电压。发现在CPU工作时,上面有高达200mV的尖峰噪声。这是典型的去耦不足。我在6502的VCC和GND引脚最近处,补焊了一个0.1uF的陶瓷电容和一个10uF的钽电容,纹波降至50mV以下。
- 重新测试:完成上述修正后,再次上电并用逻辑分析仪捕获。这一次,地址总线清晰地显示出从$FFFC/$FFFD读取复位向量,然后跳转到$8000,并开始稳定的
$8000->$8001->$8002->$8000循环,数据总线也对应出现4C, 00, 80。成功了!CPU正在正确地执行那条JMP指令。
心得:数字电路调试,三分靠电路,七分靠电源和信号完整性。时钟和电源的干净稳定,是系统可靠工作的基石。逻辑分析仪和示波器是眼睛,没有它们,调试就像在黑暗中摸索。
7. 存储器与IO扩展测试:构建完整系统
核心CPU能跑程序后,下一步就是扩展内存和基本的输入输出,构建一个可用的最小计算机系统。
7.1 RAM测试
我添加了一块32KB的静态RAM(如62256)。要测试RAM,需要编写一个能读写RAM的程序。我写了一个简单的内存测试固件,烧录到ROM中。程序逻辑是:
- 向RAM的某个测试区域(例如$0000-$0FFF)写入一个特定的模式(比如$AA)。
- 再从该区域读回数据。
- 比较写入和读出的值是否一致。
- 更换测试模式(如$55, $00, $FF),重复测试。
- 如果所有测试通过,让一个LED闪烁;如果失败,让LED常亮或熄灭。
测试时,再次借助逻辑分析仪。观察当CPU向RAM地址写入时,R/W信号是否变低,地址和数据总线是否对应变化;读取时,R/W是否变高,数据总线是否出现RAM输出的数据。我遇到了一个问题:写入正常,但读回的数据总是$FF。检查发现,是RAM芯片的输出使能引脚(/OE)被错误地接到了高电平,导致其输出始终为高阻态,而总线上拉电阻将电平拉成了$FF。修正连接后,RAM测试通过。
7.2 简单IO测试——点亮LED
为了测试基本的输出能力,我通过一个锁存器芯片(如74HC573)连接了几个LED。CPU向某个特定的IO地址写入数据,锁存器会保存这些数据并驱动LED。
我修改测试程序,循环向该IO地址写入不同的值,观察LED是否按预期闪烁或变化。同时用逻辑分析仪监测锁存器的锁存信号(LE)和数据输入。这个测试相对顺利,很快就看到了LED欢快地闪烁起来,标志着系统已经具备了最基本的“输出”能力。
7.3 地址译码逻辑的终极验证
在整个测试过程中,地址译码电路是贯穿始终的检查点。我使用逻辑分析仪,记录了CPU访问不同地址区间时,各个芯片(ROM, RAM, IO)的片选信号波形。确保:
- 无冲突:任何时候最多只有一个芯片的片选信号有效。
- 全覆盖:CPU需要访问的每个地址,都有且仅有一个芯片响应。
- 时序正确:片选信号在地址稳定后有效,在访问结束前保持,满足芯片的时序要求。
我绘制了一张“地址映射表”,将逻辑分析仪观察到的结果与设计意图对比,确保完全吻合。这是系统稳定工作的逻辑基础。
8. PCB Rev 1.0 设计复盘与改进清单
经过一系列严苛的测试,这块原型板基本达到了验证核心功能的目的。但也暴露出设计上的若干不足,这些都将成为下一版(Rev 1.1或Rev 2.0)的改进重点。
8.1 已发现的问题汇总
- 电源去耦不足:最初只在电源入口放置了滤波电容,忽略了每个主要IC旁边的去耦电容。虽然补焊可以解决,但应在PCB布局时就在每个芯片的VCC/GND引脚附近预留0402或0603封装的0.1uF陶瓷电容位置。
- 时钟信号完整性:时钟线走线过长,且没有考虑阻抗匹配,导致振铃。新版设计应将时钟源尽量靠近CPU,并在驱动端串联一个小电阻(22-100欧姆)以阻尼振铃。
- 地址译码器虚焊点:部分使用细间距TSSOP封装的逻辑芯片,焊盘较小,手工焊接容易造成虚焊。下次可以考虑改用更易焊接的SOIC封装,或者增加焊盘尺寸和间距。
- 测试点缺失:调试时经常需要测量电源、地、关键信号。Rev 1.0板上没有专门放置裸露的测试点,只能用探针小心翼翼地去戳芯片引脚或焊盘,既不方便也不安全。新版必须在所有关键网络(电源、地、所有总线、主要控制信号)上添加醒目的测试点。
- 丝印标识不清:部分元件位号被过孔或焊盘遮挡。需要调整丝印位置,确保所有标识清晰可读。同时,可以考虑在板子空白处添加版本号(如“Rev 1.0”)、项目名称和关键接口的简要标注。
8.2 计划中的功能增强
- 调试接口:考虑添加一个标准的6针或10针ARM Cortex调试接口,虽然6502本身不支持JTAG,但可以利用这个接口连接一个简单的“总线监视器”或“调试ROM”,极大方便后续软件开发。
- 更灵活的IO扩展:目前IO是固定的。下一版可以设计一个类似“GPIO”的接口,通过锁存器和缓冲器,允许更多引脚被灵活定义为输入或输出。
- 视频输出:这是终极目标之一。可以集成一个简单的VGA或复合视频生成芯片(如AD724, CH376),甚至用FPGA/CPLD来实现,让这台自制计算机能连接显示器。
- 外壳与结构:Rev 1.0只是一块裸板。下一版需要考虑安装孔、接口位置,以便能装入一个合适的外壳,成为一个完整的“产品原型”。
8.3 给初学者的建议
如果你也想开始自己的6502 SBC之旅,从这块Rev 1.0的测试经验中,我最想分享的是:从简入繁,分步验证。不要试图第一版就设计一个包含所有功能的完美板子。先做一个只有CPU、时钟、复位和ROM的最小系统板,把它调通。然后设计第二版,加入RAM和基础IO。再设计第三版,加入更多外设。每一版都专注于解决上一版的问题并增加有限的新功能。这样,每次打样的成本可控,调试的复杂度也大大降低。每一次成功的点亮,都是继续前进的巨大动力。硬件设计的乐趣,正是在于这种从无到有、亲手解决问题的过程。这块绿色的PCB Rev 1.0,尽管不完美,但它成功地“活”了过来,并且清晰地告诉了我下一步该往哪里走,这本身就是最大的成功。