1. 项目概述与核心价值如果你和我一样是个对街机厅的“黄金年代”念念不忘的老玩家同时又喜欢捣鼓硬件那么“如何让一台真正的街机框体完美运行PC上的模拟器”这个问题一定困扰过你。街机框体的灵魂在于那块硕大的CRT显示器、那个摇杆和六个按钮组成的控制面板以及投币时那一声清脆的“咔哒”响。但要把现代PC塞进去让它能接收这些“古老”的指令并安全地输出图像和声音可不是插几根线那么简单。市面上有现成的商业转换板但要么价格不菲要么功能死板无法满足我们这些“折腾党”的定制化需求。这就是“MONSTERBASH”项目诞生的背景。它是一个基于Arduino DUE微控制器设计的、开源固件的JAMMA转PC接口板。简单来说它就是一座桥梁一端连接着标准的街机JAMMA接口承载了所有控制信号、音频和视频另一端连接着你的PC。它的核心任务有三个第一将摇杆、按钮等输入信号“翻译”成PC能懂的键盘按键或游戏手柄指令第二将PC的VGA视频信号进行放大和适配安全地驱动娇贵的街机CRT显示器第三将音频信号放大到足以推动街机喇叭。与许多“黑盒”方案不同MONSTERBASH的硬件设计和固件代码完全开源这意味着你可以根据自己框体的具体情况比如特殊的控制设备、特定的显示器型号进行深度定制这才是DIY的乐趣所在。2. 核心设计思路与方案选型2.1 为什么选择Arduino DUE作为核心在规划这样一个接口板时主控芯片的选择至关重要。市面上常见的方案有使用专用CPLD/FPGA、低端8位MCU如Arduino Uno用的ATmega328P或更强大的32位ARM MCU。MONSTERBASH最终选择了Arduino DUE这背后有几个非常实际的考量。首先性能与资源。Arduino DUE搭载了一颗84MHz的32位ARM Cortex-M3内核这比传统的8位AVR单片机如16MHz的ATmega32U4强大得多。街机输入扫描虽然看似简单但当我们希望实现无延迟的响应、复杂的组合键如“连发”功能、或者未来扩展支持需要高速脉冲计数的光学摇杆/轨迹球时更高的处理速度和更宽的数据位宽就能提供充足的余量。此外DUE拥有更多的GPIO引脚和硬件串口为连接更多输入标准JAMMA有最多24路数字输入4路模拟输入和可能的调试、通信功能提供了硬件基础。其次开发生态与易用性。Arduino生态拥有庞大的用户群和丰富的库资源。例如实现USB HID人机接口设备功能无论是模拟键盘还是游戏手柄都有成熟稳定的库如Keyboard库和Joystick库可供调用极大地降低了开发门槛。对于大多数爱好者来说在Arduino IDE中修改几行代码来映射按键远比从头开始用C语言编写USB协议栈要现实得多。最后3.3V逻辑电平的考量。DUE的工作电压是3.3V这是一个双刃剑。弊端是传统的街机信号多是5V TTL电平直接连接需要电平转换。但优势在于3.3V系统功耗更低发热更小并且与许多现代外设如某些传感器、模块的电压更匹配。对于视频同步信号的处理3.3V的输入门槛也更容易通过简单的电阻分压来实现安全接入避免损坏MCU。2.2 整体系统架构解析MONSTERBASH的架构可以清晰地分为三个功能模块输入处理模块、视频处理模块和音频处理模块。这三个模块围绕Arduino DUE协同工作。输入处理模块这是接口板的“大脑”功能部分。所有来自JAMMA连接器的控制信号上、下、左、右、各功能按钮、投币、开始等都以数字输入的形式接入DUE的GPIO。DUE持续扫描这些引脚的状态。同时4路模拟输入端子可以连接光枪的电位器或270度旋转方向盘等模拟设备。固件程序负责将这些物理输入转化为对应的USB HID报告描述符并通过DUE的Native USB端口发送给PC让PC认为连接了一个键盘或游戏手柄。视频处理模块这是项目的技术难点和安全性核心。PC的VGA输出包含R、G、B三路模拟信号和行同步H-Sync、场同步V-Sync数字信号。街机CRT显示器同样需要RGB模拟信号但通常接受一个复合同步信号Composite Sync。该模块首先使用一个由电阻和二极管组成的简单电路将分离的H/V同步信号合并为复合同步信号并分压至3.3V供DUE检测。DUE通过测量同步信号的频率来判断PC输出的分辨率/刷新率是否在街机显示器安全范围内例如避免输出高分辨率的桌面信号烧毁低行频的CRT。核心视频放大则由一颗THS7374视频运放完成它将微弱的VGA RGB信号放大到足以驱动CRT的电压摆幅并通过可调电阻来匹配不同显示器如街机原装管或改装电视的输入阻抗。音频处理模块相对简单独立。PC的音频输出通常是3.5mm接口的线路电平接入一个基于LM386的经典小功率音频放大电路。该电路由街机电源提供的12V供电将信号放大到足以推动街机内置喇叭的功率。一个可调电阻用于控制音量。注意视频信号的处理是重中之重错误的接线或参数可能导致昂贵的CRT显示器永久损坏。MONSTERBASH设计中的同步频率检测和视频放大使能控制是一个关键的安全保护措施。在确认同步信号频率符合预期例如15kHz即标准低解信号之前DUE会保持THS7374处于禁用状态从而没有视频信号输出到显示器。3. 硬件电路详解与关键元件选型3.1 视频放大与同步处理电路视频通路的质量直接决定了最终画面的清晰度、色彩和稳定性。这里我们深入看一下几个关键设计点。视频放大器THS7374选择这颗芯片而非简单的晶体管放大电路是出于对信号完整性的考虑。THS7374是一颗集成式的四通道视频放大器我们用了其中三个通道给RGB它具有高带宽、低噪声和优秀的抗干扰能力。其“禁用”Disable引脚是关键它允许Arduino DUE通过一个GPIO脚直接控制整个视频放大器的输出通断实现了软件层面的“硬开关”保护。阻抗匹配与电平调整VGA标准输出阻抗是75欧姆信号幅度约为0.7Vpp。而不同街机CRT的输入阻抗可能从75欧姆到几百欧姆不等。直接连接可能导致信号反射、过冲或衰减。MONSTERBASH在THS7374的每个输出通道上串联了一个500欧姆的可调电阻Trimpot。通过调整这个电阻可以改变输出级的驱动能力从而与显示器的输入阻抗达到近似匹配获得最佳的图像效果。这是一个非常实用的“调校”环节因为每台显示器的状态都可能因老化而不同。同步信号合并与降压标准的数字同步信号是5V TTL电平。DUE的GPIO可承受电压是3.3V因此必须降压。设计中使用了一个由1KΩ和2.2KΩ电阻组成的分压器原理图中简化为一个示意将大约5V的同步信号降至约3.3V * (1K/(1K2.2K)) ≈ 1.5V这仍在DUE识别高电平的可靠范围内。同时利用一个1N4148二极管进行“线与”逻辑将行、场同步合并为一个复合同步信号供DUE的频率检测和显示器使用。实操心得焊接THS7374这类SSOP封装0.65mm引脚间距的芯片对新手是个挑战。我的经验是1. 使用高质量的助焊膏我推荐RMA型涂在焊盘上。2. 先用烙铁给一个对角线的两个焊盘上少量锡。3. 用镊子将芯片对准放好固定这两个点。4. 然后使用“拖焊”技巧在烙铁头上挂适量锡从芯片引脚的一侧快速拖到另一侧表面张力会使多余的锡被带走留下完美的焊点。务必保持通风并准备一块吸锡编织线处理连锡。多练习几次成功率会大大提升。3.2 输入接口与电源设计JAMMA接口连接JAMMA标准定义了56个金手指MONSTERBASH板通过一个标准的56针孔式连接器或直接焊接排线与之对接。板上的设计将玩家1/2的控制线、投币、测试等开关信号通过上拉电阻连接到DUE的GPIO。当街机按钮按下时对应的线路接地DUE检测到低电平。这种“低电平有效”的设计符合大多数开关的接法。模拟输入接口板载的4路模拟输入通过螺丝端子引出。每路都连接至DUE的一个模拟输入引脚A0-A3。这些引脚可以读取0-3.3V的电压。对于光枪其电位器会随着瞄准位置输出变化的电压对于模拟方向盘也是类似的原理。在固件中你需要编写代码将ADC读取的数值映射到游戏手柄的某个轴如X轴上。电源分配整个板子的电源来自街机电源通过JAMMA接口提供的5V和12V。5V主要为Arduino DUE通过其VIN引脚DUE板载稳压到3.3V和数字电路部分供电。12V则专门供给LM386音频放大电路以确保有足够的电压摆幅来提供驱动喇叭的功率。在电源入口处分别放置了10uF和100nF的电容进行退耦以滤除高频和低频噪声这是保证系统稳定尤其是音频纯净、视频无干扰的基础。3.3 物料清单BOM与采购建议以下是核心物料清单你可以根据它进行采购类别元件规格/型号数量备注核心板Monsterbash PCB-1需自行在PCB打样厂下单Arduino DUE-1注意是DUE不是其他型号视频部分VGA母座PCB安装90度1推荐带屏蔽壳的视频放大器THS73741SSOP-16封装备多一两颗二极管1N41481电阻820Ω1可调电阻500Ω (Trimpot)3用于RGB输出调校LED3mm任意颜色1电源指示电阻1KΩ6同步分压、上拉等电阻220Ω1LED限流电解电容22uF2电源滤波涤纶电容100nF1高频滤波音频部分音频放大器LM386N-11DIP-8封装易焊接电解电容10uF2电解电容220uF1输出耦合涤纶电容47nF, 22nF, 100nF各1频率补偿、滤波电阻10Ω, 5.1KΩ各1增益设置可调电阻10KΩ (Trimpot)1音量调节可换为面板旋钮其他排针2.54mm间距40Pin2排连接Arduino DUE连接线VGA线、音频线各1长度根据机箱内布局定提示PCB设计文件通常以Gerber格式提供。你可以将文件打包成ZIP上传到如PCBWay、JLCPCB等在线打样平台。对于此板选择1.6mm板厚、FR-4材料、有铅喷锡便于焊接即可。颜色任选不影响功能。首次制作建议做5-10片平摊下来单价更划算也可以留作备用或分享给朋友。4. 固件开发与功能配置详解4.1 开发环境搭建与库安装要让Arduino DUE跑起来需要先配置好软件环境。安装Arduino IDE从Arduino官网下载并安装最新版的IDE。添加DUE支持打开IDE进入“文件”-“首选项”在“附加开发板管理器网址”中添加DUE核心的URL通常为https://www.arduino.cc/download.php?f/package_arduinohardware_index.json。然后进入“工具”-“开发板”-“开发板管理器”搜索“Arduino SAM Boards (32-bits ARM Cortex-M3)”并安装。安装USB驱动根据你的操作系统可能需要安装Arduino DUE的USB端口驱动具体请参考Arduino官方文档。安装第三方库针对摇杆固件如果你打算使用“Joystick”模式的固件需要安装Joystick库。在IDE中点击“项目”-“加载库”-“管理库”搜索“Joystick”选择由“Matthew Heironimus”开发的版本进行安装。4.2 固件代码结构解析项目提供的两个基础固件键盘和摇杆结构相似主要包含以下几个部分// 示例代码结构以键盘固件为例 #include Keyboard.h // 内置键盘库 // 1. 引脚定义 const int syncPin 2; // 复合同步信号输入引脚 const int videoEnablePin 3; // THS7374使能引脚 const int buttonPins[] {4, 5, 6, ...}; // 所有按钮对应的引脚数组 const int shiftButtonPin 22; // “开始”键作为Shift功能键 // 2. 变量声明 int syncFrequency 0; bool videoEnabled false; bool shiftPressed false; // 3. 按键映射表 // 普通模式下的按键映射 char keyMapNormal[] {q, w, e, a, s, d, ...}; // 对应MAME默认键位 // Shift模式下的按键映射按住开始键时 char keyMapShift[] {1, 2, 3, 4, 5, 6, ...}; // 对应功能键、投币等 void setup() { // 初始化串口用于调试 Serial.begin(115200); // 初始化键盘库 Keyboard.begin(); // 配置引脚模式 pinMode(syncPin, INPUT); pinMode(videoEnablePin, OUTPUT); digitalWrite(videoEnablePin, LOW); // 初始禁用视频输出 for(int i0; inumButtons; i) { pinMode(buttonPins[i], INPUT_PULLUP); // 启用内部上拉电阻 } pinMode(shiftButtonPin, INPUT_PULLUP); } void loop() { // 4. 同步频率检测 syncFrequency measureSyncFrequency(syncPin); if(syncFrequency 14000 syncFrequency 16000) { // 检测是否为~15kHz if(!videoEnabled) { digitalWrite(videoEnablePin, HIGH); videoEnabled true; Serial.println(Video AMP ENABLED - 15kHz Sync Detected); } } else { if(videoEnabled) { digitalWrite(videoEnablePin, LOW); videoEnabled false; Serial.println(Video AMP DISABLED - Unsafe Sync Frequency); } } // 5. 读取Shift键状态 shiftPressed (digitalRead(shiftButtonPin) LOW); // 6. 扫描所有按钮 for(int i0; inumButtons; i) { int buttonState digitalRead(buttonPins[i]); // ... 这里需要添加防抖逻辑和状态跟踪 ... if(buttonState LOW lastButtonState[i] HIGH) { // 按下瞬间 char keyToPress shiftPressed ? keyMapShift[i] : keyMapNormal[i]; Keyboard.press(keyToPress); } if(buttonState HIGH lastButtonState[i] LOW) { // 释放瞬间 char keyToPress shiftPressed ? keyMapShift[i] : keyMapNormal[i]; Keyboard.release(keyToPress); } lastButtonState[i] buttonState; } delay(1); // 短暂延时降低CPU占用 } // 7. 测量频率的函数示例需完善 long measureSyncFrequency(int pin) { // 使用pulseIn或外部中断定时器测量高/低电平时间 // 计算频率 1 / 周期 // 返回频率值Hz }核心功能解读同步检测measureSyncFrequency函数需要精确实现。一个可靠的方法是使用pulseIn(pin, HIGH)测量一个完整周期的时间或者更高效地使用外部中断引脚触发在中断服务程序里用微秒定时器计算周期。只有检测到频率在安全范围例如14-16kHz对应标准低解信号才使能视频放大。输入扫描与防抖机械按钮在按下和释放时会产生抖动导致多次误触发。代码中需要实现软件防抖例如在检测到状态变化后等待几毫秒再次读取确认状态稳定后再执行动作。lastButtonState数组就是用来跟踪上一次状态的。Shift功能通过检测“开始”键是否被按住切换两套不同的按键映射表。这巧妙地用单个按钮扩展了控制能力非常适合在模拟器前端中进行菜单导航例如一套映射游戏控制另一套映射菜单操作。4.3 自定义按键映射与功能扩展开源固件的最大优势就是可定制性。你可以轻松修改keyMapNormal和keyMapShift数组将街机按钮映射到任何你需要的键盘按键上。例如如果你用的不是MAME而是其他模拟器如FinalBurn Neo, RetroArch或者前端软件如LaunchBox, Attract-Mode只需根据其键位设置修改这里的字符即可。对于摇杆固件原理类似但使用的是Joystick库的API如Joystick.setButton(buttonNumber, state)和Joystick.setXAxis(value)用于模拟输入。你可以在setup()中调用Joystick.begin()进行初始化。扩展思路支持光枪将模拟输入引脚A0-A3读取的ADC值通过map()函数映射到Joystick.setXAxis()和Joystick.setYAxis()的范围内即可实现光枪定位。支持连发功能在按钮扫描循环中为特定按钮添加一个计时器。当按钮被长时间按住时以一定频率如每秒10次自动模拟按下/释放动作。状态指示灯可以利用DUE板载的LED或外接一个LED用不同的闪烁模式来指示当前状态如等待同步、正常运行、错误等。5. 组装、调试与系统集成实战5.1 PCB焊接与组装步骤准备与检查收到PCB后先目视检查有无明显缺陷。对照BOM清单清点所有元件。焊接顺序建议从低到高先焊贴片电阻、电容这些元件体积小先焊接可以避免被大元件挡住。注意阻容值不要弄错。焊接IC底座如果有对于LM386这类DIP封装的芯片强烈建议使用IC插座方便日后更换。焊接THS7374视频运放这是最精细的步骤。按照前文提到的拖焊技巧操作。焊接完成后用放大镜检查有无桥连或虚焊并用万用表通断档测量相邻引脚是否短路。焊接排针将两排40针排针插入Arduino DUE和Monsterbash PCB的对应孔位对齐后焊接固定。这确保了DUE能稳固地插在接口板上。焊接连接器与端子焊接VGA母座、螺丝端子等。VGA母座的金属外壳焊盘需要大功率烙铁和足够焊锡以确保接地良好。最后焊接电解电容和可调电阻注意电解电容的极性长脚正短脚负PCB上有“”标记。焊接后清洁与检查使用洗板水或无水酒精和硬毛刷清除残留的助焊剂。再次全面检查焊点确保无虚焊、短路。5.2 上电前检查与初步测试安全第一在连接任何电源或显示器前请务必完成以下检查短路测试使用万用表电阻档测量PCB上5V和GND、12V和GND之间的电阻。在未上电、未插任何芯片的情况下电阻不应为0或非常小几欧姆。如果接近短路说明存在焊接桥连或元件装反。电源极性检查再次确认所有有极性的元件电解电容、二极管、LED、IC方向与PCB丝印一致。分步上电先不要插入Arduino DUE和任何IC。将街机电源的5V和12V正确连接到JAMMA接口的对应引脚或通过接线端子接入PCB。用万用表电压档测量PCB上的5V和12V测试点或相关芯片的电源引脚确认电压稳定且正确。断电插入LM386音频运放。上电用手触摸音频输入线喇叭应发出“嗡嗡”的感应噪声说明音频部分基本正常。调节音量电位器噪声应有变化。断电插入THS7374视频运放。此时切勿连接显示器5.3 系统连接与功能调试连接PC与接口板用VGA线连接PC和接口板用音频线连接PC声卡输出和接口板音频输入。通过USB线将Arduino DUE连接到PC。上传固件在Arduino IDE中选择开发板为“Arduino Due (Programming Port)”选择正确的COM端口。打开对应的键盘或摇杆固件代码点击上传。同步信号与视频调试将PC显示分辨率设置为街机显示器支持的模式例如通过CRT Emudriver等工具设置为640x48060Hz水平频率约31.5kHz但复合同步是15.7kHz或更低解像度如320x24060Hz~15.7kHz。打开串口监视器设置波特率为115200。你应该能看到固件输出的调试信息当检测到正确的同步频率时会打印“Video AMP ENABLED”信息并且板子上连接视频使能引脚的LED如果有应点亮。此时才可以谨慎地将接口板的视频输出通过JAMMA接口或RGB线连接到街机显示器。开机后显示器上应出现PC的桌面图像。调节RGB通道的三个500欧姆可调电阻观察画面颜色、亮度和聚焦的变化直到获得清晰、色彩平衡、无重影的图像为止。输入功能测试对于键盘固件打开一个文本编辑器逐个按下街机按钮看是否输出对应的字母或数字。对于摇杆固件打开Windows的“设置”-“游戏控制器”查看是否识别出一个游戏手柄并测试每个按钮和摇杆方向。测试“Shift”功能按住“开始”键再按其他按钮应输出另一套映射的按键。音频调试播放一段测试音调节板上的音量电位器确保声音清晰无破音。注意街机喇叭的阻抗如果声音太小或失真可能需要调整LM386外围的增益电阻R5原理图中通常为1.2KΩ和10uF电容并联在1、8脚之间增大电阻可降低增益。6. 常见问题排查与进阶技巧6.1 问题速查表现象可能原因排查步骤无图像电源灯不亮电源未接通或接反PCB电源部分短路。1. 检查电源线连接。2. 断电用万用表测5V/GND电阻。3. 检查保险丝如果有。电源灯亮但无图像视频放大器未使能同步信号异常VGA线问题。1. 查看串口输出确认是否检测到同步信号。2. 检查同步信号输入引脚接线和分压电阻。3. 检查videoEnablePin输出是否为高电平。4. 更换VGA线测试。图像模糊、有重影、颜色不正RGB输出阻抗不匹配信号线过长或质量差显示器老化。1.重点调整RGB输出端的三个500欧姆可调电阻。2. 使用屏蔽良好的高质量线缆。3. 检查显示器本身的会聚和聚焦调整。图像不稳定跳动、滚动同步信号不稳定或频率不准地线连接不良。1. 确保PC输出的是稳定的低解信号。2. 检查同步信号合并/分压电路焊接。3. 加强所有设备之间的地线连接共地。按钮无反应或乱跳内部上拉电阻未启用按键接触不良代码防抖逻辑问题。1. 确认代码中pinMode(pin, INPUT_PULLUP)设置正确。2. 用万用表测量按钮按下时对应GPIO是否可靠接地。3. 优化代码中的防抖延时参数。PC无法识别USB设备Arduino DUE驱动未安装USB线仅供电无数据固件未正确上传。1. 检查设备管理器中是否有未知设备。2. 尝试使用DUE上另一个USB口Programming Port。3. 重新上传一个最简单的Blink程序测试DUE是否正常。音频无声或噪音大音量电位器调至最小音频线接触不良LM386损坏或焊接问题电源噪声。1. 调节音量电位器。2. 触碰音频输入脚听是否有感应噪声。3. 检查LM386的电源引脚电压是否为12V左右。4. 在12V电源入口处增加更大的滤波电容如1000uF。6.2 进阶技巧与优化建议同步检测的优化基础版的频率检测可能在信号模式切换时如游戏切换分辨率有短暂误判。可以加入“迟滞”和“确认”机制例如连续检测到5个周期都在安全范围内才使能输出失去同步信号后延迟100ms再关闭避免画面闪烁。输入响应速度delay(1)在主循环中会引入至少1ms的延迟。对于追求极限响应的玩家可以尝试使用中断来检测按钮按下但要注意消抖或者使用更高效的状态机扫描方式将扫描周期控制在1ms以内。支持更多设备4路模拟输入可能不够用。DUE有多个模拟输入引脚可以扩展更多的螺丝端子。对于需要数字脉冲输入的光学设备如轨迹球、旋转编码器可以连接到DUE的数字引脚并编写代码使用中断来计数脉冲。固件配置界面高级玩家可以尝试为DUE添加一个OLED屏幕和几个导航按钮制作一个简单的菜单系统允许直接在街机面板上修改按键映射、调整模拟输入死区等参数而无需重新编译上传代码。外壳与集成为接口板设计一个3D打印或亚克力切割的外壳可以使其在街机机箱内更整洁、安全。将音量电位器、视频调节电位器通过延长线引到便于操作的位置如服务门内侧方便后期微调。这个项目最吸引人的地方就在于它从一个可用的方案出发为你提供了无限可能的修改和扩展起点。无论是修复一台老旧的街机还是打造一台终极的复古游戏一体机MONSTERBASH都提供了一个坚实、透明且充满乐趣的硬件基础。
基于Arduino DUE的JAMMA转PC接口板设计:开源街机模拟器硬件方案
发布时间:2026/6/2 8:08:43
1. 项目概述与核心价值如果你和我一样是个对街机厅的“黄金年代”念念不忘的老玩家同时又喜欢捣鼓硬件那么“如何让一台真正的街机框体完美运行PC上的模拟器”这个问题一定困扰过你。街机框体的灵魂在于那块硕大的CRT显示器、那个摇杆和六个按钮组成的控制面板以及投币时那一声清脆的“咔哒”响。但要把现代PC塞进去让它能接收这些“古老”的指令并安全地输出图像和声音可不是插几根线那么简单。市面上有现成的商业转换板但要么价格不菲要么功能死板无法满足我们这些“折腾党”的定制化需求。这就是“MONSTERBASH”项目诞生的背景。它是一个基于Arduino DUE微控制器设计的、开源固件的JAMMA转PC接口板。简单来说它就是一座桥梁一端连接着标准的街机JAMMA接口承载了所有控制信号、音频和视频另一端连接着你的PC。它的核心任务有三个第一将摇杆、按钮等输入信号“翻译”成PC能懂的键盘按键或游戏手柄指令第二将PC的VGA视频信号进行放大和适配安全地驱动娇贵的街机CRT显示器第三将音频信号放大到足以推动街机喇叭。与许多“黑盒”方案不同MONSTERBASH的硬件设计和固件代码完全开源这意味着你可以根据自己框体的具体情况比如特殊的控制设备、特定的显示器型号进行深度定制这才是DIY的乐趣所在。2. 核心设计思路与方案选型2.1 为什么选择Arduino DUE作为核心在规划这样一个接口板时主控芯片的选择至关重要。市面上常见的方案有使用专用CPLD/FPGA、低端8位MCU如Arduino Uno用的ATmega328P或更强大的32位ARM MCU。MONSTERBASH最终选择了Arduino DUE这背后有几个非常实际的考量。首先性能与资源。Arduino DUE搭载了一颗84MHz的32位ARM Cortex-M3内核这比传统的8位AVR单片机如16MHz的ATmega32U4强大得多。街机输入扫描虽然看似简单但当我们希望实现无延迟的响应、复杂的组合键如“连发”功能、或者未来扩展支持需要高速脉冲计数的光学摇杆/轨迹球时更高的处理速度和更宽的数据位宽就能提供充足的余量。此外DUE拥有更多的GPIO引脚和硬件串口为连接更多输入标准JAMMA有最多24路数字输入4路模拟输入和可能的调试、通信功能提供了硬件基础。其次开发生态与易用性。Arduino生态拥有庞大的用户群和丰富的库资源。例如实现USB HID人机接口设备功能无论是模拟键盘还是游戏手柄都有成熟稳定的库如Keyboard库和Joystick库可供调用极大地降低了开发门槛。对于大多数爱好者来说在Arduino IDE中修改几行代码来映射按键远比从头开始用C语言编写USB协议栈要现实得多。最后3.3V逻辑电平的考量。DUE的工作电压是3.3V这是一个双刃剑。弊端是传统的街机信号多是5V TTL电平直接连接需要电平转换。但优势在于3.3V系统功耗更低发热更小并且与许多现代外设如某些传感器、模块的电压更匹配。对于视频同步信号的处理3.3V的输入门槛也更容易通过简单的电阻分压来实现安全接入避免损坏MCU。2.2 整体系统架构解析MONSTERBASH的架构可以清晰地分为三个功能模块输入处理模块、视频处理模块和音频处理模块。这三个模块围绕Arduino DUE协同工作。输入处理模块这是接口板的“大脑”功能部分。所有来自JAMMA连接器的控制信号上、下、左、右、各功能按钮、投币、开始等都以数字输入的形式接入DUE的GPIO。DUE持续扫描这些引脚的状态。同时4路模拟输入端子可以连接光枪的电位器或270度旋转方向盘等模拟设备。固件程序负责将这些物理输入转化为对应的USB HID报告描述符并通过DUE的Native USB端口发送给PC让PC认为连接了一个键盘或游戏手柄。视频处理模块这是项目的技术难点和安全性核心。PC的VGA输出包含R、G、B三路模拟信号和行同步H-Sync、场同步V-Sync数字信号。街机CRT显示器同样需要RGB模拟信号但通常接受一个复合同步信号Composite Sync。该模块首先使用一个由电阻和二极管组成的简单电路将分离的H/V同步信号合并为复合同步信号并分压至3.3V供DUE检测。DUE通过测量同步信号的频率来判断PC输出的分辨率/刷新率是否在街机显示器安全范围内例如避免输出高分辨率的桌面信号烧毁低行频的CRT。核心视频放大则由一颗THS7374视频运放完成它将微弱的VGA RGB信号放大到足以驱动CRT的电压摆幅并通过可调电阻来匹配不同显示器如街机原装管或改装电视的输入阻抗。音频处理模块相对简单独立。PC的音频输出通常是3.5mm接口的线路电平接入一个基于LM386的经典小功率音频放大电路。该电路由街机电源提供的12V供电将信号放大到足以推动街机内置喇叭的功率。一个可调电阻用于控制音量。注意视频信号的处理是重中之重错误的接线或参数可能导致昂贵的CRT显示器永久损坏。MONSTERBASH设计中的同步频率检测和视频放大使能控制是一个关键的安全保护措施。在确认同步信号频率符合预期例如15kHz即标准低解信号之前DUE会保持THS7374处于禁用状态从而没有视频信号输出到显示器。3. 硬件电路详解与关键元件选型3.1 视频放大与同步处理电路视频通路的质量直接决定了最终画面的清晰度、色彩和稳定性。这里我们深入看一下几个关键设计点。视频放大器THS7374选择这颗芯片而非简单的晶体管放大电路是出于对信号完整性的考虑。THS7374是一颗集成式的四通道视频放大器我们用了其中三个通道给RGB它具有高带宽、低噪声和优秀的抗干扰能力。其“禁用”Disable引脚是关键它允许Arduino DUE通过一个GPIO脚直接控制整个视频放大器的输出通断实现了软件层面的“硬开关”保护。阻抗匹配与电平调整VGA标准输出阻抗是75欧姆信号幅度约为0.7Vpp。而不同街机CRT的输入阻抗可能从75欧姆到几百欧姆不等。直接连接可能导致信号反射、过冲或衰减。MONSTERBASH在THS7374的每个输出通道上串联了一个500欧姆的可调电阻Trimpot。通过调整这个电阻可以改变输出级的驱动能力从而与显示器的输入阻抗达到近似匹配获得最佳的图像效果。这是一个非常实用的“调校”环节因为每台显示器的状态都可能因老化而不同。同步信号合并与降压标准的数字同步信号是5V TTL电平。DUE的GPIO可承受电压是3.3V因此必须降压。设计中使用了一个由1KΩ和2.2KΩ电阻组成的分压器原理图中简化为一个示意将大约5V的同步信号降至约3.3V * (1K/(1K2.2K)) ≈ 1.5V这仍在DUE识别高电平的可靠范围内。同时利用一个1N4148二极管进行“线与”逻辑将行、场同步合并为一个复合同步信号供DUE的频率检测和显示器使用。实操心得焊接THS7374这类SSOP封装0.65mm引脚间距的芯片对新手是个挑战。我的经验是1. 使用高质量的助焊膏我推荐RMA型涂在焊盘上。2. 先用烙铁给一个对角线的两个焊盘上少量锡。3. 用镊子将芯片对准放好固定这两个点。4. 然后使用“拖焊”技巧在烙铁头上挂适量锡从芯片引脚的一侧快速拖到另一侧表面张力会使多余的锡被带走留下完美的焊点。务必保持通风并准备一块吸锡编织线处理连锡。多练习几次成功率会大大提升。3.2 输入接口与电源设计JAMMA接口连接JAMMA标准定义了56个金手指MONSTERBASH板通过一个标准的56针孔式连接器或直接焊接排线与之对接。板上的设计将玩家1/2的控制线、投币、测试等开关信号通过上拉电阻连接到DUE的GPIO。当街机按钮按下时对应的线路接地DUE检测到低电平。这种“低电平有效”的设计符合大多数开关的接法。模拟输入接口板载的4路模拟输入通过螺丝端子引出。每路都连接至DUE的一个模拟输入引脚A0-A3。这些引脚可以读取0-3.3V的电压。对于光枪其电位器会随着瞄准位置输出变化的电压对于模拟方向盘也是类似的原理。在固件中你需要编写代码将ADC读取的数值映射到游戏手柄的某个轴如X轴上。电源分配整个板子的电源来自街机电源通过JAMMA接口提供的5V和12V。5V主要为Arduino DUE通过其VIN引脚DUE板载稳压到3.3V和数字电路部分供电。12V则专门供给LM386音频放大电路以确保有足够的电压摆幅来提供驱动喇叭的功率。在电源入口处分别放置了10uF和100nF的电容进行退耦以滤除高频和低频噪声这是保证系统稳定尤其是音频纯净、视频无干扰的基础。3.3 物料清单BOM与采购建议以下是核心物料清单你可以根据它进行采购类别元件规格/型号数量备注核心板Monsterbash PCB-1需自行在PCB打样厂下单Arduino DUE-1注意是DUE不是其他型号视频部分VGA母座PCB安装90度1推荐带屏蔽壳的视频放大器THS73741SSOP-16封装备多一两颗二极管1N41481电阻820Ω1可调电阻500Ω (Trimpot)3用于RGB输出调校LED3mm任意颜色1电源指示电阻1KΩ6同步分压、上拉等电阻220Ω1LED限流电解电容22uF2电源滤波涤纶电容100nF1高频滤波音频部分音频放大器LM386N-11DIP-8封装易焊接电解电容10uF2电解电容220uF1输出耦合涤纶电容47nF, 22nF, 100nF各1频率补偿、滤波电阻10Ω, 5.1KΩ各1增益设置可调电阻10KΩ (Trimpot)1音量调节可换为面板旋钮其他排针2.54mm间距40Pin2排连接Arduino DUE连接线VGA线、音频线各1长度根据机箱内布局定提示PCB设计文件通常以Gerber格式提供。你可以将文件打包成ZIP上传到如PCBWay、JLCPCB等在线打样平台。对于此板选择1.6mm板厚、FR-4材料、有铅喷锡便于焊接即可。颜色任选不影响功能。首次制作建议做5-10片平摊下来单价更划算也可以留作备用或分享给朋友。4. 固件开发与功能配置详解4.1 开发环境搭建与库安装要让Arduino DUE跑起来需要先配置好软件环境。安装Arduino IDE从Arduino官网下载并安装最新版的IDE。添加DUE支持打开IDE进入“文件”-“首选项”在“附加开发板管理器网址”中添加DUE核心的URL通常为https://www.arduino.cc/download.php?f/package_arduinohardware_index.json。然后进入“工具”-“开发板”-“开发板管理器”搜索“Arduino SAM Boards (32-bits ARM Cortex-M3)”并安装。安装USB驱动根据你的操作系统可能需要安装Arduino DUE的USB端口驱动具体请参考Arduino官方文档。安装第三方库针对摇杆固件如果你打算使用“Joystick”模式的固件需要安装Joystick库。在IDE中点击“项目”-“加载库”-“管理库”搜索“Joystick”选择由“Matthew Heironimus”开发的版本进行安装。4.2 固件代码结构解析项目提供的两个基础固件键盘和摇杆结构相似主要包含以下几个部分// 示例代码结构以键盘固件为例 #include Keyboard.h // 内置键盘库 // 1. 引脚定义 const int syncPin 2; // 复合同步信号输入引脚 const int videoEnablePin 3; // THS7374使能引脚 const int buttonPins[] {4, 5, 6, ...}; // 所有按钮对应的引脚数组 const int shiftButtonPin 22; // “开始”键作为Shift功能键 // 2. 变量声明 int syncFrequency 0; bool videoEnabled false; bool shiftPressed false; // 3. 按键映射表 // 普通模式下的按键映射 char keyMapNormal[] {q, w, e, a, s, d, ...}; // 对应MAME默认键位 // Shift模式下的按键映射按住开始键时 char keyMapShift[] {1, 2, 3, 4, 5, 6, ...}; // 对应功能键、投币等 void setup() { // 初始化串口用于调试 Serial.begin(115200); // 初始化键盘库 Keyboard.begin(); // 配置引脚模式 pinMode(syncPin, INPUT); pinMode(videoEnablePin, OUTPUT); digitalWrite(videoEnablePin, LOW); // 初始禁用视频输出 for(int i0; inumButtons; i) { pinMode(buttonPins[i], INPUT_PULLUP); // 启用内部上拉电阻 } pinMode(shiftButtonPin, INPUT_PULLUP); } void loop() { // 4. 同步频率检测 syncFrequency measureSyncFrequency(syncPin); if(syncFrequency 14000 syncFrequency 16000) { // 检测是否为~15kHz if(!videoEnabled) { digitalWrite(videoEnablePin, HIGH); videoEnabled true; Serial.println(Video AMP ENABLED - 15kHz Sync Detected); } } else { if(videoEnabled) { digitalWrite(videoEnablePin, LOW); videoEnabled false; Serial.println(Video AMP DISABLED - Unsafe Sync Frequency); } } // 5. 读取Shift键状态 shiftPressed (digitalRead(shiftButtonPin) LOW); // 6. 扫描所有按钮 for(int i0; inumButtons; i) { int buttonState digitalRead(buttonPins[i]); // ... 这里需要添加防抖逻辑和状态跟踪 ... if(buttonState LOW lastButtonState[i] HIGH) { // 按下瞬间 char keyToPress shiftPressed ? keyMapShift[i] : keyMapNormal[i]; Keyboard.press(keyToPress); } if(buttonState HIGH lastButtonState[i] LOW) { // 释放瞬间 char keyToPress shiftPressed ? keyMapShift[i] : keyMapNormal[i]; Keyboard.release(keyToPress); } lastButtonState[i] buttonState; } delay(1); // 短暂延时降低CPU占用 } // 7. 测量频率的函数示例需完善 long measureSyncFrequency(int pin) { // 使用pulseIn或外部中断定时器测量高/低电平时间 // 计算频率 1 / 周期 // 返回频率值Hz }核心功能解读同步检测measureSyncFrequency函数需要精确实现。一个可靠的方法是使用pulseIn(pin, HIGH)测量一个完整周期的时间或者更高效地使用外部中断引脚触发在中断服务程序里用微秒定时器计算周期。只有检测到频率在安全范围例如14-16kHz对应标准低解信号才使能视频放大。输入扫描与防抖机械按钮在按下和释放时会产生抖动导致多次误触发。代码中需要实现软件防抖例如在检测到状态变化后等待几毫秒再次读取确认状态稳定后再执行动作。lastButtonState数组就是用来跟踪上一次状态的。Shift功能通过检测“开始”键是否被按住切换两套不同的按键映射表。这巧妙地用单个按钮扩展了控制能力非常适合在模拟器前端中进行菜单导航例如一套映射游戏控制另一套映射菜单操作。4.3 自定义按键映射与功能扩展开源固件的最大优势就是可定制性。你可以轻松修改keyMapNormal和keyMapShift数组将街机按钮映射到任何你需要的键盘按键上。例如如果你用的不是MAME而是其他模拟器如FinalBurn Neo, RetroArch或者前端软件如LaunchBox, Attract-Mode只需根据其键位设置修改这里的字符即可。对于摇杆固件原理类似但使用的是Joystick库的API如Joystick.setButton(buttonNumber, state)和Joystick.setXAxis(value)用于模拟输入。你可以在setup()中调用Joystick.begin()进行初始化。扩展思路支持光枪将模拟输入引脚A0-A3读取的ADC值通过map()函数映射到Joystick.setXAxis()和Joystick.setYAxis()的范围内即可实现光枪定位。支持连发功能在按钮扫描循环中为特定按钮添加一个计时器。当按钮被长时间按住时以一定频率如每秒10次自动模拟按下/释放动作。状态指示灯可以利用DUE板载的LED或外接一个LED用不同的闪烁模式来指示当前状态如等待同步、正常运行、错误等。5. 组装、调试与系统集成实战5.1 PCB焊接与组装步骤准备与检查收到PCB后先目视检查有无明显缺陷。对照BOM清单清点所有元件。焊接顺序建议从低到高先焊贴片电阻、电容这些元件体积小先焊接可以避免被大元件挡住。注意阻容值不要弄错。焊接IC底座如果有对于LM386这类DIP封装的芯片强烈建议使用IC插座方便日后更换。焊接THS7374视频运放这是最精细的步骤。按照前文提到的拖焊技巧操作。焊接完成后用放大镜检查有无桥连或虚焊并用万用表通断档测量相邻引脚是否短路。焊接排针将两排40针排针插入Arduino DUE和Monsterbash PCB的对应孔位对齐后焊接固定。这确保了DUE能稳固地插在接口板上。焊接连接器与端子焊接VGA母座、螺丝端子等。VGA母座的金属外壳焊盘需要大功率烙铁和足够焊锡以确保接地良好。最后焊接电解电容和可调电阻注意电解电容的极性长脚正短脚负PCB上有“”标记。焊接后清洁与检查使用洗板水或无水酒精和硬毛刷清除残留的助焊剂。再次全面检查焊点确保无虚焊、短路。5.2 上电前检查与初步测试安全第一在连接任何电源或显示器前请务必完成以下检查短路测试使用万用表电阻档测量PCB上5V和GND、12V和GND之间的电阻。在未上电、未插任何芯片的情况下电阻不应为0或非常小几欧姆。如果接近短路说明存在焊接桥连或元件装反。电源极性检查再次确认所有有极性的元件电解电容、二极管、LED、IC方向与PCB丝印一致。分步上电先不要插入Arduino DUE和任何IC。将街机电源的5V和12V正确连接到JAMMA接口的对应引脚或通过接线端子接入PCB。用万用表电压档测量PCB上的5V和12V测试点或相关芯片的电源引脚确认电压稳定且正确。断电插入LM386音频运放。上电用手触摸音频输入线喇叭应发出“嗡嗡”的感应噪声说明音频部分基本正常。调节音量电位器噪声应有变化。断电插入THS7374视频运放。此时切勿连接显示器5.3 系统连接与功能调试连接PC与接口板用VGA线连接PC和接口板用音频线连接PC声卡输出和接口板音频输入。通过USB线将Arduino DUE连接到PC。上传固件在Arduino IDE中选择开发板为“Arduino Due (Programming Port)”选择正确的COM端口。打开对应的键盘或摇杆固件代码点击上传。同步信号与视频调试将PC显示分辨率设置为街机显示器支持的模式例如通过CRT Emudriver等工具设置为640x48060Hz水平频率约31.5kHz但复合同步是15.7kHz或更低解像度如320x24060Hz~15.7kHz。打开串口监视器设置波特率为115200。你应该能看到固件输出的调试信息当检测到正确的同步频率时会打印“Video AMP ENABLED”信息并且板子上连接视频使能引脚的LED如果有应点亮。此时才可以谨慎地将接口板的视频输出通过JAMMA接口或RGB线连接到街机显示器。开机后显示器上应出现PC的桌面图像。调节RGB通道的三个500欧姆可调电阻观察画面颜色、亮度和聚焦的变化直到获得清晰、色彩平衡、无重影的图像为止。输入功能测试对于键盘固件打开一个文本编辑器逐个按下街机按钮看是否输出对应的字母或数字。对于摇杆固件打开Windows的“设置”-“游戏控制器”查看是否识别出一个游戏手柄并测试每个按钮和摇杆方向。测试“Shift”功能按住“开始”键再按其他按钮应输出另一套映射的按键。音频调试播放一段测试音调节板上的音量电位器确保声音清晰无破音。注意街机喇叭的阻抗如果声音太小或失真可能需要调整LM386外围的增益电阻R5原理图中通常为1.2KΩ和10uF电容并联在1、8脚之间增大电阻可降低增益。6. 常见问题排查与进阶技巧6.1 问题速查表现象可能原因排查步骤无图像电源灯不亮电源未接通或接反PCB电源部分短路。1. 检查电源线连接。2. 断电用万用表测5V/GND电阻。3. 检查保险丝如果有。电源灯亮但无图像视频放大器未使能同步信号异常VGA线问题。1. 查看串口输出确认是否检测到同步信号。2. 检查同步信号输入引脚接线和分压电阻。3. 检查videoEnablePin输出是否为高电平。4. 更换VGA线测试。图像模糊、有重影、颜色不正RGB输出阻抗不匹配信号线过长或质量差显示器老化。1.重点调整RGB输出端的三个500欧姆可调电阻。2. 使用屏蔽良好的高质量线缆。3. 检查显示器本身的会聚和聚焦调整。图像不稳定跳动、滚动同步信号不稳定或频率不准地线连接不良。1. 确保PC输出的是稳定的低解信号。2. 检查同步信号合并/分压电路焊接。3. 加强所有设备之间的地线连接共地。按钮无反应或乱跳内部上拉电阻未启用按键接触不良代码防抖逻辑问题。1. 确认代码中pinMode(pin, INPUT_PULLUP)设置正确。2. 用万用表测量按钮按下时对应GPIO是否可靠接地。3. 优化代码中的防抖延时参数。PC无法识别USB设备Arduino DUE驱动未安装USB线仅供电无数据固件未正确上传。1. 检查设备管理器中是否有未知设备。2. 尝试使用DUE上另一个USB口Programming Port。3. 重新上传一个最简单的Blink程序测试DUE是否正常。音频无声或噪音大音量电位器调至最小音频线接触不良LM386损坏或焊接问题电源噪声。1. 调节音量电位器。2. 触碰音频输入脚听是否有感应噪声。3. 检查LM386的电源引脚电压是否为12V左右。4. 在12V电源入口处增加更大的滤波电容如1000uF。6.2 进阶技巧与优化建议同步检测的优化基础版的频率检测可能在信号模式切换时如游戏切换分辨率有短暂误判。可以加入“迟滞”和“确认”机制例如连续检测到5个周期都在安全范围内才使能输出失去同步信号后延迟100ms再关闭避免画面闪烁。输入响应速度delay(1)在主循环中会引入至少1ms的延迟。对于追求极限响应的玩家可以尝试使用中断来检测按钮按下但要注意消抖或者使用更高效的状态机扫描方式将扫描周期控制在1ms以内。支持更多设备4路模拟输入可能不够用。DUE有多个模拟输入引脚可以扩展更多的螺丝端子。对于需要数字脉冲输入的光学设备如轨迹球、旋转编码器可以连接到DUE的数字引脚并编写代码使用中断来计数脉冲。固件配置界面高级玩家可以尝试为DUE添加一个OLED屏幕和几个导航按钮制作一个简单的菜单系统允许直接在街机面板上修改按键映射、调整模拟输入死区等参数而无需重新编译上传代码。外壳与集成为接口板设计一个3D打印或亚克力切割的外壳可以使其在街机机箱内更整洁、安全。将音量电位器、视频调节电位器通过延长线引到便于操作的位置如服务门内侧方便后期微调。这个项目最吸引人的地方就在于它从一个可用的方案出发为你提供了无限可能的修改和扩展起点。无论是修复一台老旧的街机还是打造一台终极的复古游戏一体机MONSTERBASH都提供了一个坚实、透明且充满乐趣的硬件基础。