总目录

《单片机—HLK-W801移植Nes模拟器(一)》
《单片机—HLK-W801移植Nes模拟器(二)》
《单片机—HLK-W801移植Nes模拟器(三)》

前面已经完成了程序的移植,今天试一下按键操作,好歹也能跳一下,吃个蘑菇,也行啊

按键识别

w801上按键的识别,我这里用的是一个之前用过的全向按键键盘,
通过GPIO的方式采集按键,为了消除抖动,采用了中断定时器循环扫描的方式,连续扫描到8次高电平,认为是按下。
方法参考自博客《#51单片机#中断实现按键消抖》

首先定义一下宏

#define GPIO_UP              WM_IO_PA_01
#define GPIO_DOWN           WM_IO_PA_02
#define GPIO_LFT            WM_IO_PA_08
#define GPIO_RHT            WM_IO_PA_04
#define GPIO_START          WM_IO_PA_05
#define GPIO_A              WM_IO_PA_06
#define GPIO_B              WM_IO_PA_07

然后注册GPIO,

#ifdef GPIO_UPtls_gpio_cfg(GPIO_UP, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);
#endif
#ifdef GPIO_DOWNtls_gpio_cfg(GPIO_DOWN, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);
#endif
……
#ifdef GPIO_Btls_gpio_cfg(GPIO_B, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);
#endif

然后定义一个定时器,每2毫秒就扫描一次按键

void  timer_demo(void)
{u8 timer_id;struct tls_timer_cfg timer_cfg;timer_cfg.unit = TLS_TIMER_UNIT_MS;timer_cfg.timeout = 2;timer_cfg.is_repeat = 1;timer_cfg.callback = (tls_timer_irq_callback)demo_timer_irq;timer_cfg.arg = NULL;timer_id = tls_timer_create(&timer_cfg);tls_timer_start(timer_id);printf("timer start\n");    }

最后实现循环扫描中断函数,这里只写了一个按键作为例子

static void demo_timer_irq(u8 *arg)
{#ifdef GPIO_UP{static unsigned char keybuf_UP = 0XFF;  //扫描缓冲区,保存一段时间内的扫描值。u8 KEY_UP;KEY_UP=tls_gpio_read(GPIO_UP);keybuf_UP = (keybuf_UP<<1)|KEY_UP; //缓冲区左移一位,并将当前扫描值移入最低位。if(keybuf_UP == 0X00){               //连续8次扫描值为0,即16ms内都只检测到按下状态,可认为按键已按下。up_key = 0; }else if(keybuf_UP == 0XFF){              //连续8次扫描值为1,即16ms内都只检测到弹起状态,可认为按键已弹起。up_key = 1;}}#endif
}

最后通过变量up_key ,通知到模拟器。模拟器通过以下函数,循环扫描按键变化

void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )

三个参数分别是1P,2P以及开关机按钮,默认的注释


//手柄控制定义,由一个DWORD类型数据表示,手柄1和手柄2定义相同
//      case Key_Right:
//    pdwPad1 |= (1<<7);  第七位表示 右
//    break;
//  case Key_Left:
//    *pdwPad1 |= (1<<6); 第六位表示左
//    break;
//  case Key_Down:
//    *pdwPad1 |= (1<<5);第五位表示下
//    break;
//  case Key_Up:
//    *pdwPad1 |= (1<<4);第四位表示上
//    break;
//  case Key_S:
//    *pdwPad1 |= (1<<3);第三位表示 Start
//    break;
//  case Key_A:
//    *pdwPad1 |= (1<<2); A键
//    break;
//  case Key_Z:
//    *pdwPad1 |= (1<<1); Z键
//    break;
//  case Key_X:
//    *pdwPad1 |= (1<<0); X键

这里还是以上键作为例子

#define PAD_JOY_UP       0x10
    *pdwPad1 = 0;
#ifdef GPIO_UPif(up_key){*pdwPad1 |= PAD_JOY_UP;printf("up\n");}
#endif

超级玛丽这款游戏的话,添加上 左右 开始和A键,就可以玩了,没有加速而已。添加好之后,展示效果



虽然是很卡顿,颜色也不正,但是好歹是走出了第一步。

颜色问题

估计是在写入SPI的时候,点的颜色与字节序有关系,猜测的没错,颠倒顺序之后,颜色就纯正多了

void ILI9341_DrawLineOne(u16 y,u16* data)
{int i=0;u16* dat=data;ILI9341_Address_Set(0,y,240,y);//设置光标位置 GPIO_DATA();//写数据for(i=0;i<240;i++){uint8_t data[2];data[0] = (*dat)>>8;data[1] = (*dat);tls_spi_write((uint8_t *)data,2);dat++;}}

不过随之而来的速率更慢了……因为每画一个点,都需要计算颠倒一次数据,再写入SPI。
不过我马上又灵机一动,
假如它想显示AB;
我错了一次,把AB显示成了BA;
那么让nes计算点的时候,也错一次,它要AB的,我就给它BA的,错上加错……
那么我画BA的时候,就会画成AB,那么

画AB目的达到!!!

这叫负负得正!!!

结果还真显示正常了。
修改方法就是,SPI改回原来的直接写一行

void ILI9341_DrawLineOne(u16 y,u16* data)
{int i=0;ILI9341_Address_Set(0,y,240,y);//设置光标位置 GPIO_DATA();//写数据tls_spi_write((uint8_t *)data,480);}

再把调色板的高低位对调

/*-------------------------------------------------------------------*/
/*  Palette data                                                     */
/*-------------------------------------------------------------------*/
WORD NesPalette[64]={#if 00x738E,0x20D1,0x0015,0x4013,0x880E,0xA802,0xA000,0x7840,0x4140,0x0200,0x0280,0x01C2,0x19CB,0x0000,0x0000,0x0000,0xBDD7,0x039D,0x21DD,0x801E,0xB817,0xE00B,0xD940,0xCA41,0x8B80,0x0480,0x0540,0x0487,0x0411,0x0000,0x0000,0x0000,0xFFDF,0x3DDF,0x5C9F,0x445F,0xF3DF,0xFB96,0xFB8C,0xFCC7,0xF5C7,0x8682,0x4EC9,0x5FD3,0x075B,0x0000,0x0000,0x0000,0xFFDF,0xAF1F,0xC69F,0xD65F,0xFE1F,0xFE1B,0xFDD6,0xFED5,0xFF14,0xE7D4,0xAF97,0xB7D9,0x9FDE,0x0000,0x0000,0x0000,
#else0x8E73,0xD120,0x1500,0x1340,0x0E88,0x02A8,0x00A0,0x4078,0x4041,0x0002,0x8002,0xC201,0xCB19,0x0000,0x0000,0x0000,0xD7BD,0x9D03,0xDD21,0x1E80,0x17B8,0x0BE0,0x40D9,0x41CA,0x808B,0x8004,0x4005,0x8704,0x1104,0x0000,0x0000,0x0000,0xDFFF,0xDF3D,0x9F5C,0x5F44,0xDFF3,0x96FB,0x8CFB,0xC7FC,0xC7F5,0x8286,0xC94E,0xD35F,0x5B07,0x0000,0x0000,0x0000,0xDFFF,0x1FAF,0x9FC6,0x5FD6,0x1FFE,0x1BFE,0xD6FD,0xD5FE,0x14FF,0xD4E7,0x97AF,0xD9B7,0xDE9F,0x0000,0x0000,0x0000,
#endif
};

我还真是个天才

刷新速率

这个还是在研究中

结束语

年前工作最后一天,其实对放假也没有什么渴望,听说教主和按住了北鼻离婚了,可能是有人劝说他们中一个,这样的人,不离婚留着过年吗?希望别再因为家产打官司上热搜,看够了这些人了。

单片机---HLK-W801移植Nes模拟器(二)相关推荐

  1. 单片机开发---ESP32S3移植NES模拟器(二)

    书接上文 <单片机开发-ESP32-S3模块上手> <单片机开发-ESP32S3移植lvgl+触摸屏> <单片机开发-ESP32S3移植NES模拟器(一)> 暖场视 ...

  2. 单片机开发---ESP32S3移植NES模拟器(一)

    书接上文 <单片机开发-ESP32-S3模块上手> <单片机开发-ESP32S3移植lvgl+触摸屏> 参考内容 依旧是参考韦东山老师的作品来移植的 <ESP32|爷青回 ...

  3. 构建一个轻量级的嵌入式虚拟平台,开发工程用板stm32 picoc解释器,大量自定义函数,sarm拓展,lwip移植,nes模拟器移植,系统优化,等等技术的融合

    让嵌入式想java一样一处编写到处运行 第一次写博客,其实接触嵌入式已经快两年了,从开始学51单片机的时候,怀着满腔的热情.写出了点亮第一个流水灯代码的时候那个无比的激动,到后面自己做许多有趣的东西( ...

  4. V3S移植nes游戏模拟器(附带游戏合集)

    V3S移植nes游戏模拟器(附带游戏合集) 1.资源准备: nes源码 alsa源码(本文采用buildroot已编译好的alsa库 编译该库可参考mplayer那篇文章,也可自行编译) 可以使用音频 ...

  5. iMX6ULL应用移植 | 移植 infoNES 模拟器(重玩经典NES游戏)

    没玩过NES游戏的童年,可能不是80后的童年.我们小时候是从玩FC开始接触游戏机的,那时真的是红极一时啊,我上初中时还省吃俭用买了一台小霸王,暑假里把电视机都给打爆了!那时任天堂单是FC机的主机的发售 ...

  6. uCOS-II在51单片机上的移植

    uCOS-II在51单片机上的移植 约定:文中所写的硬件堆栈或系统堆栈是指51单片机SP指针所指向的堆栈空间,而用户堆栈或任务堆栈是指用来保存任务状态为每个任务分配的堆栈空间. 前一段时间一直在学习U ...

  7. SimpleFOC移植STM32(二)—— 开环控制

    目录 注意事项 一.硬件介绍 1.1.硬件准备 1.1.1.SimpleMotor方案 1.1.2.SimpleFOCShield V2.0.3方案 1.2.硬件连接 1.2.1.原理图 1.2.2. ...

  8. 单片机软件常用设计分享(二)驱动设计之LED灯显示设计

    单片机软件常用设计分享(二)驱动设计之LED灯显示设计 前言 <驱动设计–LED灯显示驱动> 一.LED灯工作方式 1.常亮 2.常灭 3.闪烁 4.间歇性闪烁 二.LED灯驱动数据结构 ...

  9. 给手机安装NES模拟器,游戏无限玩

    MTK平台手机安装MRP的NES游戏模拟器教程和软件曾经的我们,在玩红白机(小霸王)上经典游戏的时候,经常会因为那些技术娴熟的人如同行云流水般的动作而表现出惊叹和钦佩之情.时光匆匆,游戏界的一代骄子如 ...

  10. 基于keil环境下mm32f327单片机rtthread的移植

    基于keil环境下mm32f327单片机rtthread的移植 文章目录 基于keil环境下mm32f327单片机rtthread的移植 前言 一.所需资源 二.创建工程目录 三.复制所需文件到相应文 ...

最新文章

  1. 多类SVM的损失函数
  2. 混合云计算应用中小企业市场前景看好
  3. 中缀转后缀表达式并求值
  4. 扬州工业机器人外壳设计排名_工业交换机的外壳设计重要吗?
  5. sklearn 中的线性回归、岭回归、Lasso回归参数配置及示例
  6. Xcode12快捷键配置
  7. python入门系列:对象引用、垃圾回收、可变性
  8. 魅族15系统是android,魅族15系列评测:性能够用王者荣耀优化
  9. 从还珠格格到街头霸王!80后的怀旧神器 三星GalaxyFold另类体验
  10. JDK自带的Timer类
  11. (26)基于cookie的登陆认证(写入cookie、删除cookie、登陆后所有域下的网页都可访问、登陆成功跳转至用户开始访问的页面、使用装饰器完成所有页面的登陆认证)...
  12. 解决Maven项目pom文件中出现的错误:Missing artifact oracle:ojdbc7:jar:12.1.0.2.0:compile
  13. OpenGL纹理叠加基础知识
  14. 千峰JAVA逆战班Day32
  15. matplotlib中添加水平线和垂直线
  16. 《思考力---引爆无限潜能》书摘(二)
  17. 华为服务器维修报告,服务器运维报告
  18. Linux磁盘空间进行扩容--增大卷组空间
  19. 给exe文件签名,避免杀毒软件扫描
  20. mixamo动画批量添加根骨骼与将动作处理成原地动作(blender)

热门文章

  1. 贝塔自助授权系统php源码,贝塔自助授权系统v1.1
  2. panic recovered, err: runtime error: invalid memory address or nil pointer dereference 怎么排查问题
  3. Xcode 8 的新功能一览
  4. Failed to initialize NVML 长效解决方法
  5. 程序员快收藏:国内一二线城市的互联网公司汇总
  6. 【冬瓜哥论文】浅析固态介质在存储系统中的应用方式
  7. pug安装与使用教程
  8. css3动画按钮_CSS3的动画按钮
  9. 为什么摇滚的人害羞_并非每个人都需要成为摇滚明星
  10. android popWindow组件微信式实现(较完整版)