本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:曾是一颗薏米

一、项目背景

在几年前,Google 给 Chrome 浏览器加了一个有趣的彩蛋:如果你在未联网的情况下访问网页,弹出的错误界面会出现一只小恐龙。许多人可能觉得这只恐龙只是一个可爱的小图标,在断网的时候陪伴用户。但是后来有人按下空格键,小恐龙开始奔跑!
这个小彩蛋成为深受人们喜爱的小游戏,风靡至今。

二、体验Google Chrome小恐龙游戏

在电脑上只要安装了Google Chrome浏览器并在网址栏输入:chrome://dino/,然后按下空格就能开始小恐龙游戏。

三、移植工作

前段时间在b站看到up主(hj240)移植到单片机上,想到刚好可以在MM32上玩一下!于是,开始了移植工作。
硬件使用:0.96寸的oled屏(4线,i2c接口)

使用杜邦线按下面方法连接:

VCC ----> 板载3.3V
GND ----> 板载GND
SLC ----> PF0
SDA ----> PF1

MM32的i2c数据手册有使用dma的描述,但例程只提供轮询和中断两种实现。鉴于程序较简单,用软件模拟i2c接口方便移植~之前在使用stm32硬件i2c有时出现总线挂死,看了手册MM32支持SDA恢复,后续可考虑使用硬件i2c。

  1. 使能相应时钟。因为使用S3、S4作为按键,与之对应GPIOH/I时钟需要使能。GPIOF口用于软件模拟i2c也要使能该时钟。
void BOARD_InitBootClocks(void)
{CLOCK_ResetToDefault();CLOCK_BootToHSE120MHz();/* UART1. */RCC_EnableAPB2Periphs(RCC_APB2_PERIPH_UART1, true);RCC_ResetAPB2Periphs(RCC_APB2_PERIPH_UART1);/* GPIOB. */RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOB, true);RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOB);/* GPIOC. */RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOC, true);RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOC);/* GPIOD. */RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOD, true);RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOD);/* GPIOI. */RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOI, true);RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOI);/* GPIOF. */RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOF, true);RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOF);/* GPIOH. */RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOH, true);RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOH);
}
  1. 设置gpio,用于按键和软件模拟i2c。
    由原理图可知,按键有外部上拉,因此io模式配置为上拉,当按下时检测低电平即可。

void BOARD_InitPins(void)
{
GPIO_Init_Type gpio_init;

/* PB6 - UART1_TX. */
gpio_init.Pins = GPIO_PIN_6;
gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio_init);
GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_7);

/* PB7 - UART1_RX. */
gpio_init.Pins = GPIO_PIN_7;
gpio_init.PinMode = GPIO_PinMode_In_Floating;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio_init);
GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_7);

/* LED0. */
gpio_init.Pins = GPIO_PIN_0;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOI, &gpio_init);

/* LED1. */
gpio_init.Pins = GPIO_PIN_2;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &gpio_init);

/* SCLK */
gpio_init.Pins = GPIO_PIN_0;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &gpio_init);

/* SDA */
gpio_init.Pins = GPIO_PIN_1;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF, &gpio_init);

/* KEY2. */
gpio_init.Pins = GPIO_PIN_15;
gpio_init.PinMode = GPIO_PinMode_In_PullUp;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio_init);

/* KEY1. */
gpio_init.Pins = GPIO_PIN_2;~~~~
gpio_init.PinMode = GPIO_PinMode_In_PullUp;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOH, &gpio_init);
}

  1. 在oled12864.h修改软件模拟i2c的引脚
    //-----------------OLED IIC端口定义----------------

    #define OLED_SCLK_Clr() GPIO_WriteBit(GPIOF, GPIO_PIN_0, 0u)
    #define OLED_SCLK_Set() GPIO_WriteBit(GPIOF, GPIO_PIN_0, 1u)

    #define OLED_SDIN_Clr() GPIO_WriteBit(GPIOF, GPIO_PIN_1, 0u)
    #define OLED_SDIN_Set() GPIO_WriteBit(GPIOF, GPIO_PIN_1, 1u)

  2. 实现软件延时函数用于调节游戏难度。

    void HAL_Delay(uint32_t ms)
    {
    uint32_t ms_cnt = ms;
    for (uint32_t i = 0u; i < ms_cnt; i++)
    {
    for (uint32_t j = 0u; j < (CLOCK_SYS_FREQ / 10000u); j++)
    {
    __NOP();
    }
    }
    }

  3. main函数主要逻辑

    int main(void)
    {
    unsigned char key_num = 0;
    unsigned char cactus_category = 0;
    unsigned char cactus_length = 8;
    unsigned int score = 0;
    unsigned int highest_score = 0;
    int height = 0;
    int cactus_pos = 128;
    unsigned char cur_speed = 30;
    char failed = 0;
    char reset = 0;

    BOARD_Init();
    printf(“\r\initiliazed OK!\r\n”);
    OLED_Init();
    OLED_DrawCover();
    HAL_Delay(100);
    while(get_key_val()!=2);
    HAL_Delay(100);
    OLED_Clear();

    printf(“\r\nDinosaur game initiliazed OK!\r\n”);

    while (1)
    {
    if (failed == 1)
    {
    OLED_DrawRestart();

    key_num = get_key_val();
    if (key_num == 2)
    {
    if (score > highest_score) highest_score = score;
    score = 0;
    failed = 0;
    height = 0;
    reset = 1;
    OLED_DrawDinoJump(reset);
    OLED_DrawCactusRandom(cactus_category, reset);
    OLED_Clear();
    }
    continue;
    }

score ++;if (height <= 0) key_num = get_key_val();OLED_DrawGround();OLED_DrawCloud();if (height>0 || key_num == 1) height = OLED_DrawDinoJump(reset);else OLED_DrawDino();cactus_pos = OLED_DrawCactusRandom(cactus_category, reset);if(cactus_category == 0) cactus_length = 8;else if(cactus_category == 1) cactus_length = 16;else cactus_length = 24;if (cactus_pos + cactus_length < 0){cactus_category = rand()%4;OLED_DrawCactusRandom(cactus_category, 1);}if ((height < 16) && ( (cactus_pos>=16 && cactus_pos <=32) || (cactus_pos + cactus_length>=16 && cactus_pos + cactus_length <=32))){failed = 1;}OLED_ShowString(35, 0, "HI:", 12);OLED_ShowNum(58, 0, highest_score, 5, 12);OLED_ShowNum(98, 0, score, 5, 12);reset = 0;cur_speed = score/50;if (cur_speed > 29) cur_speed = 29;HAL_Delay(30 - cur_speed);key_num = 0;}}

四、oled驱动原理 & 游戏实现讲解

有兴趣的可以看下面的链接,这里不再赘述。

链接1:【手把手讲解在51单片机实现小恐龙游戏-上集】

链接2:【手把手讲解在51单片机实现小恐龙游戏-下集】

五、玩法介绍

程序开始运行后,串口会初始化成功的打印信息。然后出现游戏界面按下开始游戏的按键即可开始游戏。游戏过程中,需控制小恐龙跃过障碍物,如果触碰障碍物则游戏结束。

六、游戏效果

由于oled屏的缘故,图片不能反应真正的游戏效果,建议自己烧录体检下。 原本担心软件i2c会比较慢导致卡顿,实际游戏效果非常丝滑。

手机录制效果比较差,难以反馈真实效果,我就不录了。大家可以参考移植到stm32的视频:

七、开源

欢迎大家沟通学习,另外感谢原作者hj240的开源。
我的gitee仓库地址:
https://gitee.com/sakura96888/mm32-f5270\_-dinosaur-game-m
第一次编译后,需自行选择下载器,如开发板标配的:CMSIS-DAP。下载后,按下复位键即可。

八、总结

MM32是国产MCU崛起的缩影,开发板硬件资源丰富,有很强的可玩性。MindSDK提供了模板用于快速开发,总体来说体验不错,但例程有些简单不够吸引人,也没有充分发挥硬件性能,希望以后MM32的生态能更丰富些。
另外,在使用时发现开发板自带的CMSIS-DAP下载器进入调试后,无法正常查看栈中的变量,能正常查看寄存器的值(原因未知,猜测下载器固件不支持Armv8-M 架构?)

【MM32F5270开发板试用】移植Google Chrome小恐龙游戏到MM32F5270相关推荐

  1. 【MM32F5270开发板试用】快速移植STM32应用到MM32F5270(以OLED为例)

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:@#@ 本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活 ...

  2. 【MM32F5270开发板试用】 MindSDK使用测评

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:胖墩墩 一.前言: 非常感谢极术社区和灵动微电子开展的MM32F5270开发板试用申请活动 ...

  3. 【MM32F5270开发板试用】播放TF卡WAV格式音乐,I2S驱动CS4344

    [MM32F5270开发板试用]播放TF卡WAV格式音乐,I2S驱动CS4344 上四篇文章: [MM32F5270开发板试用]一.依靠SPI_SD,移植FatFs文件系统 [MM32F5270开发板 ...

  4. 【MM32F5270开发板试用】RT-Thread SPI 驱动适配指南

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:xusiwei1236 本文记录了我在社区"Rice我叫加饭?"大佬移 ...

  5. 【MM32F5270开发板试用】手势传感PAJ7620U2的智能家居应用

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:风云再起 一.序 很高兴能参加极术社区联合灵动微电子组织的[灵动MM32F5270开发板试 ...

  6. 【MM32F5270开发板试用】定制MicroPython及读取MPU6050数据到OLED1306

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:HonestQiao 前言 这次有幸获得MM32F5270开发板的试用,非常幸运. 收到板 ...

  7. 【MM32F5270开发板试用】一、让MM32F5270支持RT-Thread~打通串口UART

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:Magicoe是攻城狮 喜欢RT-Thread的代码10余年-,但凡有新上手的MCU必定看 ...

  8. 【MM32F5270开发板试用】六、如何用 星辰内核 + 国产RTOS 通过I2S播放 “星辰大海”

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:Magicoe是攻城狮 这个demo和想法是参考了大神的文章 https://aijish ...

  9. 【MM32F5270开发板试用】GPIO输入+EXTI外部中断例程demo试用

    本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站.作者:Zeee 前言: 首先,感谢灵动微电子与极术社区给予宝贵的试用机会.借助本次对Plus-F ...

最新文章

  1. 如何确认oracle客户端中的TNSNAMES中的service_name
  2. Python 技术篇-利用pdfkit库实现html格式文件转换PDF文档实例演示
  3. 1.4 File类(文件操作类)获取文件属性,创建和删除文件\目录,遍历目录
  4. ASP.Net2.0 数据绑定控件的优越性在哪里?
  5. 深入浅出设计模式之设计模式简介
  6. javascript --- [FormData的使用] 文件上传进度条展示 文件上传图片即使预览
  7. Ouibounce – 在用户离开你网站时显示模态弹窗
  8. tensorflow随笔——VGG网络
  9. Adb refused a command 解决方法
  10. @程序员,你会教自己的孩子学习编程吗?
  11. mac 下安装iwork+ps+nx2
  12. 如何清除Hacktool.Rootkit病毒,如何让msdirectx.sys此文件彻底删除,谢谢!
  13. 硬盘IDE和AHCI模式的区别
  14. 高速服务器充电桩位置,最全高速服务区充电站汇总,再也不担心过年回家趴半路啦!...
  15. 在php中使用高德api,javascript - 高德地图定位如何调用api?
  16. 【华为OJ】【MML命令执行结果查询】
  17. 计算机网络 网络层 私网地址和公网地址及子网划分
  18. word批量导入试题,一键组卷,单机软件题库管家迎来1.2版本
  19. Python面向对象基本概述
  20. 卡巴斯基安装时提示有360 Antivirus Software,发生致命错误

热门文章

  1. 一文详解自动驾驶的运行设计域(ODD)| 自动驾驶系列
  2. Mybatis中XML的文件SQL语句与动态sql标签(trim|where|set|foreach|if|choose|when|otherwise|bind)
  3. Beginning Core Image in iOS 6
  4. MPlayer音视频播放器的移植
  5. 【SandQuant 量化投资】威廉·夏普:资本资产定价:风险条件下的市场均衡理论
  6. 三人行均为我师^_^
  7. 如何快速搜索多个word、excel等文件中内容
  8. 无线接入点AC设备配置命令大全
  9. 模板文件下载后乱码或异常的可能原因及解决方案
  10. 百度图表 ECharts