“盛思锐传感器”第九届立创电子设计开源大赛火热报名中,现在点击报名立创电赛赢2万现金大奖,报名后全阶段可触发福利!
大赛网址:DIY.SZLCSC.COM
为了给大家些创作灵感,今天带来第八届立创电赛一等奖项目《AtomBoy游戏机》案例分享!本文作者:瑞萨MCU杯第八届立创电子设计开源大赛选手@传说哥,禁止商用,未经许可禁止转载。
1、项目功能介绍
这是一款信用卡大小,基于瑞萨MCU的小型游戏机,OLED屏128*64分辨率,内置七款小游戏,可充电350毫安时锂电池,工作电流约15mA,待机电流小于100μA。板载daplink。
内置游戏
- [x] 恐龙游戏
- [x] 像素鸟
- [x] 贪吃蛇
- [x] 五子棋
- [x] 2048
- [x] 太空侵略者
- [x] IKUN
功能
- [x] 超长待机
- [x] 待机时保存游戏进度
[x] 板载DAP-LINK
2、硬件部分
电路
结构
电路板四角粘贴磁铁,面板同样粘贴磁铁,通过磁吸,夹住3D打印夹层。
磁吸的设计使外壳上没有螺丝固定,并且易拆卸。
目前3d外壳无法导出,等待立创eda修复bug。该bug与侧面开孔有关,删除侧面开孔后可导出,但usb接口的开孔也随之消失。临时的解决方案是3d打印到手后手动打磨。
已用SolidWorks重画,见附件。

3、软件部分
代码获取
代码托管在github上:https://github.com/liux-pro/AtomBoy
另外,daplink固件使用@XIVN1987大佬的固件,他的开源地址是https://github.com/XIVN1987/DAPLink
为板载的DAPLINK烧录固件
(可跳过此步骤,直接使用附件里的固件)下载daplink代码并使用MounRiver Studio编译daplink固件。
下载并安装WCH单片机烧录工具
如图所示选择ch32烧录,图中第六步选择附件的CH32V203_DAPLink_aa14c15.hex
短接pcb上的DAP BOOT触点。

通过usb数据线插入电脑,软件会自动烧录daplink固件。
至此DAPLINK已就绪。

编译AtomBoy
使用了瑞萨RASC生成基于cmake组织的工程文件,需使用ARM GCC编译。如果要在自己的电脑上编译,首先安装好cmake,ninja,然后下载ARM GCC,执行如下编译命令。
假设gcc工具链解压到了D盘根目录。
cmake -B build -G Ninja -DCMAKE_FIND_ROOT_PATH=D:/gcc-arm-none-eabi-10.3-2021.10-win32/gcc-arm-none-eabi-10.3-2021.10/bin cmake --build build
烧录AtomBoy
由于板载了DAP-LINK,不需要使用外置烧录设备,预先装好python3,通过pip安装pyocd。
pip install pyocd
之后usb链接电脑后,通过板载daplink直接烧录程序。
cmake --build build --target flash
模拟器
为方便调试,避免每次修改都要重新烧录,额外写了一个模拟器使大部分代码可以在电脑上运行。

- 装好 msys2 环境
- (可选)使用 msys2-mingw64 执行sed -i "s#mirror.msys2.org/#mirrors.ustc.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*切换国内源
- 使用 msys2-mingw64 执行pacman -S mingw-w64-x86_64-SDL2,安装SDL2
- 使用 msys2-mingw64 执行pacman -S mingw-w64-x86_64-toolchain cmake make ninja git,安装编译器等
- cd emulator && cmake -G Ninja -B build
- cd build && ninja
- ./AtomBoyEmulator.exe
使用CLion
使用CLion能加快开发效率,避免手动敲命令。
说不明白,看视频吧。视频中演示了如何编译,烧录,如何使用模拟器。https://www.bilibili.com/video/BV1Nx4y1X7iN/
代码结构
目录
├─.github
│ └─workflows # Github Action 自动构建hex文件
├─cmake # cmake脚本,RASC自动生成
├─emulator # 基于SDL的模拟器
├─ra # 系统代码,RASC自动生成
├─ra_cfg # 系统代码,RASC自动生成
├─ra_gen # 系统代码,RASC自动生成
├─script # 链接脚本,RASC自动生成
└─src # 源码
├─app # 应用程序
├─Arduino # 模拟Arduino形式
├─buzzer # 蜂鸣器
├─fps # 控制屏幕刷新,提供系统system tick
├─u8g2 # u8g2源码
└─u8g2_port # u8g2移植
└─main.cpp # 主函数入口
└─button.cpp # 按键扫描
└─sleep.cpp # 低功耗模式
RASC生成
代码基本结构通过RASC生成。可通过RASC导入本项目进行对瑞萨mcu的引脚,时钟,外设等配置。编译过程不需要rasc的参与。
RASC当前版本(v4.5)生成的cmake文件有各种问题,在本项目中已改成,自己生成新项目需注意。
https://github.com/renesas/fsp/issues/256
https://github.com/renesas/fsp/issues/280
整体架构
- 由定时器生成1ms的时钟源,每隔约16ms更新标志位,主循环轮询获取标志位后刷新一帧,算力足够的情况下能稳定帧率。
- 驱动OLED屏使用U8G2,移植采用硬件SPI。
- 每个按键直连一个GPIO,GPIO开启内部上拉,随屏幕刷新更新按钮状态,发现GPIO向低电平跳变代表按钮按下。无消抖。游戏中要每帧调用扫描函数,更新按键状态。
- 每个游戏(含主菜单)都视为一个app。主循环通过变量nextApplication判断进入哪个app,默认进入主菜单。
- 每个app实现run抽象方法,在内部通过u8g2操作屏幕实现游戏逻辑,run方法返回后重新进入主循环。
- 在菜单app中,选定某项后,修改nextApplication后return,下一轮循环根据修改后nextApplication进入选定的游戏。
- power键试实现了短按、长按,超过500ms视为长按。长按重启系统。短按进入低功耗模式,通过power按键的再次按下唤醒系统。
- 通过goSleep函数进入低功耗模式,关闭无关的LDO,被唤醒后恢复oled,蜂鸣器供电,并重新初始化oled,以便继续执行谁面前的逻辑。
- 5分钟无任何操作自动进入低功耗模式。
- 整体对时钟稳定性要求不高,采用内置振荡器。
- 每个APP内尽量不使用全局变量。未开启堆内存,分配 14000kb 栈内存。
注:若您的项目涉及软件开发,请在附件上传对应的工程源码。这里可以详细说明您的软件流程图、功能模块框图、相关算法的解释或科普、源码结构、编译环境的搭建和配置、源码编译方法、程序烧录方法等。推荐图文并茂的形式向别人介绍您的想法。
6、BOM清单
7、可优化部分
重新排布元件使电池附近1mm无元件,减少装配难度。
usb口置于左或右侧,而不是上下的长边处。现有的设计typec口处太薄了,强度不够。另外可以埋入小铁棍加强筋。
面板磁铁粘贴处除胶,改用ab胶粘贴,自带的3m胶不足以粘强磁。
摇杆太小,方向不好控制。
无法显示电量,充电状态。
