前集回顾
单片机—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_UP
tls_gpio_cfg(GPIO_UP, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);
#endif
#ifdef GPIO_DOWN
tls_gpio_cfg(GPIO_DOWN, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);
#endif
……
#ifdef GPIO_B
tls_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)
{
up_key = 0;
}
else if(keybuf_UP == 0XFF)
{
up_key = 1;
}
}
#endif
}
最后通过变量up_key ,通知到模拟器。模拟器通过以下函数,循环扫描按键变化
void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )
三个参数分别是1P,2P以及开关机按钮,默认的注释
这里还是以上键作为例子
#define PAD_JOY_UP 0x10
*pdwPad1 = 0;
#ifdef GPIO_UP
if(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);
}
再把调色板的高低位对调
WORD NesPalette[64]={
#if 0
0x738E,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,
#else
0x8E73,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
};
我还真是个天才
刷新速率
这个还是在研究中
结束语
年前工作最后一天,其实对放假也没有什么渴望,听说教主和按住了北鼻离婚了,可能是有人劝说他们中一个,这样的人,不离婚留着过年吗?希望别再因为家产打官司上热搜,看够了这些人了。
|