电玩圈游戏网 搜一搜

安卓手游去频道 >

角色扮演 射击枪战 棋牌卡牌 体育运动 角色扮演 赛车竞速 休闲益智 音乐舞蹈 模拟经营 战棋塔防 推理解谜 策略战争

安卓应用去频道 >

社交通讯 系统工具 影音视听 拍摄美化 效率办公 学习教育 生活服务 旅游出行 资讯阅读 金融理财 网络购物 游戏助手

游戏视频去频道 >

动作冒险 射击枪战 棋牌卡牌 体育运动 角色扮演 赛车竞速 音乐舞蹈 模拟经营 战棋塔防 推理解谜 策略战争 休闲益智

资讯攻略去频道 >

手游资讯 手游攻略 手游问答 游戏资讯 游戏杂谈 游戏攻略 软件教程 软件资讯

专题合集去频道 >

游戏专题 应用专题

排行榜单去频道 >

游戏排行 应用排行
首页 游戏 应用 视频 资讯 专题 榜单

首页>资讯>游戏攻略>深圳SHENZHENIO第13关古钱币付款终端攻略

深圳SHENZHENIO第13关古钱币付款终端攻略

作者:佚名来源:百度2022/06/02

深圳IO是一款硬核的编程游戏,有着严谨的游戏内容,那么一起来看看第13关的古钱币付款终端的攻略吧。

主界面

由于游戏过分硬核,先放个手册中的图看看冰山一角:

不过这也正对应了嵌入式开发中会遇到的海量数据手册,相当程度上还原了嵌入式日常开发的情景。

游戏中设计到部分的编程有些类似于汇编语言,这里上手还是有一些些难度的,大家请做好准备,继续直接扔核弹:

不用害怕,在游戏过程中,会逐步引导你学会使用新的指令,对于新的器件,也是随着主线的进行逐步开放的

在游戏中,你不仅可以完成指定的基本目标,还可以挑战全网玩家,看谁能达成最佳优化目标。

鱼和熊掌不可兼得,多数情况下想要达成更好的性能就要增加成本啦,不过这正是优秀的嵌入式开发人员的意义所在——比你好,还比你的便宜。

第 13 关:古钱币付款终端

关卡展示

自动售货机大家都见过吧,这关要实现的就是类似于自动售货机一样的东西。现在这台售货机里的商品价格已经定死了(写在【价格】常数芯片里),顾客投入 1/5/12 元的硬币,一旦任何时候累计价格大于等于商品价格时,就响 4 秒钟的铃,同时找零口开始给用户找钱,优先找 5 元硬币,找零剩余不足 5 元时开始找 1 元硬币。

由于找零的脉冲信号要维持 4 秒钟,且在此期间就要开始给顾客找零。所以为了方便,我们将收钱及响铃的程序写在一块芯片上,而找零的程序写在另一块芯片上。首先我们写收钱部分。

左边有三个投入口,我们肯定要把它们接到一个 DX-300 上,这样我们仅仅判断一个三位数就能得知哪个口投入了钱币。

从本关开始,我们要认识一条新的指令:跳转指令 jmp。它的用法是:jmp 行标,意思是无视原先的执行顺序,强制跳转到对应行标处执行。这条指令通常都是和 + - 号前缀同时使用的,表示“按条件跳转”。

这里我们之所以使用了 jmp 跳转指令,是因为和硬币投入口连接的 DX-300 其实是一个四态输入(没错,四种状态,连单纯的应付三种状态的 tcp 都无能为力):000 表示没有钱币投入;001 表示投入了 1 元硬币;010 表示投入了 5 元硬币;100 表示投入了 12 元硬币。如果少了最前面的(teq x1 0, + jmp d)两条指令的话,那么后面的 tcp x0 10 在遇到 000 和 001 两种状态时都会激活同样的 - 号指令(投入 1 块钱)。这显然不是我们想要的。所以,当状态值为 000 时,我们需要使用跳转指令强制跳转到最后的 slp 1,跳过 tcp 的三态判断。

下面我们来到了 tcp 三态判断。首先我们假设当前的状态值是中间状态 010(即用户投入的是 5 块钱),先令 acc +5 再说(add 5)。然后若 tcp 判定出 DX-300 的值位于两端状态,我们再做额外的调整(tcp x1 10)。当状态值是 001 时,说明客户投入的是 1 块钱,acc 要在之前的基础上 -4(1 = 5 - 4),所以 - 部分写的是 - sub 4;当状态值是 100 时,说明客户投入的是 12 块钱,acc 要在之前的基础上 +7(12 = 5 + 7),所以 + 部分写的是 + add 7。执行完上述操作后,我们得到了当前顾客已经累计投入的金额数量。

由于本游戏对于不等的判定只有【严格大于】和【严格小于】两种,所以对于【大于等于】这样的判定,我们只能用【不小于】来判定,即使用 tlt 测试指令,然后 - 号部分写“第一个数【不小于】第二个数时”的操作。我们先判断当前顾客已投入的金额数量是否【小于】价格(tlt acc x0)。若【不小于】价格,则将 acc 减去价格得到需要找零的数量(- sub x0),然后将找零值发给右边的芯片,委托右边的芯片执行找零任务(- mov acc x3),清除 acc 的值准备迎接下一个顾客(- mov 0 acc),做完这些事后,响铃 4 秒(- gen p1 4 1)。若当前顾客已投入的金额【仍小于】价格,就休眠一秒,继续等待当前顾客投入更多的硬币(+ slp 1)。

左边的“收钱及响铃”程序已经完成,现在要开始完成右边的“找零”程序。在这里,我们需要学习 jmp 指令的另一个重要功能:实现循环。

假设你现在要往 p1 口发送一段共计 20 次脉冲的方波信号,你会怎么做?即使是代码空间最大的 MC6000,你也写不下 20 条 gen 指令。或者,脉冲次数不确定,由另一个输入口提供呢?你根本不知道要写几条 gen。

程序有三大结构:顺序结构、选择结构、循环结构。我们现在已经熟练掌握了前两大结构,现在我们就要学习如何利用跳转指令实现循环结构,生成共计 20 次脉冲的方波信号给 p1。以下是代码和解释:

1: mov 20 acc

# acc 表示剩余脉冲次数。初始状态下赋值 20。

2: tcp acc 0

# 检查剩余脉冲次数是否大于 0

3:+ sub 1

# 若剩余脉冲次数大于 0,则令该次数 -1

4:+ gen p1 1 1

# 向 p1 口生成一次方波

5:+ jmp 2

# 令程序跳转到第 2 行,继续判断剩余脉冲次数是否大于 0

# 如此往复,直到脉冲次数归零为止

如果把这样的汇编代码改写成 C 语言的样式,那大概长这样:

acc = 20;

while (acc > 0) {

--acc;

gen(p1, 1, 1);

}

学过 C 语言编程的同学大概一眼就能看出来,while 语句块的部分就是一个非常典型的 20 次循环。

回到题目。当右边的 MC6000 芯片收到由左边芯片传来的“待找零数量”数据后,该如何找零呢?了解了程序的循环结构后,我们很容易设计出这样一套带有循环结构的算法:

1,将待找零数量放入 acc 寄存器。

2,判断 acc 寄存器的值是否大于 4。若满足条件,则令 acc -5,然后生成一个“找零 5 元”的脉冲信号,并反复执行此步,直到 acc 寄存器的值不大于 4 为止。

3,判断 acc 寄存器的值是否大于 0。若满足条件,则令 acc -1,然后生成一个“找零 1 元”的脉冲信号,并反复执行此步,直到 acc 寄存器的值归零为止。

4,执行到此处后,本次找零完毕,等待下一次找零信号的出现。

根据以上算法,我们写出下面这样的代码:

首先,因为找零信号不会在固定的时间出现,而是仅当用户投入了足额的硬币后才会从左边的芯片传过来,所以我们必须要用 slx 指令来等待信号出现后才能读取找零值。然后,第 2 行对应算法的第 1 步;第 3~6 行构成了“找零 5 元”循环,对应算法的第 2 步;第 7~10 行构成了“找零 1 元”循环,对应算法的第 3 步。以上任务执行完毕后,回到第 1 行 slx,对应算法的第四步“等待下一次找零信号”。

点击左下角的【模拟】,稍等片刻,便会弹出结算界面:

优化电量

将左边那块芯片中倒数第二行的 gen p1 4 1 改成 gen p1 4 3 即可。这是我尝试出来的允许的最长睡眠时间。电量可以由 318 减少到 294。

碎碎念

右边那块 MC6000 芯片接了两个 p 口和一个 x 口,寄存器也只用到了 acc。如果能省掉一行代码,那么就可以毫不费力地换成 MC4000。但是我苦思冥想,结果却无论如何都省不掉哪怕一行代码。于是这块 MC6000 芯片换不成 MC4000 了,仅仅只是多一行代码而已啊,真的好不甘心。不知道读者们有没有办法能省出来一行代码,有的话请留言告诉我。

第1关:安全摄像头

第2关:信号放大器

第3关:脉冲发生器

第4关:动画 ESPORTS 标志

第5关:游戏积分器

第6关:调谐最优化引擎

第7关:被动红外感应器

第8关:仿真蜂鸣器

第9关:无线游戏控制器

第10关;真人cs

评论 (0)

相关阅读
网友评论0条评论

上拉或点击查看更多