基于 Arduino 的 Amiga 软盘读取器:低成本开源数据恢复方案
元器件与物料
| 1 kΩ 电阻 | ×1 |
| 面包板 | ×1 |
| 跳线 | ×1 |
| SparkFun 面包板电源模块 5V/3.3V | ×1 |
| Arduino UNO(或 Pro Mini) | ×1 |
应用与在线服务
- Arduino IDE
项目背景与动机
作者因童年拥有 Amiga 500+,积累大量 3.5 英寸双面双密度 (DD) 软盘。随着原机损坏,现代 PC 无法直接读取 Amiga 格式磁盘(MFM 编码、80 磁道、11 扇区/磁道、512 字节/扇区),商业方案(KryoFlux、Catweasel)昂贵且闭源。因此决定自研低成本开源方案:Arduino + Windows 应用程序,实现磁盘镜像(.ADF)提取,后续扩展写入与 FDI/IPF 格式支持。
核心技术挑战
- 数据率 500 kbps(300 RPM,MFM 编码),Arduino 16 MHz 主频下采样极其紧张。
- 软盘驱动器转速漂移、写入时钟偏差导致同步困难。
- 读取信号为窄脉冲而非电平,需硬件计数器捕捉。
演进历程(六次尝试)
尝试 1:双 74HC594 移位寄存器降频采样
用两级 8 位移位寄存器将 500 kHz 降为 62.5 kHz 并行读取,配合 2 Mbps FTDI 串口传输。虽 CPU 占用低,但数据无意义,发现需更深入分析驱动器波形。
尝试 2:中断采样(ISR)
用 500 kHz 定时器触发中断读取脉冲,但 ISR 开销过大(>32 周期),digitalRead 太慢,甚至直接操作端口仍不够快,放弃。
尝试 3:硬件计数器(Timer0 外部时钟)
利用 ATmega328 Timer0 计数外部脉冲,主循环以 500 kHz 定时器溢出为基准检查计数值。数据开始出现同步字(0x4489),但相位漂移导致校验错误频发。
尝试 4:软件相位锁环(PLL)
在主循环中检测到脉冲即重置定时器计数器至相位中点(1 µs),实现逐位同步。配合重复读取直到 11 扇区校验全通过,成功生成有效 ADF 镜像。示波器波形确认双信号锁定。
尝试 5:外部中断(INT0)加速重同步
将数据脉冲同时接入 Timer0 和 INT0,编写裸中断(ISR_NAKED)仅 5 条指令(0.3125 µs)完成重同步,进一步降低抖动。
尝试 6:施密特触发器整形
加入 SN74HCT14 六路施密特触发器并改为上升沿触发,效果无显著提升,保持尝试 5 方案。
尝试 7:MFM 编码规则纠错
利用 MFM 规则(不允许连续两个 1、不允许连续四个 0)对读回数据做事后校验,发现错误极少,部分磁盘仍无法读取,推测介质退化或驱动器机械问题。
解码与 ADF 生成
- 同步字搜索:
0xAAAAAAAA44894489或兼容早期 Bug 的0x2AAAAAAA44894489(需 &0x7FFFFFFFFFFFFFFF)。 - 扇区头/数据校验:循环重读直至 11 扇区全通过。
- ADF 格式:按磁道、磁头顺序顺序写入 512 字节扇区数据。
后续规划(V2 已发布)
- 全项目 GPLv3 开源:GitHub 仓库
- 支持写入功能(ADF/FDI)
- 引入通用 FDI 格式,解决非标准扇区/复制保护磁盘
- 探索无校验和下的数据完整性验证方法
代码与资源
- Arduino 固件与 Windows 上位机源码:GitHub
原理图与波形


制造工艺
- 动画演变与工艺:从幻灯片到计算机生成
- 软盘演进史:从磁存储到光存储
- DIY 蓝牙控制 Arduino 间谍小车
- FlickMote:基于手势的智能家居红外遥控器
- DIY Arduino TV-B-Gone:万能关机遥控器
- 自制大尺寸LED主时钟带闹钟功能 — 12米外清晰可见
- Find Me:基于 Arduino 与蓝牙的智能寻物器制作指南
- Arduino 项目优化供电方案:从按键开关到电池监测与数据记录
- Arduino 井字棋游戏:MAX7219 点阵屏 + 纸板外壳 DIY
- 从零构建智能 Arduino 四足机器人:完整指南
- DIY Arduino 手柄方向盘 - 游戏竞速模拟器自制指南
- 基于 Arduino 的 Amiga 软盘读取器:低成本开源数据恢复方案