开启辅助访问
 找回密码
 立即注册

模拟示波器通常是什么样的架构什么系统,如何编程(有人在日立V-422上编写了一款FPS游戏)?

hide0823 回答数5 浏览数144280
日立V-422模拟示波器上编写的FPS游戏: Quake running on an oscilloscope is the ultimate demake 当年第一款电子游戏网球也诞生于示波器。 新的数字示波器大多是嵌入式系统乃至就是独立的计算机,这个就很容易理解了。
夜色彩888 | 未知
题主的问题描述里面都已经写明了“模拟示波器”,先来复习一下模拟示波器的工作原理:

电子示波器的核心部分是电子示波管,它由电子枪、偏转系统和荧光屏组成。电子枪通过发射高速电子流,经过由两对金属板组成的偏转系统进行偏转后打在荧光屏上使荧光材料发光,从而显示特定的图像。通过向控制偏转板上加上特定的电压,就可以把电压变化的信号以图像的形式显示出来,这是电子示波器的基本工作原理。
假如在示波器的X轴偏转板上加上锯齿形的扫描电压,并于Y轴上加上待观察信号的电压,那么荧光屏上面显示的是两种信号的合位移,也就是待测信号的时域图像。通过往Y轴偏转板上加不同的待测信号,即可观察到不同待测信号的时域图像。
为了观察到稳定的待测信号的波形,示波器工作过程中要求Y轴上待测电压信号的周期为X轴上扫描信号的周期的整数倍。示波器内部具有同步触发电路,能够保证X轴信号与Y轴信号的周期同步,以便观察到稳定的波形。
(以上文字本人保留版权)

在原理上分析,其实模拟示波器就是个高级点、灵敏点、显像面积少点的CRT显示器罢了,根本就没有什么架构系统那个高级的东西。。。实现这种效果的关键在于如何利用好模拟示波器的显示功能。(顺便说一下,只有比较高级的数字示波器才会带独立嵌入式系统,入门级的数字示波器一般就是用一两片FPGA实现的)

对于新闻中的日立V-422模拟示波器,应该是年代久远了。google上也难以找出完整的技术参数,但是唯一可以明确的一点是这是一款通用模拟示波器,这种模拟示波器内部是基本不可能存在可以编程的器件的,那就根本不存在编程一说。

现在再来分析如何做出FPS的功能。给出的链接中并没有提供详细的相关实现,但是我google到了原作者的博文:Quake on an oscilloscope: A technical report,大家可以到博客中详细参考原作者的技术实现过程(部分内容需要科学浏览)。我就只做一个小小搬运工把他的博文的内容简要翻译一下。(下面的文字只是意译,我根据问题描述补充了部分内容)

从网上找到的仪器面板图是这样的:


来源网络,侵删

可以看见上面TIME/DIV旋钮上面有一个X-Y档,如果把示波器的旋钮调到这个档的话示波器就不会往X轴偏转板上面输出锯齿波的扫描信号了,X轴偏转板“直接”连上示波器的输入通道1。这种情况下示波器的两个输入通道的输入电压直接决定了示波器荧光屏亮点的水平和垂直位置。换句话说,根据视觉停留的原理,如果能够控制这个亮点移动以极快的速度移动,人眼就可以“看见”亮点移动的轨迹,这个亮点的轨迹是一个二维平面上的时域函数。众所周知,游戏画面中的3D模型是由许多顶点组成的。那么控制亮点在这些顶点之间移动,就可以画出模型顶点之间相应的线段了。


如图所示,轨迹是“连续”而不是离散的。

但是这里有一个问题:实际显示的图像中线段并不一定都是连续(或者说首尾相接)的,而亮点的轨迹必须是连续的。作者为了解决这个问题采用的方法是将绘制图像实际需要的线段的时间尽可能延长,然后在亮点移动到下一条需要绘制的线段的起点的过程中对当前绘制的frame进行快速缩放,这样就可以在很大程度上隐藏不希望看到的亮点移动轨迹了。

在解决了绘图的问题后,接着要解决的问题就是如何把信号从计算机输出到示波器上面。示波器接收和显示的都是电压信号,这就意味着需要一些DAC将控制信号转化为模拟量来控制示波器上亮点的位置及其移动轨迹。作者在这里使用的是声卡(声卡基本都支持左右两个声道的立体声输出,正好满足题中所要求的X-Y两路信号)。显示图像的过程中,显示设备的刷新率当然是越高越好,这样游戏玩起来才爽,所以作者一开始选择了ASIO作为音频后端协议,但是折腾了几天都发不出丁点声音(ASIO在win上的支持不好),后来换成了PortAudio才解决了问题。

然后就是声卡硬件上的问题了,作者手头上的所有声卡硬件上都是配备了低通滤波器的,这样通频带会下降,对应每一帧图像上所能够画出来的线段数就会减少。作者设想调高声卡DAC的转换速率来解决这个问题,但是后来发现96k和44.1k输出的画面基本没区别,就略过这个问题了。

到这里,硬件上面的问题就基本解决了,接下来解决软件的问题。简单点说,作者改造了原游戏中的3D引擎,利用了一些WinAPI实现了3D引擎和音频合成器之间的通信管道。游戏引擎的具体工作细节原文中有提到,这里不再赘述。

在游戏引擎中渲染出来的3D模型不能在示波器上直接显示,因为其中有一些透明的几何图形(示波器只能显示单色的线框,透明的几何物体是不应该绘制出来的),并且渲染深度和实际希望的有些许出入(太大)。声卡的输出信号的速率有限,于是作者用C++写了一个程序在管道的buffer上面对游戏引擎输出的图像进行处理(主要是删减不必要的线框),然后再输出到合成器上。目前发现的最大的Bug是这个处理程序不能正确处理房间的“角落”,有时候显示不出来墙角。

这样一来,合成器上面每frame需要绘制的线段数控制在了1800条左右,合成器在没有收到新数据的时候能够自动读取buffer里面暂存的数据,自动刷新画面。由于“亮点”是连续移动的,因此画面刷新是以几何物体的线段为单位进行的,每条线段的刷新率在5-20Hz/frame左右。并且由于声卡上面有LPF,在一些线段的末端会有莫名其妙的抖动。作者在这个作品上面用了一块廉价的USB声卡,因此图像上面也有一些莫名其妙的低频噪声。声卡96k的最大输出速率也极大地限制了每frame中能够显示的线段的最大数量。因此实际游戏玩起来体验不是很好。

以上大概就是technical report的内容概括了。实现这种功能的关键并不是“对模拟示波器进行编程”,而是巧妙利用模拟示波器的X-Y档,将其改造为一个简易的CRT显示器。实际的计算操作,还是得交给电脑来完成的。
用Deepseek满血版问问看
回复
使用道具 举报
djinlin | 未知
这个我本科的时候做过,用模拟示波器、单片机和一些标准器件完成。示波器设置成XY模式后可以接受X、Y、Z三路模拟信号输入,(X,Y)控制坐标,Z控制亮度。只要分别产生周期同步的锯齿波和阶梯波作为X和Y输入,就实现了在示波器屏幕上逐行扫描的效果,然后在单片机的内存里弄一块区域作为输出缓冲区,把它的内容逐点同步输出到Z,也就通过控制亮度实现了图形输出。



如上图,所有的同步信号都由单片机输出,我是用硬件电路对行同步信号整形产生的锯齿波,阶梯波比较麻烦,所以直接拿单片机的DAC输出了。

这样弄好之后就能在示波器屏幕上显示单片机输出缓冲区里的点阵数据了,剩下的怎么操作点阵数据都是软件问题,是做个记事本还是做个刺客信条就随你了。我做的时候就只是在屏幕上显示了几个汉字,然后用外接的4x4键盘实现了A~F这几个字母的输入还有移动光标、换行、删除、复制粘贴等功能,都是用汇编写的,就这么点东西快写吐了。

注意一下分辨率的限制,为了让图像不闪烁,屏幕扫描的帧率至少得50Hz吧,在20ms内能扫描几行就看单片机系统的时钟周期了,我用的时钟周期0.5us,1/4分频后送到移位寄存器的,所以一屏最多10000个“像素”,最后设置的90行x96列。

锯齿波发生器:


移位寄存器:

因为74LS166输出的高低电平是5V和0V,示波器Z轴的接受范围是-5V~+5V,所以用运放做了个电压比较器放大了一下,让屏幕上亮暗更分明一点。

程序流程图:

最后,珍爱生命,远离汇编。
回复
使用道具 举报
三个太阳 | 未知
人家那是把游戏图像实时转换成模拟波形信号再输出到示波器上的。你都知道模拟示波器是个模拟设备了,模拟设备怎么能编程。至于图形怎么转成波形信号,就是另一个问题了。
回复
使用道具 举报
遊戲人生 | 未知
示波器有个模式叫做XY模式,就和电视一样。
回复
使用道具 举报
aassdd2008 | 未知
我的大概思路是:通过matlab可以把图片二值化,然后通过二值图把图像的边界确定,再通过转换变成电压波形图,在输出给示波器
回复
使用道具 举报
快速回复
您需要登录后才可以回帖 登录 | 立即注册

当贝投影