请选择 进入手机版 | 继续访问电脑版
查看: 961|回复: 1

[分享] 用最简单的MCU演示John Conway的"生命游戏”

[复制链接]
  • TA的每日心情
    开心
    5 天前
  • 签到天数: 265 天

    [LV.8]以坛为家I

    3284

    主题

    6519

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    31751
    最后登录
    2024-3-19
    发表于 2020-11-26 09:55:00 | 显示全部楼层 |阅读模式
    用最简单的MCU演示John Conway的"生命游戏”
    今年四月初,当代最有趣的数学家John Horton Conway,因为新冠肺炎逝世了,享年82岁。


    有人评价他,世界上可能有比他更厉害的数学家,但是在顶尖的数学家里,没有人能比他科普做得更好。
    量子位,公众号:中科院物理所
    生命游戏发明者、英国全能数学家John Conway因新冠去世

    1.png
    他发明的一款生命游戏,在上世纪70年代占据了1/4的计算机,成为那时极客的最爱。
    现在最简单的32位MCU,在计算性能上早已可以和70年代的计算机媲美,玩玩这款数学游戏应该不在话下。
    正好今年暑假之前,我接到一个任务要指导天津大学2019恩智浦班的同学做实习,实习平台选择了LPC812-Max开发板。当时的第一想法就是,可以让同学们在LPC812上把这个游戏做出来。
    这就是LPC812-Max开发板
    2.png
    下面先简单介绍一下LPC812这款产品。

    LPC812简介


    下面是LPC812的框图:
    3.png


    LPC812的基本特性包括:
    ·Arm Cortex-M0+内核,运行主频30MHz,具有单周期的乘法指令和单周期的快速I/O端口。
    ·16KB Flash存储器和4KB SRAM
    ·3个USART、2个SPI和1个I2C接口
    ·18个高速GPIO端口
    ·灵活的I/O开关矩阵
    ·状态机可配置计数器(SCT)
    ·CRC计算引擎
    ·工作温度范围可达-40~105C
    ·多种封装:DIP8、XSON16、TSSOP16、SO20和TSSOP20


    LPC812的应用领域包括但不限于:
    ·传感器集中器
    ·无线通信的接口,例如NFC、BTLE、Zigbee或WiFi等
    ·人机接口,例如触摸、手势等
    ·电池供电管理
    ·替换传统的8/16位应用等



    “生命游戏”演示
    John Conway的生命游戏的规则非常简单,描述如下:


    1、每个细胞有两种状态,存活或死亡。每个细胞与以自身为中心的周围八个细胞产生互动。
    2、当前细胞为存活状态时,如果它周围的存活细胞低于2个时(不包含2个),该细胞变成死亡状态。(模拟生命数量过少)
    3、当前细胞为存活状态时,如果它周围有2个或3个存活细胞时,该细胞保持原样。
    4、当前细胞为存活状态时,如果它周围有超过3个存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
    5、当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。(模拟繁殖)


    为了验证这个题目,我自己先动手在LPC812上编了个程序实现它。
    由于LPC812开发板本身没有显示屏,所有的显示都是通过UART串口,通过板载调试器附带的USB转UART接口,传送到PC的串口窗口显示,我用的是PuTTY软件。
    先来看看演示视频:


    若干实现要点


    在这个游戏中有若干编程要点,值得重点介绍一下供大家参考。
    首先是显示的问题

    一般我们通过串口窗口显示的都是字符,并且是黑白的单色字符,如何能够显示图形,而且是彩色图形呢?
    这个问题在过去的CRT显示器时代就已经解决了。当时的显示器都只能显示字符,不能直接显示点阵图形,因此人们就发明了一些显示符号,用于显示一些表格和大字。
    在现在任何的Windows系统中,只要打开"字符图"(Character Map)这个应用程序就会看到这些特殊字符,如下为其截图:
    4.png
    当我们的程序向串口发送这些字符时,就会显示在PuTTY窗口中。
    例如上面视频显示的演示中,使用了以下三个字符:
    5.png
    红框中从左至右:一个全黑方块(E2 96 88)、一个下半小方块(E2 96 84)和一个上半小方块(E2 96 80),再加上一个空格。这里括号中是它们的十六进制编码,需要连续输出3个字节才能显示对应字符。
    这样每个字符行可以显示游戏中的两行数据的状态:某个单元有生命则显示小方块,没有生命则显示底色(空白)。
    通过这样的显示符号还可以显示其它很多内容,例如下面这样的表格,这个显示是另一个"计算八皇后"实习项目的演示:
    6.png
    那么怎么显示颜色呢?在过去字符显示器时代,颜色是通过输出一串转义字符实现,这里简单地列出一部分内容:
    7.png
    例如前述视频中需要的绿色背景下显示红色字符,就要输出ESC[31;42m,这里的ESC是转义字符,十六进制为0x1B,因此在C语言里,这个字串表示为"\033[31;42m"。
    使用转义字符还可以实现光标的移动、清除屏幕或字符行等操作。有兴趣的读者可以在网上找到完整的说明文档。
    其次是显示图形的尺寸问题
    在上面演示视频中,整个"世界"是一个96x56个细胞单元的矩阵,如果每个单元都用一个字节表示,那么至少需要超过5KB的存储容量,但是LPC812内部的RAM只有4KB,所以需要改变存储方式,采用每个细胞单元使用一个比特位表示,这样整个"世界"只需672个字节即可。
    为了充分利用32位的带宽,在实际实现中使用3个字表示图形中的一行96个细胞,总共需要56x3个字的存储。
    我在代码中定义了两个这样的二维数组,一个命名为theSky,另一个命名为theEarth,每次计算都是参考其中一个数组的状态,而设置另一个数组的状态,即实现细胞世界的换代。
    最后是显示的速度问题
    采用这种双数组的方式,就可以在计算其中一个数组的时候,显示另一个数组(上一代)状态,从而提供整体模拟的速度。
    我在另一款LPC824的开发板上,用DMA的方式实现了上一代的显示与新一代更新的重叠。但因为LPC812没有DMA外设,只能采用串行的方式操作。
    当然,如前面所讨论的,每两行细胞单元合并显示在单一字符行中,因此在显示之前需要进行一次变换,把二维数组的内容转换为转义字符串,并暂存在一个大的缓存中,转交DMA或输出函数进行发送。


    小结


    和现在很多MCU相比,LPC812看起来很简单,但是从本文的演示看,只要在算法上考虑好,选择合适的存储和计算策略,同样可以做出很出色的效果。
    再加上LPC800系列中,很多优秀的内置外设,还可以实现很多复杂的操作,以后我会慢慢地分享出来。


    PS:需要LPC812MAX开发板的可以联系我(1278064213)
    上班第一天
    回复

    使用道具 举报

  • TA的每日心情
    开心
    昨天 17:08
  • 签到天数: 1332 天

    [LV.10]以坛为家III

    88

    主题

    4287

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    8996
    最后登录
    2024-3-19
    发表于 2020-11-26 11:48:51 | 显示全部楼层
    这个小游戏确实有很多思考的地方。
    古人云“我思,故我在”
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-3-19 14:50 , Processed in 0.118956 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表