电玩圈游戏网 搜一搜

安卓手游去频道 >

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

安卓应用去频道 >

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

游戏视频去频道 >

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

资讯攻略去频道 >

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

专题合集去频道 >

游戏专题 应用专题

排行榜单去频道 >

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

首页>资讯>游戏攻略>深圳SHENZHENIO第3关脉冲发生器攻略

深圳SHENZHENIO第3关脉冲发生器攻略

作者:佚名来源:百度2022/05/31

深圳IO是一款硬核的编程游戏,有着严谨的游戏内容,那么一起来看看第3关信号脉冲发生器的攻略吧。

概念MAIL:任务中心,游戏的主题都在其中,为了仿照认真工作的样子,所有的任务背景和内容都模拟邮件的形式进行

数据手册:嵌入式开发必经之路,相当于正常游戏的新手引导,哈哈,读起来很有感觉呢

控制面板:就是控制台啦,这不需要过多叙述了

纸牌游戏:这个会在游戏前期解锁,一旦解锁,这个游戏可能就变成了一款蜘蛛牌游戏。

主界面

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

游戏中DX300参考

像这样的器件足足有17个!!!! 哈哈,有没有已经感觉到挑战了呢?

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

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

游戏中主要使用的编程语言

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

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

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

第1关:安全摄像头

第2关:信号放大器

第3关:脉冲发生器

关卡展示

这一关需要让你在按钮未按下时(对应的输入信号为 0)保持待命,而在按钮按下时(对应的输入信号为 100)生成 100×1s,0×1s 的循环脉冲信号。

这一关我们需要了解【测试指令】这个新概念。

测试指令一共有 4 条:

1,teq I1/R1/P1 I2/R2/P2,测试(test)第一个操作数是否等于(equals)第二个操作数。若两数相等,激活所有带 + 前缀的指令,关闭所有带 - 前缀的指令。若两数不等,激活所有带 - 前缀的指令,关闭所有带 + 前缀的指令。

2,tlt I1/R1/P1 I2/R2/P2,测试第一个操作数是否小于(lower than)第二个操作数。若第一个数小于第二个数,激活所有带 + 前缀的指令,关闭所有带 - 前缀的指令。若第一个数大于或等于第二个数,激活所有带 - 前缀的指令,关闭所有带 + 前缀的指令。

3,tgt I1/R1/P1 I2/R2/P2,测试第一个操作数是否大于(greater than)第二个操作数。若第一个数大于第二个数,激活所有带 + 前缀的指令,关闭所有带 - 前缀的指令。若第一个数小于或等于第二个数,激活所有带 - 前缀的指令,关闭所有带 + 前缀的指令。

4,tcp I1/R1/P1 I2/R2/P2,比较(compare)两个操作数的大小。若第一个数小于第二个数,激活所有带 - 前缀的指令,关闭所有带 + 前缀的指令。若第一个数大于第二个数,激活所有带 + 前缀的指令,关闭所有带 - 前缀的指令。若两数相等,关闭所有带 + 和 - 前缀的指令。

5,带 + - 前缀的指令会一直保持自己的激活或关闭状态,直到遇到下一条测试指令。测试指令前也是可以带 + - 前缀的,这意味着测试指令不是一定会被执行。这属于高阶技巧,以后我们再详细讲解。

举例说明:

1: teq p0 100

2:+ mov 50 p1

3:- mov 0 p1

4: slp 1

首先,我们测试 p0 端口的值是否为 100。如果是 100,那么后续 + 前缀的指令(mov 50 p1)将会被执行,而 - 前缀的指令(mov 0 p1)将不会被执行,那么 p1 口收到的值很明显是 50。反之,p0 端口的值不是 100 时,+ 前缀的指令不执行,- 前缀的指令正常执行,p1 口收到的值就会是 0。

回到这一关,我们需要在按钮按下时(按钮端口的值为 100)时生成脉冲方波(使用 gen 指令生成);而在按钮抬起时(按钮端口的值为 0)时安心休眠待命(使用 slp 指令)。经过以上分析后,这一关的答案已经呼之欲出:

按钮端口只有 0 和 100 两种值,我们首先对和按钮端口相连接的 p0 口执行测试指令 tcp p0 50。当 p0 小于 50 时,按钮处于抬起状态,激活 - 前缀的指令,我们需要执行休眠指令原地待命(- slp 1);当 p0 大于 50 时,按钮处于按下状态,激活 + 前缀的指令,我们需要不断执行 gen 指令生成 100 和 0 各占一秒的方波(+ gen p1 1 1),直到某刻 tcp 测试指令变为 - 生效为止。

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

优化代码行数

这里要提到一个隐藏特性:slp 里的休眠时间,和 gen 里的两个休眠时间是可以指定为 0 的。

mov 0 p0

slp 1

等价于

mov 100 p0

slp 0

mov 0 p0

slp 1

等价于

gen p0 0 1

我们在同一个时钟周期里可以反复给同一个 p 口赋不同的值,当前的时钟周期过去了之后,确认面板上会显示出对应 p 口【最后一次】赋的值。所以,我们在同一时钟周期里给 p0 依次赋值 100 和 0 后,p0 口这一个时钟周期内的实际值只会是 0。

现在,我们要再了解一个新的元件:DX-300。这个原件最多可以同时对 3 个简单 I/O 口进行读取或写入操作,具体的做法和二进制的【位运算】有点相似。

我们先说 DX-300 怎么同时读三个口的数据。我们将 DX-300 的 p0、p1、p2 分别和三个简单 I/O 口相连,然后另一侧的三个 X 口会实时传送一个三位数表示三个简单 I/O 口的状态:p0 为 0/100 时,个位数为 0/1;p1 口为 0/100 时,十位数为 0/1;p2 口为 0/100 时,百位数为 0/1。那么 DX-300 的 X 口所传出的三位数就有以下 8 种可能:000、001、010、011、100、101、110、111,依次对应三个简单 I/O 的开/关状态的 8 种排列组合。

同时写三个简单 I/O 的原理也很类似,我们往 DX-300 的任意一个 X 口写入以上 8 种三位数中的一种,就达到了用一条指令同时控制三个简单 I/O 的目的。比如你想让 p0 和 p2 变为 100,p1 变为 0,那么你就给 DX-300 传 101 就可以了。

那么这道题,我们怎么优化到 1 条指令呢?我们的第一种方案里,芯片里的代码是这样的:

1: tcp p0 50

2:- slp 1

3:+ gen p1 1 1

然后,我们可以推断出来,当执行到【- slp 1】时,p1 口的值一定是 0。由于 gen 指令一定以将对应 p 口赋 0 终结,所以以上 slp 指令也可以替换成 gen 指令,我们的代码可以改写成下面的样子

1: tcp p0 50

2:- gen p1 0 1

3:+ gen p1 1 1

这两条 gen 指令只有一个操作数不一样,那么它们能不能合并成一条呢?答案是可以的。我们不难发现:当 p0 是 0 时,执行的是 gen p1 0 1;当 p0 是 100 时,执行的是 gen p1 1 1。如果我们有一种办法能把 p0 的 100 转换成 1,那么只要一条 gen p1 (?) 1 指令就够了,问号处是经过转换后的数字。

这时候,我们的 DX-300 闪亮登场。我们将【按钮】端口接到 DX-300 的 p0 口上,其余两个口空着不接(视为对应端口的值恒为 0)。这样,当【按钮】端口的值为 0 时,经过 DX-300 加工后为 000;反之,当【按钮】端口的值为 100 时,这个值经过 DX-300 加工后会变成 001。这个加工后的值正好是我们需要在 gen 指令中用到的值!

于是,只用一行代码的设计方案顺利完成!

评论 (0)

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

上拉或点击查看更多