单片机---HLK-W801移植Nes模拟器(二)
總目錄
《單片機—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改回原來的直接寫一行
再把調色板的高低位對調
/*-------------------------------------------------------------------*/ /* 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模拟器(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 判断浏览器类型 (区分IE浏览器)
- 下一篇: Java 跨平台获取 MAC 地址的两种
