亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino UNO 面包板电脑编程器 – 构建并编写你的 8 位系统

组件与供应

Arduino UNO 面包板电脑编程器 – 构建并编写你的 8 位系统 Arduino UNO × 1

关于项目

这是一个什么项目?

这是 Ben Eater 的 8 位面包板电脑项目的扩展。我非常享受跟随 Ben 的视频构建面包板电脑,并制作了自己的版本。如果你没有跟随 Ben 的教程,强烈建议先观看他的视频,否则这个项目很难理解。

构建完成后很快发现,如果每次开机都要通过拨码开关手动输入程序,这台电脑根本用不起来。即使只是反复输入 16 字节也让人厌烦。而且我计划将内存扩展到 256 字节,只有能加载和保存程序才有意义。

能用它做什么?

这是一个演示这些功能的视频(请原谅视频质量,我不是专业内容创作者):

工作原理

制作这个项目时有几个目标:

最初考虑使用 EEPROM 存储程序,再用逻辑电路将程序从 EEPROM 传输到面包板电脑的 RAM。但传输逻辑比我能应付的更复杂(我更擅长软件,虽然也喜欢贴近硬件的工作)。我恰好是 Arduino 爱好者,于是想用 Arduino 替代传输逻辑。花了一段时间说服自己用 Arduino 并非“作弊”(毕竟 Arduino UNO 比面包板电脑强得多),但我对结果满意,所以释怀了。

Arduino 需要做什么?读取和写入内存数据。最简单、侵入性最小的方法是利用内存模块现有的总线和控制信号接口。Arduino 数字 I/O 引脚是双向的,将 8 个引脚直接连到总线上,就能读写总线。要让 RAM 模块读写总线,只需相应设置 MI/RI/RO 信号。这些信号通常由控制逻辑的 EEPROM 驱动,如果 Arduino 也控制它们会导致冲突和短路风险。但 Ben 使用的 AT28C16 EEPROM 有片选(CE)输入,拉高可将所有数据输出置于高阻态,从而允许 Arduino 操控信号。

读取 RAM 的步骤:

  1. 将 EEPROM 的 CE 信号拉高(禁用控制逻辑)
  2. 将要读取的首个地址输出到总线
  3. 拉高 MI 信号并等待时钟上升沿
  4. 拉低 MI、拉高 RO 并等待时钟上升沿
  5. 从总线读取数据字节
  6. 对所有 16 个地址重复步骤 2-5
  7. 将 EEPROM 的 CE 信号拉低(重新启用控制逻辑)

写入 RAM 类似,只需向总线写数据并拉高 RI 代替 RO。当然还有一些技术细节要解决,但上述基本机制是本项目的核心。

面包板电脑需要做哪些改动?

需要两项改动:

下拉电阻

下拉电阻是必须的,因为一旦 EEPROM 被禁用,连接到控制信号(如 AO/AI/EO 等)的逻辑门输入端的上拉电阻会将这些信号拉高,导致多个寄存器同时向总线写入数据,产生冲突。

74LS 系列芯片输入端的上拉电阻约 10kΩ。下拉电阻需足够小以将电压拉低。大多数信号线我用了 3.3kΩ 电阻。有两个例外:

我发现最方便是在放置蓝色 LED 的面包板上加下拉电阻,即在 LED 阳极(连接 EEPROM 输出)与地之间连接。HIT/MI/RI 信号的电阻因空间不足,我在面包板其他位置添加。

Arduino UNO 面包板电脑编程器 – 构建并编写你的 8 位系统

环形计数器复位

另一项改动是复位环形计数器。技术上这不是保存/加载程序所必需,但能实现从 Arduino 向控制逻辑平滑移交控制权。关键是只要 CE 为高(控制逻辑禁用),就让环形计数器保持在 0。当 Arduino 将 CE 拉低(启用控制逻辑)时,环形计数器处于 0 状态,面包板电脑开始执行下一条指令。

我的构建中不需要额外操作,因为我用一个 EEPROM 输出来复位环形计数器。这不仅在指令结束时立即复位计数器以提高性能,而且当控制逻辑 EEPROM 被禁用时,该输出上的下拉电阻会将信号拉低,自动复位环形计数器。

如果你用的是 Ben 的固定 5 步环形计数器,我认为在他的复位电路基础上增加以下电路可在 CE 为高时复位计数器(点击左右箭头切换原电路和扩展版):

Arduino UNO 面包板电脑编程器 – 构建并编写你的 8 位系统

需要 3 个额外的 NAND 门,即多一片 74LS00 芯片。注意我未测试此方案,但理论上可行。

此改动非绝对必要,初期可省略。加载/保存、监视器/汇编器/反汇编器仍正常工作。但任何需要将控制权从 Arduino 移交给控制逻辑的操作将失效,最典型的是开机自动运行保存的程序、单步调试和运行到断点。

如何设置 Arduino?

将 Git 仓库中的草图上传到 Arduino,并按以下方式连接面包板电脑:

此外需按原理图将 Arduino 模拟引脚 1 和 2 接到拨码开关和按钮(详见附件 Fritzing 文件)。

Arduino UNO 面包板电脑编程器 – 构建并编写你的 8 位系统
Arduino UNO 面包板电脑编程器 – 构建并编写你的 8 位系统

最小功能版本可简化为:

使用加载/保存按钮只需按原理图连接按钮、拨码开关及相关电阻到模拟引脚 1、2。

要使用自动启动功能(确保已加必要电路),将拨码开关设为程序保存的文件号,然后给面包板电脑上电(或按复位键)。两种特殊情况:所有拨码开关关闭则正常启动,不自动运行;所有开关打开则 Arduino 启动时直接进入监视器模式。

如何加载和保存程序?

最小配置下可通过串口控制 Arduino。需终端程序如 Putty 或 TeraTerm,Arduino IDE 自带串口监视器也可但输入输出区分离操作稍笨拙。

  1. 给面包板电脑上电
  2. USB 线连接 Arduino 到电脑
  3. 启动终端程序,设置 9600 波特率、8 数据位、无奇偶校验、1 停止位
  4. 终端窗口按 ESC 进入监视器模式
  5. 应看到“.”命令提示符
  6. 输入“h”回车查看支持命令列表

最小配置下可用“m”、“M”、“C”、“l”、“s”命令,查看/修改内存、加载/保存程序。

通过按钮保存/加载程序:

  1. 关闭面包板电脑时钟
  2. 拨码开关选文件号
  3. 按“保存”或“加载”按钮,连接 CE 的 LED 亮起,表示 Arduino 接管控制
  4. 开启时钟,观察内存地址寄存器 LED 循环地址
  5. 等待总线 LED 停止闪烁,地址寄存器显示 1111
  6. 关闭时钟,CE LED 熄灭,控制权归还控制逻辑

如何使用汇编器和反汇编器?

使用汇编/反汇编及调试功能前,需修改 Arduino 程序中的 opcodes_4bit 结构以匹配你的具体设置。找到源码中定义该结构的部分:

struct opcodes_struct opcodes_4bit [] = {
  {"NOP ", B00000000, 0, false},
  {"LDA ", B00010000, 2, true},
  ...
  {".OR ", B11111110, 0, true}, // 设置起始地址
  {".BY ", B11111111, 0, true}, // 定义一个数据字节
  {NULL, 0, 0, false}
};

每行定义一个操作码:

需根据你的面包板电脑实现的指令集调整此列表。最后两行是汇编器用的特殊操作码,保持不变。

修改后上传到 Arduino。连接终端进入监视器模式(终端按 ESC 或全拨码开关打开)。现在可反汇编程序。监视器中输入“d”从地址 0 开始反汇编。

汇编器虽简陋但实用。输入“a”从地址 0 开始汇编。约定:

斐波那契代码示例:

rst LDA #0 ; x = 0
STA x
LDA #1 ; y = 1
STA y
lp ADD x ; z = y + x
STA z
JC rst ; 溢出则重启
OUT ; 打印 z
LDA y ; x = y
STA x
LDA z ; y = z
STA y
JMP lp ; 循环
x .BY 0
y .BY 0
z .BY 0

局限性

为节省 Arduino RAM,汇编器采用单遍汇编(否则需缓冲所有源码)。汇编器在输入时直接将操作码写入面包板电脑内存,因此汇编速度受面包板电脑时钟速度限制。若在终端粘贴文本,Arduino 可能跟不上 9600 波特率的输入(因花费大量时间等待面包板电脑时钟),导致字符丢失。解决办法:降低波特率、用 TeraTerm 设置字符发送延迟、或提高面包板电脑时钟速度。我的时钟可达 160kHz,此时 9600 波特率下粘贴代码无问题。

默认配置下 Arduino 草图支持面包板电脑时钟频率约 1-2kHz(可能略高)。Ben 的默认时钟不超过 500Hz。若时钟更快,查找代码中的 #ifdef FAST_IO 开关。开启 FAST_IO 可支持高达 250kHz 时钟,我测试过 160kHz 正常。更高速度可能需汇编优化关键循环,但 160kHz 对功能有限的面包板电脑已嫌太快。开启 FAST_IO 前请仔细阅读代码注释。

Arduino 有 1k EEPROM,可存 1024/16 = 64 个程序。实际 63 个(16 字节留作配置数据)。虽不多但足够。只有 0-15 号程序可通过拨码开关选择(1-14 用于自动启动),但“s”和“l”命令支持 0-62 全范围。

看起来有点乱,能整理一下吗?

能!最终版我直接用裸片 Atmega328P(配 16MHz 晶振和电容)替代 Arduino UNO。UNO 上的稳压器这里不需要,因为 Arduino 直接使用我们电源的 5V。唯一损失是需单独用 USB 转串口模块(FTDI 等)与 Atmega 通信。整体外观更协调:

Arduino UNO 面包板电脑编程器 – 构建并编写你的 8 位系统
Arduino UNO 面包板电脑编程器 – 构建并编写你的 8 位系统

另一优化是移除 Arduino/Atmega 的引导程序,消除启动时 2 秒延迟。如有兴趣我会发布操作指南,请在评论区留言!

代码

面包板电脑编程器

Arduino 草图:https://github.com/dhansel/programmer

原理图

drive_pD8k28E85v.fzz

制造工艺

  1. 计算机鼠标的进化史:设计、制造与未来趋势
  2. Satellite CCRMA 套件:构建传感器驱动的音频效果器
  3. DIY 蓝牙控制 Arduino 间谍小车
  4. FlickMote:基于手势的智能家居红外遥控器
  5. DIY Arduino TV-B-Gone:万能关机遥控器
  6. 自制大尺寸LED主时钟带闹钟功能 — 12米外清晰可见
  7. Find Me:基于 Arduino 与蓝牙的智能寻物器制作指南
  8. Arduino 项目优化供电方案:从按键开关到电池监测与数据记录
  9. Arduino 井字棋游戏:MAX7219 点阵屏 + 纸板外壳 DIY
  10. 从零构建智能 Arduino 四足机器人:完整指南
  11. Arduino + ThingSpeak 实时气象监测站
  12. DIY Arduino 手柄方向盘 - 游戏竞速模拟器自制指南