大二开始几个小伙伴一起跟杨俊做了个单片机的小东西
最后感觉也就是水过了
这几天准备重新把资料理出来看看,没准面试可以用一下。
Orz
基本原理:
从核心部分开始:
UZEBOX主机
具体电路图如上所示,用到的芯片只有两个,单片机和后面的AD转换芯片,剩下的都是一些简单的电路。
硬件部分
CPU
CPU采用了ATmega644,8位的AVR单片机,主要功能是完成所有任务。
- 生成视频同步信号
- 画面的呈现。这包括滚动和确定精度的透明度来抑制背景
- 混合并且输出音乐和声音效果
- 读操纵杆按钮状态
- 读取和处理通过UART的MIDI数据流
- 处理对SD卡的读写操作
- 最后也是最重要的一步:运行游戏
这块芯片的标准主频是20MHz,但是使用时需要超频到28.6MHz。
因为AD725的工作频率是14.3MHz,为了防止视频信号采样发生混叠,MCU和AD725的信号需要同步发生。
视频信号
如上图所示,UZEBOX的视频部分主要靠单片机的C口进行输出,以3/3/2的比例向外输出R/G/B视频信号
红和绿都是用3位表示,蓝色信号2位,经过一个R-2R权电阻网络进行简单的DA转换,可以把三种颜色的数字信号转成0~0.7V的模拟信号,然后继续输入AD725,转换成NTSC格式的视频信号
AD725的主要输入信号是前面来的RGB,然后再加上单片机的同步信号和时钟信号辅助,就能完成视频信号的转换了
声音信号
声音输出只用到了PD7一个口,是单声道信号进行脉冲宽度调制(PWM)产生的。用电阻把输出信号幅值控制在1V的峰峰值即可
手柄
这里用的是一个简单的SNES(Super Nintendo Entertainment System)的手柄。就是一个触发器和一个移位寄存器,单片机读取移位寄存器里面存储的状态即可。
软件部分
内核
内核就是烧录进单片机里面的主要内容。单片机上没有操作系统,因此内核里面的所有部分事实上只能顺序执行,但是因为执行速度足够快,可以表现得像多任务同时工作一样进行。单片机需要同时完成多项任务:产生视频信号、读取手柄的控制信息、播放音乐等等。
主要工作内容是:
- 初始化端口,计时器和其他硬件外围设备重置
- 生成复合视频AD725所需的同步脉冲
- 解码音乐数据,产生声音效果
- 混合四种声音样本
- 在规律的间隔时间从混合缓冲器中输出声音样本
- 对控制器按钮和鼠标移动的读取
- 读取UART中的入栈数据并将其存储到缓冲区中
中断
内核使用定时器1,即16位的计数器来触发中断。
计时器开始为0,计数到1820,此时它会自动回转到0,并且生成一个中断。
1820的值是由主晶振频率(28.63636MHZ)除以NTSC扫描线率(15.73426KHZ)得到的。
内核中断负责暂停主程序,进行渲染视频和混合音乐。由于速度和时间要求,需要用汇编语言来写。
视频引擎
内核提供12种不同的工作模式,每种都有不同的特点,用于实现视频绘制
声音引擎
音乐处理涉及到音乐乐谱的读取和波封的处理,这里使用的是MIDI这种紧凑格式的音频,纯软件完成
游戏载入
从github上下到完整的包是这样的
1 | demos //各种运行工具以及游戏包 |
执行make之后,会在Rom目录下生成一些.hex和.uze的文件
.uze文件是原本生成了.hex文件之后加上首部打包而成
载入的过程可以有两种:
- 直接将游戏包生成好的.hex文件烧录进Atmega644即可
- 往单片机中烧录gameloader的.hex文件,之后通过读取SD卡中的.uze文件来载入游戏。gameloader占内存4K,剩下还有60K的内存可供游戏调用
改进部分
游戏机制作完成之后,我们对其进行了两方面的改进
无线传输
将视频信号通过一个简易的无线电路发射出去,可以通过一般的CRT电视来接收
该电路非常简化,制作该电路的时候也是使用双面覆铜板完成
所有暴露在外面的导线都是尽可能地贴近覆铜板,使高频信号尽可能地衰减掉
选择一个电视频道,并调节可调电感来使得两个设备相互适配
当发射机与电视机的距离、频率都调整到一个合适的位置时候,电视机上可以清晰地收到显示的游戏画面
无线控制
通过三轴加速度传感器来对感知空间三维姿态,并通过无线的方式将其传递到另一台主机上,主机进一步向外输出控制信号
这一部分可以代替原始设计中的手柄部分