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

这篇具有很好参考价值的文章主要介绍了单片机开发---ESP32S3移植NES模拟器(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

书接上文

《单片机开发—ESP32-S3模块上手》
《单片机开发—ESP32S3移植lvgl+触摸屏》
《单片机开发—ESP32S3移植NES模拟器(一)》

暖场视频,小时候称这个为—超级曲线射门!!!!!!!!!!

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

ESP32上天使之翼游戏

继续优化

看门狗

源码中有两处看门狗的喂狗操作,前期都被注释掉了。
单片机开发---ESP32S3移植NES模拟器(二)
因为开始经常出现看门狗报警的重启。然后我将看门狗都关闭之后就不再重启了
单片机开发---ESP32S3移植NES模拟器(二)
问题如果不再出现,那它还是问题吗
单片机开发---ESP32S3移植NES模拟器(二)

分区表

前面如果需要使用分区存储rom数据的时候,需要使用定制的分区表
在(Top) → Partition Table → Partition Table 配置下,选择第四项
单片机开发---ESP32S3移植NES模拟器(二)
根目录下放置文件,内容如下
单片机开发---ESP32S3移植NES模拟器(二)
如果直接用内存,就不需要修改这些。
如果有多个应用的话,可以在这里选择配置,从不同位置启动程序。

I2S声音输出

有了声音,才能更好的玩游戏
单片机开发---ESP32S3移植NES模拟器(二)

所以又斥资购买的外置模块,接线图如下

单片机开发---ESP32S3移植NES模拟器(二)
I2S有3个主要信号,各种叫法,反正就这个意思

各种昵称 说明
SCLK 、BCLK 串行时钟SCLK,也叫位时钟(BCLK),即对应数字音频的每一位数据,SCLK都有1个脉冲。SCLK的频率=2×采样频率×采样位数。
LRCK、LRC、WS 帧时钟LRCK,(也称WS),用于切换左右声道的数据。LRCK为“1”表示正在传输的是右声道的数据,为“0”则表示正在传输的是左声道的数据。LRCK的频率等于采样频率。
SDATA、DIN 串行数据SDATA,就是用二进制补码表示的音频数据。

增加了声音的驱动,将原来写在一起的部分分离开,方便以后移植。

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s.h"
#include "driver/gpio.h"
#include "esp_system.h"
#include "esp_log.h"
#include <math.h>
#include "drv_pin.h"
#include "drv_sound.h"

#if CONFIG_SOUND_ENABLED

void sound_init(void)
{
    i2s_config_t i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_TX ,
        .sample_rate = AUDIO_SAMPLERATE,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
        .communication_format = I2S_COMM_FORMAT_I2S_MSB,
        .dma_buf_count = 8,
        .dma_buf_len = 64,
        .use_apll = false,
        .intr_alloc_flags = ESP_INTR_FLAG_INTRDISABLED   //Interrupt level 1
    };
    i2s_pin_config_t pin_config = {
        .mck_io_num = I2S_PIN_NO_CHANGE,
        .bck_io_num = I2S_BCK_IO,
        .ws_io_num = I2S_WS_IO,
        .data_out_num = I2S_DO_IO,
        .data_in_num = I2S_DI_IO    //Not used
    };
    i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
    i2s_set_pin(I2S_NUM, &pin_config);
}

void sound_send(const void *src, size_t size, size_t *bytes_written, TickType_t ticks_to_wait)
{
	i2s_write(I2S_NUM, src, size, bytes_written, ticks_to_wait);
}
void sound_stop(void)
{
	i2s_stop(I2S_NUM);
}
void sound_clear(void)
{
	i2s_zero_dma_buffer(I2S_NUM);
}
#endif

用这些函数代替之前的操作。
不过为什么波特率配置为这个44.1k的一半,还不太清楚,后续可以研究一下。

按照这样配置的时候,会有很大的杂音。需要修改一下声道。

 .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,

这里也要注意,模块电压是5V,等我回去试试电压5V是不是更好一些。
单片机开发---ESP32S3移植NES模拟器(二)

手柄适配

声音有了,还是需要用手柄玩,更贴心。
单片机开发---ESP32S3移植NES模拟器(二)

常用的九孔插头,里面有5根线有用。
单片机开发---ESP32S3移植NES模拟器(二)
七孔插头
单片机开发---ESP32S3移植NES模拟器(二)
还有一种
单片机开发---ESP32S3移植NES模拟器(二)

引脚 含义
VCC 5V供电
GND 地线
LATCH 锁存信号,由主机发送
CLOCK 时钟信号,有些文档会叫PULSE,由主机发送
DATA 串行数据线 低电平有效。

时序图
单片机开发---ESP32S3移植NES模拟器(二)
先普及个基础知识。日版美版FC主机均为NTSC制式,画面为60Hz。欧版以及中国的仿制机为PAL-D制式,50Hz。港版正规机以及某些地区是PAL-60制式,60Hz。下面的说明都是基于60Hz来解释,50Hz和60Hz时间参数有点差异。

当游戏机启动后,游戏机会每16.67ms(60Hz,1/60秒)读取一次手柄的状态。这个过程通过两个步骤来实现。

首先主机发送一个LATCH锁存信号脉冲,这个脉冲的宽度为12us。告诉手柄开始检查按键状态。

在LATCH的脉冲发送后间隔6us,CLOCK(PULSE)线开始发送周期为12us,占空比50%的脉冲信号,一共发8次。每次的脉冲的上升沿对DATA线采样,检查DATA线是否在该位置被拉低。按键被检查的顺序是固定的(游戏机设计时候设计人员固定的),按键顺序为A,B,SEL,START,上下左右。上图DATA线上标注的就是每个按键时序所在位置。如果按键被按下,那么对于位置的DATA是低电平。

这里找到了一个原理图,感觉可以自己做一个了。
单片机开发---ESP32S3移植NES模拟器(二)
单片机开发---ESP32S3移植NES模拟器(二)

引脚初始化,一定要注意上拉和下拉的使用
单片机开发---ESP32S3移植NES模拟器(二)

读取代码如下,时间可以严格按照时序图中的要求来定义,记住在上升沿的时候,读取data值。

	int b2b1 = 65535;
	
	gpio_set_level(INPUT_HW_JS1_LATCH_PIN, 1);
    ets_delay_us(12);
    gpio_set_level(INPUT_HW_JS1_LATCH_PIN, 0);
    for(int i = 0; i < 8; i++)
    {
		ets_delay_us(6);
		if(gpio_get_level(INPUT_HW_JS1_DATA_PIN) == 0)
		{
			b2b1 -= sfc_ps_button_info[i];
			//printf("%s ",sfc_ps_button_va[i]);
		}
		
        gpio_set_level(INPUT_HW_JS1_CLOCK_PIN, 1);
		ets_delay_us(6);
        gpio_set_level(INPUT_HW_JS1_CLOCK_PIN, 0);
    }

一定要注意,这种手柄的电压,至少要达到4.8V,否则可能出现如下问题
1.延迟必须增大才能读取按键
2.在读取按键的时候,一次如果按下超过两个按键,就会识别为全部按下。

这也是我灵光一现,才破解了这个问题。
单片机开发---ESP32S3移植NES模拟器(二)

双手柄支持

这里需要重新增加一个手柄
单片机开发---ESP32S3移植NES模拟器(二)

void osd_getinput2(void)
{
	// Note: These are in the order of PSX controller bitmasks (see psxcontroller.c)
	const int ev[16] = 
	{
		event_joypad2_select, 
		0, 
		0, 
		event_joypad2_start, 
		event_joypad2_up, 
		event_joypad2_right, 
		event_joypad2_down, 
		event_joypad2_left,
		0, 
		0, 
		0, 
		0, 
		0, 
		event_joypad2_a, 
		event_joypad2_b, 
		0
	};
	
	static int oldb = 0xffff;
	int b = input2_read();
	int chg = b ^ oldb;
	int x;
	oldb = b;
	event_t evh;
	//	printf("Input: %x\n", b);
	for (x = 0; x < 16; x++)
	{
		if (chg & 1)
		{
			evh = event_get(ev[x]);
			if (evh)
				evh((b & 1) ? INP_STATE_BREAK : INP_STATE_MAKE);
		}
		chg >>= 1;
		b >>= 1;
	}
}

主要就是注意选择事件。不过改归改,还么测试
单片机开发---ESP32S3移植NES模拟器(二)

游戏名称

注意复制到SD卡中的游戏,名字不能过长,否则会出现死机的问题,导致重启。
另外可以增加如下判断,只显示rom名称,屏蔽其他文件
单片机开发---ESP32S3移植NES模拟器(二)
这个后续可以替换成其他界面,毕竟连汉字都不支持,低端
单片机开发---ESP32S3移植NES模拟器(二)

游戏兼容性

测试了一些过关游戏,基本都可以,不过在测试一些智能卡的游戏的时候,会出现重启现象,打印输出

GUI: Mapper 74 not yet implemented

因为本身模拟器支持的mapper有限,并没有支持到74号,这个游戏就是《天使之翼》,
还有164号mapper,游戏是《三国志2》。

后续一定要解决这个问题,加上mapper。
至于这个mapper是什么

mapper,这个概念来源于 memory mapping,又叫做 Memory Management Chip,它是解决地址映射的一种电路,简单来说就是决定物理内存如何映射到 CPU 或者 PPU 的地址空间。
mapper 可以用来支持增加卡带的 RAM 甚至支持额外的音频通道,但更一般的目的就是控制物理内存到地址空间的映射,突破游戏 40KB 的限制。
为什么说是 40KB 的限制,因为早期一般的游戏最大就是 的 PRG,以及 的 CHR,加起来就是 40KB,而更复杂的 mapper 硬件可以使得游戏突破这个限制。

软件重启

增加了手柄远端重启机器,其实就是在按键的时候判断一下,如果同时按下select和start,重启设备
单片机开发---ESP32S3移植NES模拟器(二)
这样测试就比较方便了。

效果展示

冒险岛系列
单片机开发---ESP32S3移植NES模拟器(二)
赤色要塞
单片机开发---ESP32S3移植NES模拟器(二)

热血系列,这么激烈打斗的游戏,非常流畅。单片机开发---ESP32S3移植NES模拟器(二)
快打旋风
单片机开发---ESP32S3移植NES模拟器(二)
激龟忍者传视频

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

ESP32S3-nes上的《激龟忍者传3》

参考资料

《FC游戏机手柄工作原理 》
《小霸王游戏机手柄(一)——硬件破解》
《NES 模拟器开发教程》
《童年神机小霸王(七) Mapper》
这篇文章的作者写了几篇相关的介绍,感兴趣的可以学习一下。
单片机开发---ESP32S3移植NES模拟器(二)

结束语

这个83年推出的产品,到现在快四十年了,承载了无数80后的儿童时光,几年玩的游戏加起来,估计也没有几十兆的空间,里面的技术可想而知,把硬件软件的性能压榨到了极点了。
单片机开发---ESP32S3移植NES模拟器(二)

最近这chatGPT很火,国内外各种模仿争相出现,国内的还是老样子,不该问的别问。救媳妇还是救妈妈,豆腐脑吃甜的还是辣的,是吧
单片机开发---ESP32S3移植NES模拟器(二)

反正豆腐脑我吃咸的。
单片机开发---ESP32S3移植NES模拟器(二)文章来源地址https://www.toymoban.com/news/detail-406121.html

到了这里,关于单片机开发---ESP32S3移植NES模拟器(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ESP32单片机入门篇

    目录 一、ESP32单片机的基本概念 1.双核架构 2. Wi-Fi和蓝牙功能 3. 集成多种外设 4. 支持多种操作系统 二、开发环境 1. Arduino IDE 2. ESP-IDF 三、开发语言 四、注意事项 五、代码例程 (1)点亮LED灯 1. 电路图 2. 代码 3. 代码注释 4. 注意事项 (2)控制继电器 1. 电路图 2. 代码 3. 代码

    2024年02月08日
    浏览(55)
  • FreeRTOS_Stm32F103系列单片机标准库移植

    链接:FreeRTOS 下面的教程是基于从github下载压缩包进行的,最好下载这个或者直接看3.1,从我百度网盘下载。如果是别的下载源也问题不大,大同小异。 此时我们需要下载以下两个仓库, 点进去按下面的步骤下载就行了,另一个也是这样下。 链接: FreeRTOS官网 打开链接我们

    2024年01月22日
    浏览(53)
  • POWERLINK协议在stm32单片机+w5500移植成功经验分享

    连续折腾了多个晚上,又趁周末又花了一天时间,终于把powerlink协议移植成功到单片机上啦。本想放弃,但想了下不管我能不能用上,结个尾吧,分享给有需要的人。放弃并不难,但坚持一定很酷。为了移植测试这个协议花了不少血本。stm32开发板就买了两套,其中第一套板

    2024年02月09日
    浏览(60)
  • 单片机项目分享 单片机(stm32)远程智能宠物喂养系统 - 物联网 esp8266

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月19日
    浏览(67)
  • STM32 -- 实现按键的长按与短按检测(其他单片机可移植)

    目录 资源获取 一 前言 二 思路  三 实现代码 1.主要代码 四 完整代码 Key.h Key.c 该改进版本(1ms太繁琐了,我改成了25ms检测一次)   1.定时器部分 2.按键检测部分  五、参考 欢迎关注微信公众号--星之援工作室 发送(长短按检测) 今天在逛博客的时候,偶然看到了一

    2024年02月12日
    浏览(40)
  • esp32单片机在arduino环境下,串口接收解码

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 当主控芯片发送一串数据,但此数据为一串字符串,需要将此字符串翻译成整型数组,以形成指令,控制串口屏。 例如:esp32单

    2024年02月09日
    浏览(46)
  • esp32单片机在arduino环境下,WIF联网

    文章目录 系列文章目录 前言 一、WIFI是什么? 二、使用步骤 1.引入库 2.读入数据 总结 随着人工智能的不断发展,物联网这门技术也越来越重要,很多人都开启了物联网学习,本文就介绍了物联网WIFI模块的基础内容。 WIFI在中文里又称作\\\"行动热点\\\",是 Wi-Fi联盟 制造商的商标

    2024年02月15日
    浏览(56)
  • 【Arduino环境下驱动合宙esp32c3单片机基本外设】

    本教程是参加FastBond2活动主题4 - 测量仪器中的【Arduino环境下驱动合宙esp32c3单片机基本外设】。 围绕FastBond2阶段1——基于ESP32C3开发的简易IO调试设备项目需求开发。 设计目标: 多种数字和模拟信号的输入输出:用户可以选择不同的输入输出模式,并通过设备的操作界面进行

    2024年02月04日
    浏览(60)
  • STM32+esp8266实现单片机与服务器的WiFi通信

             源码已上传至gitee: stm32: 一些stm32模块使用经验记录 - Gitee.com https://gitee.com/lrf1125962926/stm32/tree/esp8266wifi%E9%80%9A%E4%BF%A1/         本实验采用STM32F1系列+esp8266 01s模块,采用HAL库开发。主控芯片哪个系列和型号都可以,只要有两个串口(UART或者USART,以下统称串口)

    2024年02月07日
    浏览(61)
  • ESP32单片机使用DHT11温湿度传感器的实践与代码解析

    摘要:本文将介绍如何使用ESP32单片机与温湿度传感器进行连接和数据读取。通过实例代码的解析,帮助读者了解实现温湿度检测的原理和方法。 一、引言 ESP32是一款功能强大的微控制器,广泛应用于物联网、智能家居等领域。在许多应用场景中,温湿度传感器是不可或缺的

    2024年02月21日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包