基于RP2040与CircuitPython的SNES手柄USB改造指南 1. 项目概述与核心价值如果你和我一样对90年代那台灰紫色的Super Nintendo Entertainment SystemSNES或我们更熟悉的“超级任天堂”有着难以割舍的情怀那么你家里很可能也躺着几个早已落灰的SNES手柄。这些手柄的十字键和ABXY按键手感是后来无数手柄模仿却难以超越的经典。但问题是它们那专用的接口让它们在现代的PC、Mac甚至树莓派上毫无用武之地只能作为一段记忆被封存。这个项目就是要给这些“老伙计”注入新的灵魂。我们将利用一块小巧但功能强大的Adafruit KB2040开发板基于RP2040芯片配合极易上手的CircuitPython编程环境将原装或第三方兼容的SNES手柄改造成一个标准的USB HID游戏手柄。改造完成后它就能像任何现代Xbox或PS手柄一样即插即用地在Windows、macOS、Linux甚至复古游戏机上使用玩转Steam游戏、复古模拟器或是作为自定义控制器用于创意项目。整个改造过程的核心是理解并桥接两种“语言”一是SNES手柄古老的、基于移位寄存器的串行通信协议二是现代计算机通用的USB HID协议。我们不需要破坏手柄的任何原有电路只是通过“搭桥”的方式用几根细线将手柄的“大脑”PCB与KB2040连接起来。这意味着改造是100%可逆的哪天你想把它装回原主机拆掉这几根线即可完美保留其收藏价值。2. 核心硬件解析与选型考量2.1 为什么是KB2040市面上微控制器板卡琳琅满目为何独选Adafruit的KB2040这背后有几个经过实战检验的考量。首先形态与尺寸。KB2040采用了经典的“Arduino Pro Micro”外形尺寸非常小巧约33mm x 18mm能轻松塞进SNES手柄内部有限的空间。其引脚排列在两侧也便于我们焊接连接线。其次核心芯片RP2040。这是树莓派基金会设计的双核ARM Cortex-M0微控制器性能对于本项目绰绰有余。更重要的是它原生支持USB可以非常方便地被配置成各种USB设备包括HID游戏手柄。其丰富的GPIO和灵活的I/O能力完美适配读取SNES协议的需求。第三CircuitPython的完美支持。Adafruit是CircuitPython的主要维护者其旗下的KB2040拥有“开箱即用”的CircuitPython体验。CircuitPython让我们可以用高级的Python语言来编写固件无需复杂的编译环境和底层寄存器操作极大地降低了开发门槛。对于实现USB HID描述符、处理按钮扫描逻辑这类任务Python代码比C/C要直观易懂得多。最后社区与生态。Adafruit提供了极其详尽的文档、库和示例。本项目所需的usb_hid、digitalio等库都已高度优化且稳定。当你在焊接或编程中遇到问题时庞大的社区能提供有力支持。注意关于电压匹配SNES手柄内部逻辑电平是5V而KB2040的GPIO引脚耐受电压是3.3V。幸运的是SNES手柄的移位寄存器芯片通常是74HC系列在3.3V下也能正常工作。因此我们可以直接将手柄的VCC电源连接到KB2040的3.3V输出引脚实现安全的电平匹配无需额外的电平转换电路这简化了改造步骤。2.2 材料清单与工具准备一份清晰的物料清单是成功的一半。除了主角SNES手柄和KB2040一些细节材料的选择直接影响最终成品的可靠性和美观度。核心材料SNES/超级任天堂兼容手柄原装或高质量的第三方手柄均可。原装手柄的导电橡胶和按键手感通常更佳。Adafruit KB2040项目的“大脑”。细导线强烈推荐使用30 AWG美国线规的线缆包线。这种线非常细、柔软且外皮颜色多样便于区分。它的粗细正好适合在密集的PCB焊点间穿梭不会因太硬而拉扯焊盘。大约需要2英尺约60厘米五根不同颜色的线用于信号连接另外四根用于USB线。USB-A转Micro-USB数据线用于给KB2040供电和通信。务必确认是数据线而非仅能充电的线缆。长度建议1-2米方便使用。热熔胶与胶枪用于在手柄内部固定KB2040板防止其晃动导致焊点脱落。这是一种非永久性固定方式日后需要维修时可以用酒精或热风枪软化后取下。必备工具电烙铁与焊锡建议使用尖头、可调温的烙铁设置在320°C-350°C为宜。细径的含铅或无铅焊锡0.6mm-0.8mm更适合精细焊接。吸锡线或吸锡器万一焊点短路或需要修改它们是救命稻草。精密螺丝刀套装SNES手柄背面的螺丝是十字Phillips螺丝需要合适的螺丝刀打开。斜口钳/电子剪钳用于修剪导线和元器件引脚保持内部整洁。万用表可选但强烈推荐在焊接前后用于检查通断、确认电源和地线没有短路能避免很多“玄学”故障。一个简单的数字万用表即可。实操心得导线颜色编码在焊接前花一分钟为你的导线制定一个颜色编码规则并坚持下去例如红色-VCC3.3V黑色-GND黄色-Data绿色-Clock白色-Latch。这会在后续的焊接和调试中为你节省大量时间尤其是在光线不佳的手柄内部排查问题时颜色比用万用表一个个测要直观得多。3. 手柄拆解、清洁与内部结构探秘3.1 安全拆解手柄SNES手柄的固定通常依赖于背面的五颗十字螺丝。使用合适大小的螺丝刀均匀用力将其拧下。特别注意有些第三方手柄的螺丝可能藏在电池盖或铭牌贴纸下面需要仔细检查。打开外壳后你会看到手柄的PCB印刷电路板通过一个排线或插头与外壳上的按键膜、导电橡胶相连。动作一定要轻柔。通常PCB是通过卡扣或螺丝固定在下壳上的小心地将其取下。如果连接的是排线通常有一个黑色的锁紧卡扣轻轻将其抬起即可拔出排线切勿直接拉扯排线本身。取下PCB后你就获得了本次改造的核心部件。此时你可以清晰地看到PCB一侧有一个五针的连接器这就是原来连接主机线缆的接口。我们需要焊接的五个点正是这个连接器的五个引脚。3.2 深度清洁强烈建议这些手柄大多有三十年历史了内部积攒的灰尘、汗渍和氧化层是导致按键接触不良的元凶。改造的同时进行一次彻底清洁能让你的“新”手柄焕发第二春。外壳与按键塑料外壳和按键可以用温水加少量洗洁精清洗用软布或软毛刷轻轻擦洗然后彻底晾干。导电橡胶与PCB触点这是清洁的重点。用棉签蘸取少量99%异丙醇电子清洁剂轻轻擦拭PCB上与导电橡胶接触的圆形金属触点以及导电橡胶本身的黑色导电层。异丙醇挥发快不留残渣能有效去除氧化层。切勿使用水或含油清洁剂。PCB板可以用干燥的软毛刷或压缩气罐清除灰尘。对于顽固污渍同样可用蘸有少量异丙醇的棉签小心擦拭。清洁后在重新组装前可以简单测试一下将PCB放回装上导电橡胶和按键用手指按压导电橡胶对应位置用万用表的通断档测量PCB背面五针接口对应引脚之间的电阻变化例如按下A键时某个数据引脚与地之间的电阻应变小。这能验证手柄的原始功能是否完好避免在改造完成后才发现是手柄本身有问题。3.3 理解SNES手柄通信协议要成功“翻译”手柄的按键信号我们必须先理解它的“语言”。SNES手柄内部使用了两个8位并行输入串行输出PISO移位寄存器通常是74HC165或类似芯片。这两个寄存器串联形成一个16位的移位寄存器链。手柄上有12个按键方向键4个A/B/X/Y/L/R/Start/Select每个按键的状态按下或释放对应一个比特位。此外还有4个固定的ID比特位通常为高电平1用于主机识别设备类型。通信过程由主机在这里是我们的KB2040发起遵循严格的时序Latch锁存脉冲主机将Latch线拉高至少12微秒µs。这个信号告诉手柄“准备好我要开始读取了”。手柄会在Latch上升沿的瞬间将当前所有12个按键的状态加上4个ID位并行锁存到移位寄存器中。Clock时钟脉冲与数据读取接着主机将Latch线拉低。然后主机产生16个Clock脉冲。每个Clock脉冲由低到高上升沿时手柄内部的移位寄存器会将锁存的数据整体向右移动一位并将最高位MSB的数据通过Data线输出给主机。主机在Clock为高电平期间读取Data线的状态。数据顺序第一个Clock脉冲后读出的是第一个按钮通常是B键的状态第二个是Y键以此类推。一个关键细节在SNES协议中按键按下时Data线输出低电平0释放时输出高电平1。我们的代码中需要用逻辑“非”not来处理这个关系。这个过程听起来复杂但用CircuitPython的digitalio库来模拟无非就是精确控制三个GPIO引脚Latch输出、Clock输出、Data输入的高低电平和时间间隔。我们后面编写的read_snes_controller()函数就是对这个过程的精确复现。4. 硬件改造焊接与组装实战4.1 焊接USB线到KB2040首先我们需要为KB2040提供电源和数据通道。剪掉USB-A数据线中不用的那一端通常是Micro-USB或USB-C的另一头剥开约2厘米的外皮露出里面的四根芯线红VCC/5V、黑GND、白D-、绿D。有些线缆还有一根裸露的屏蔽线可以将其拧在一起焊接到GND或者直接剪掉并用热缩管绝缘。根据KB2040的引脚图将四根线分别焊接红色VCC-VBUS引脚。这是从USB口取电的5V输入。黑色GND-GND引脚。白色D--D-引脚。绿色D-D引脚。焊接完成后用万用表检查是否有短路特别是VCC和GND之间。确认无误后可以用热熔胶或电工胶带对焊点进行绝缘和固定防止拉扯。4.2 焊接信号线到手柄PCB这是改造中最需要耐心和细心的环节。我们需要五根约10厘米长的30 AWG细线分别焊接到手柄PCB背面五针接口的五个焊盘上。识别引脚将手柄PCB的焊接面通常是背面朝上五针接口通常标有数字1-5或通过丝印可以判断。最可靠的确认方法是使用万用表将万用表调到通断档一个表笔接地比如连接器金属外壳或某个大面积接地焊盘另一个表笔依次触碰五个引脚。当你按下不同的按键时会发出蜂鸣声的那个引脚就是对应的数据引脚。通过测试B、Y、Select、Start四个键通常就能确定1-4号引脚GND, Data, Latch, Clock剩下的那个就是VCC5V。典型的引脚排列如下表所示但务必以你的实测为准引脚编号从特定边开始数功能连接到KB20401Ground (GND)GND2Data (Serial Data Out)GPIO D7 (作为输入)3Latch (Latch/Strobe)GPIO D6 (作为输出)4Clock (Serial Clock)GPIO D5 (作为输出)5Power (5V)3.3V焊接给每个引脚和导线头上锡。由于焊盘可能较小且老旧建议使用尖头烙铁温度不要过高快速点焊避免长时间加热导致焊盘脱落。焊好后轻轻拉扯导线确认焊接牢固。理线与固定将五根线理顺可以用一点点热熔胶或可撕性助焊胶固定在PCB非走线区域避免它们在后续操作中晃动。4.3 连接KB2040与固定将手柄PCB小心地放回手柄下壳前半部分中。现在将五根信号线按照上表的对应关系焊接至KB2040手柄 Pin1 (GND)-KB2040 任意 GND引脚。手柄 Pin2 (Data)-KB2040 D7。手柄 Pin3 (Latch)-KB2040 D6。手柄 Pin4 (Clock)-KB2040 D5。手柄 Pin5 (Power)-KB2040 3.3V输出引脚。再次强调这里是3.3V不是5V接下来是固定。在手柄PCB中央或空旷处点上一小坨热熔胶然后将KB2040板子按压上去。注意让USB接口朝向手柄尾部出口的位置并确保板子上的元器件不会与外壳或按键发生干涉。热熔胶的优点是可逆如果需要调整用热风枪或电烙铁稍微加热即可取下。重要注意事项通电前最终检查在连接USB线到电脑之前请务必进行以下检查这是避免烧毁芯片的关键步骤短路检查用万用表蜂鸣档检查KB2040的3.3V引脚与GND之间是否短路。检查VBUS5V与GND之间是否短路。连线检查对照引脚表逐一检查五根信号线是否连接正确有无虚焊或错焊。绝缘检查确保所有裸露的焊点特别是USB线的5V和GND没有相互触碰或接触到KB2040或手柄PCB上的其他金属部分。5. 软件配置CircuitPython环境搭建与编程5.1 刷入CircuitPython固件KB2040出厂时通常是UF2引导程序。我们需要先将其刷成CircuitPython运行环境。进入引导模式断开USB连接。按住KB2040板上的BOOTSEL按钮通常标有“BOOT”不要松开然后将USB线插入电脑。继续按住按钮约1-2秒直到电脑上出现一个名为RPI-RP2的可移动磁盘。拖放固件从CircuitPython官网下载适用于KB2040的最新版.uf2固件文件。将其直接拖拽或复制到RPI-RP2磁盘中。完成磁盘会自动弹出稍等片刻电脑上会出现一个新的名为CIRCUITPY的磁盘。这表明CircuitPython已成功刷入并运行。5.2 理解项目代码结构我们将需要两个核心文件boot.py和code.py。它们的作用截然不同boot.py在CircuitPython启动时最先运行用于进行一些初始配置。在本项目中它的核心任务是定义USB设备描述符告诉电脑“我是一个游戏手柄”。这个文件只需要在第一次设置时写入之后除非更改USB设备类型否则无需改动。code.py这是主程序文件在boot.py之后运行并且会循环执行。它包含了读取SNES手柄、映射按钮、发送USB报告的所有逻辑。这是我们主要修改和调试的对象。5.3 编写boot.py定义USB游戏手柄boot.py文件的核心是创建一个符合USB HID规范的“游戏手柄设备描述符”。这个描述符是一串字节数组精确地定义了我们的设备有多少个按钮、几个摇杆、几个方向键Hat Switch以及数据报告的格式。# boot.py import usb_hid GAMEPAD_REPORT_DESCRIPTOR bytes(( 0x05, 0x01, # USAGE_PAGE (Generic Desktop) 0x09, 0x05, # USAGE (Gamepad) ... # 此处是完整的描述符字节数组较长详见原始资料或项目包 )) gamepad usb_hid.Device( report_descriptorGAMEPAD_REPORT_DESCRIPTOR, usage_page0x01, # Generic Desktop Control usage0x05, # Gamepad report_ids(0,), # 报告ID为0 in_report_lengths(19,), # 输入报告长度为19字节 out_report_lengths(0,), # 无输出报告 ) usb_hid.enable((gamepad,))关键点解析report_descriptor这是描述符本身我们直接使用了一个广泛兼容的DirectInput模式描述符模板。它定义了14个按钮、1个8方向Hat Switch用于十字键和4个8位模拟摇杆轴X, Y, Z, Rz。虽然我们只用十字键和部分按钮但完整的描述符能获得最好的系统兼容性。in_report_lengths(19,)这意味着我们的手柄每次向电脑发送的数据包是19个字节。代码中需要构建一个19字节的数组来填充数据。usb_hid.enable((gamepad,))这行代码启用了我们自定义的HID设备。一旦启用电脑在插入时就会识别到一个新的游戏控制器。对于绝大多数用户你不需要理解描述符里每一个字节的含义直接从项目包中复制完整的boot.py文件到CIRCUITPY根目录即可。它的作用就是“挂牌营业”告诉操作系统“嗨我来了我是个标准游戏手柄”。5.4 编写code.py主逻辑与映射code.py文件包含了所有业务逻辑。我们来逐部分拆解其工作原理和可定制点。1. 引脚定义与初始化import time import board import digitalio import usb_hid LATCH_PIN board.D6 CLOCK_PIN board.D5 DATA_PIN board.D7 latch digitalio.DigitalInOut(LATCH_PIN) latch.direction digitalio.Direction.OUTPUT clock digitalio.DigitalInOut(CLOCK_PIN) clock.direction digitalio.Direction.OUTPUT data digitalio.DigitalInOut(DATA_PIN) data.direction digitalio.Direction.INPUT data.pull digitalio.Pull.UP # 启用内部上拉电阻这里定义了与硬件焊接对应的三个GPIO引脚并将它们初始化为输出Latch, Clock和输入Data。为Data引脚启用内部上拉电阻确保在无信号时保持高电平提高稳定性。2. 按钮映射表buttonmap这是整个代码中最灵活、最值得自定义的部分。它定义了SNES手柄的每个按钮对应到USB HID报告中的哪个字节byte_index和哪个比特位button_value。buttonmap { B: (0, 0, 0x2), # SNES第0位 - 报告第0字节第1位二进制0000 0010 Y: (1, 0, 0x1), # SNES第1位 - 报告第0字节第0位二进制0000 0001 Select: (2, 1, 0x01), # SNES第2位 - 报告第1字节第0位 Start: (3, 1, 0x02), # SNES第3位 - 报告第1字节第1位 Up: (4, 0, 0), # 方向键单独处理此处占位 Down: (5, 0, 0), # 同上 Left: (6, 0, 0), # 同上 Right: (7, 0, 0), # 同上 A: (8, 0, 0x4), # SNES第8位 - 报告第0字节第2位二进制0000 0100 X: (9, 0, 0x8), # SNES第9位 - 报告第0字节第3位二进制0000 1000 L: (10, 0, 0x10), # SNES第10位 - 报告第0字节第4位二进制0001 0000 R: (11, 0, 0x20) # SNES第11位 - 报告第0字节第5位二进制0010 0000 }映射规则解读元组(SNES_bit_index, HID_byte_index, HID_bitmask)。SNES_bit_index: 从read_snes_controller()函数返回的列表中该按钮对应的位置索引0-11。HID_byte_index: 在19字节的HID报告中该按钮状态位于哪个字节。通常前两个字节索引0和1用于按钮。HID_bitmask: 一个十六进制数表示在该字节中代表这个按钮的是哪一位。例如0x2是二进制0000 0010代表第1位从0开始数。如果你想交换A和B键的功能只需交换它们对应的HID_bitmask值即可无需改动硬件。3. 十字键D-pad到Hat Switch的转换USB HID游戏手柄用“Hat Switch”帽式开关来表示方向它是一个4比特的值对应8个方向加一个释放状态。我们需要将四个独立的方向按钮状态组合成一个Hat值。dpad_state {Up: 0, Down: 0, Left: 0, Right: 0} hat_map { (0,0,0,0): 0x08, # 释放 (1,0,0,0): 0x00, # 上 (1,1,0,0): 0x01, # 右上 (0,1,0,0): 0x02, # 右 (0,1,0,1): 0x03, # 右下 (0,0,0,1): 0x04, # 下 (0,0,1,1): 0x05, # 左下 (0,0,1,0): 0x06, # 左 (1,0,1,0): 0x07, # 左上 }dpad_state字典记录当前四个方向的状态1按下0释放。hat_map字典将一个四元组(Up, Right, Left, Down)映射到标准的Hat值。注意这里的顺序是(上右左下)这是为了匹配常见映射。4. 核心函数读取SNES手柄def read_snes_controller(): data_bits [] latch.value True time.sleep(0.000012) # 12µs 锁存脉冲宽度 latch.value False for _ in range(16): time.sleep(0.000006) # 等待6µs data_bits.append(data.value) # 在时钟上升沿前读取数据 clock.value True time.sleep(0.000006) # 6µs 时钟高电平 clock.value False time.sleep(0.000006) # 6µs 时钟低电平 return data_bits这个函数严格模拟了SNES主机的读取时序。12µs和6µs的延时是经过测试的可靠值保证了与各种SNES手柄芯片的兼容性。函数返回一个包含16个布尔值的列表前12个对应按钮True表示释放False表示按下。5. 主循环状态处理与报告发送主循环不断读取手柄状态更新HID报告并在报告发生变化时发送给电脑。while True: button_state read_snes_controller() # 读取16位数据 # ... 处理每个按钮更新report数组 ... # SOCD清洁防止同时按下左右或上下 if (dpad_state[Up] and dpad_state[Down]): dpad_state[Down] 0 # “上”优先 if (dpad_state[Left] and dpad_state[Right]): dpad_state[Left] 0 dpad_state[Right] 0 # 同时按左右视为“空” # 计算Hat值 dpad_tuple (dpad_state[Up], dpad_state[Right], dpad_state[Left], dpad_state[Down]) report[2] hat_map.get(dpad_tuple, 0x08) # 报告第3字节是Hat # 仅当状态改变时才发送报告节省资源 if prev_report ! report: gamepad_device.send_report(report) prev_report[:] report time.sleep(0.01) # 10ms的轮询间隔平衡响应速度和CPU占用SOCD清洁是格斗游戏社区的一个术语意为“同时对立方向消除”。这里实现了一个简单规则同时按上/下时优先响应“上”同时按左/右时两个都取消回中。这可以防止游戏中的角色行为错乱。你可以根据需要修改这个逻辑。延时time.sleep(0.01)设置了主循环的频率约100Hz。这对于游戏手柄来说足够了。降低这个值可以提高响应速度但会增加CPU负担增加则会降低响应速度。通常0.01-0.02是一个好的平衡点。5.5 部署与测试文件部署将编写好的boot.py和code.py文件以及任何必要的库文件通常项目包中已包含全部复制到CIRCUITPY磁盘的根目录。软复位按一下KB2040上的RESET按钮或者重新插拔USB线让新代码运行。测试打开浏览器访问Gamepad Tester网站。按下手柄上的任意键网站应该能检测到一个新的游戏控制器并显示按下的按钮。十字键会显示为“Hat”的八个方向。6. 进阶玩法与故障排查6.1 探索GP2040-CE固件Bonus部分如果你对CircuitPython的灵活性感到满意但又想追求极致的低延迟和更多高级功能如摇杆死区调整、宏编程、多平台模式切换那么GP2040-CE是一个绝佳的选择。它是一个用C编写的、专为RP2040优化的开源游戏手柄固件性能更强功能更专业。如何切换和刷入CircuitPython类似按住BOOTSEL键进入UF2模式。将下载好的GP2040-CE的.uf2文件拖入RPI-RP2磁盘。重启后你的手柄就变成了一个功能强大的GP2040-CE控制器。默认是XInput模式识别为Xbox 360手柄兼容性极佳。GP2040-CE的优势超低延迟专为格斗游戏等对输入延迟要求高的场景优化。Web配置界面通过网页浏览器连接后访问192.168.7.1即可进行所有设置无需修改代码。多模式支持通过组合键可在启动时切换XInput、DInput、Switch、PS4等多种模式。SNES插件GP2040-CE社区已经开发了SNES输入插件你甚至无需焊接可以直接使用插件配置引脚但本项目的焊接方案同样兼容。6.2 常见问题与排查技巧即使按照步骤操作也可能会遇到一些问题。以下是一些常见故障及解决方法问题现象可能原因排查步骤电脑完全无法识别USB设备1. USB线仅供电不支持数据。2.boot.py文件错误或缺失。3. KB2040未正确进入CircuitPython模式。1. 更换已知良好的数据线。2. 检查CIRCUITPY磁盘根目录是否有boot.py并确认其内容正确。3. 重新刷写CircuitPython UF2文件。电脑识别为“未知设备”或“HID设备”但游戏不识别USB HID描述符不兼容。确保使用的是项目提供的完整boot.py描述符。尝试在设备管理器中卸载设备后重新插拔。Gamepad Tester网站检测到设备但按键无反应1. 信号线焊接错误或虚焊。2.code.py中引脚定义与实际焊接不符。3. 手柄PCB本身故障。1. 用万用表通断档检查五根信号线从手柄PCB到KB2040是否连通。2. 核对LATCH_PIN,CLOCK_PIN,DATA_PIN的定义。3. 用万用表测试手柄原始功能见3.2节。部分按键反应迟钝或连发主循环延时time.sleep()设置过长或代码效率低。尝试减小主循环中的time.sleep(0.01)值例如改为0.005。检查代码中是否有耗时的操作。按键映射错误如按A出Bbuttonmap字典中的映射关系错误。对照read_snes_controller()函数返回的列表顺序调整buttonmap中每个按钮的SNES_bit_index。十字键对角线方向不触发hat_map字典中的四元组顺序定义错误或SOCD清洁逻辑过于激进。检查hat_map中元组的顺序是否为(Up, Right, Left, Down)。检查SOCD清洁代码是否错误地清除了有效输入。热熔胶固定后按键卡住KB2040或线材过高顶到了外壳或按键。断开USB重新打开手柄调整KB2040的位置使用更少或更薄的热熔胶确保所有按键行程不受阻。调试利器串口输出在code.py中添加print()语句是调试的黄金法则。例如在read_snes_controller()函数后打印button_state列表可以直观看到每个按钮的原始状态。在循环中打印report数组的内容可以确认HID报告是否正确生成。只需使用Mu编辑器或任何串口终端软件如PuTTY、screen、minicom连接到KB2040出现的串行端口如COMx, /dev/ttyACM0波特率通常为115200即可看到输出信息。改造完成后拧回最后五颗螺丝你的经典SNES手柄就重生为了一款充满个性且手感绝佳的现代USB手柄。它不仅是一件功能完备的外设更是一个融合了硬件 hacking、嵌入式编程和复古情怀的独特作品。无论是用来重温《超级马里奥世界》的精准操作还是在现代独立游戏中寻找复古的乐趣这个亲手打造的工具都会让游戏体验别有一番风味。