HaaS100除了在物聯網領域可以大顯身手外,還有哪些可能的玩法呢?今天就帶大家一起尋找童年的記憶,打造一臺復古街機,最終完工圖如下圖:

接下來我們分三個步驟來進行打造:
- LCD及游戲手柄硬體接線
- 驅動開發
- 游戲開發
1、接線配置
1.1、LCD模塊
我們采用了2.4寸彩色LCD螢屏,解析度320*240,該螢屏使用SPI串口總線,因此使用較小的引腳數量就可以實作驅動,

具體的接線配置如下,大家可以參考LCD模塊上的絲印以及HaaS100開發板的引腳配置來完成接線,如果想要修改該引腳配置,請記得在代碼中也進行更改嗷,
更多HaaS100的硬體規格請參考 https://help.aliyun.com/document_detail/184186.html?spm=a2c4g.11186623.6.642.7fd815815Xe5iP

1.2、🎮模塊
游戲拓展模塊采用的是Arduino的硬體生態,該游戲模塊具備了一個搖桿以及4顆按鍵,足夠適配大量街機游戲(街機經典配置),由于該模塊沒有具體的絲印,所以請開發者們參考下圖的接線方式,使用標注的引腳進行連接,這么有意思的一款模塊在以下地址購買:https://item.taobao.com/item.htm?spm=a1z09.2.0.0.3e082e8ddu5BB8&id=35422379433&_u=f1tg6s600889

2、驅動開發
2.1、 LCD模塊
LCD模塊與HaaS100的通訊方式為SPI,因此這里采用SPI0進行通訊,對于SPI0及相關GPIO的配置如下:
// 硬體SPI0 最高通訊速度26MHz
spi_ili9341.port = 0;
spi_ili9341.config.mode = SPI_WORK_MODE_3; // CPOL = 1; CPHA = 1
spi_ili9341.config.freq = 26000000;
spi_ili9341.config.role = SPI_ROLE_MASTER;
spi_ili9341.config.firstbit = SPI_FIRSTBIT_MSB;
spi_ili9341.config.t_mode = SPI_TRANSFER_NORMAL;
spi_ili9341.config.serial_len = 8;
spi_ili9341.config.data_size = SPI_DATA_SIZE_8BIT;
spi_ili9341.config.cs = SPI_CS_EN;
// Data/Cmd引腳 用于切換發送指令或是資料
gpio_ili9341_dc.port = ILI9341_DC_PIN;
gpio_ili9341_dc.config = OUTPUT_PUSH_PULL;
gpio_ili9341_dc.priv = NULL;
// 復位引腳
gpio_ili9341_reset.port = ILI9341_RESET_PIN;
gpio_ili9341_reset.config = OUTPUT_PUSH_PULL;
gpio_ili9341_reset.priv = NULL;
我們在驅動檔案中已經實作了多種繪圖函式,開發者可以直接使用這些繪圖函式來進行更多有意思的開發,
void (*lcd_frame_draw)(uint32_t *frame);
void (*lcd_area_draw)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t *frame, uint32_t areaSize);
void (*lcd_line_draw)(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t color);
void (*lcd_rect_draw)(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t borderWidth, uint32_t color);
void (*lcd_fill_rect_draw)(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t color);
void (*lcd_circle_draw)(uint16_t x, uint16_t y, uint16_t r, uint16_t borderWidth, uint32_t color);
void (*lcd_fill_circle_draw)(uint16_t x, uint16_t y, uint16_t r, uint32_t color);
2.2、🎮模塊
該模塊包含 搖桿 及 按鍵 兩部分,
搖桿的結構是兩個相互垂直的彈性電位器,當用戶操作搖桿時,即引發電位器的阻值變動,進而改變觀測點輸出的電壓,因此只需要使用ADC采集觀測點的電壓值,便能夠得到搖桿的位置資訊,

ADC的讀取方法如下,需要注意的是,在每次 hal_adc_value_get 之前, 都需要進行 hal_adc_init ,才能進行有效地資料讀取,
hal_adc_init(&roll_X);
hal_adc_init(&roll_Y);
hal_adc_value_get(&roll_X, &roll_X_value, 5);
hal_adc_value_get(&roll_Y, &roll_Y_value, 5);
按鍵采用中斷檢測的方式,對于每個按鍵設定上升沿觸發中斷,并在中斷函式中完成鍵值的變換,
int game_key_init()
{
int ret = 0;
int key_num = straight; // 在這里填鍵值
key_Y.port = 33;
key_Y.config = IRQ_MODE;
ret |= hal_gpio_init(&key_Y);
// 上升沿觸發中斷函式 game_key_irq_fun, 同時傳入鍵值
ret |= hal_gpio_enable_irq(&key_Y, IRQ_TRIGGER_RISING_EDGE, game_key_irq_fun, key_num);
return ret;
}
void game_key_irq_fun(int key_num)
{
// do your things here
printf("key %d down\n", key_num);
}
3、游戲開發
3.1、SDL多媒體庫移植
單獨寫一個游戲很麻煩,怎么樣可以玩更多的游戲呢?這里就給大家介紹一個多媒體庫SDL,Why use SDL?用官方的話來講——“因為它是一個跨平臺的多媒體庫,提供了多種控制影像、聲音、和輸入設備的函式,可以讓游戲開發者專注于游戲本身”,這里為了幫你找回童年記憶,AliOS Things已經將SDL移植進來,



SDL移植后的代碼在:
./components/utility/SDL,
將底層LCD驅動和遙桿驅動適配到SDL,驅動適配的邏輯參考:
./components/utility/SDL2/src/video/alios/SDL_AliOS_framebuffer.c
./components/utility/SDL2/src/video/alios/SDL_AliOS_video.c
AOS_APP_GAME_DEMO宏定義相關代碼,
3.2、俄羅斯方塊游戲移植
基于SDL的開源游戲在市面上已經非常多,在github上搜一搜一大把,當然我們先來一個經典俄羅斯方塊試試水https://github.com/andwn/sdl2-tetris,代碼已經移植好,你可以在AliOS Things的github倉庫中找到游戲demo,

4、游戲燒錄
游戲中涉及到字體,在編譯代碼前先將字體檔案拷貝到預編譯目錄:
$cp application/example/game_demo/sdl2-tetris/data/DejaVuSerif.ttf ./platform/mcu/haas1000/prebuild/data/
編譯game demo:
$aos make game_demo@haas100 -c config
$aos make
燒錄以下兩個檔案:
參考燒錄方法鏈接
./out/wificamera_demo@haas100/binary/wificamera_demo@haas100.bin
./platform/mcu/haas1000/release/write_flash_gui/ota_bin/littlefs.bin
5、小結
到此為止,俄羅斯方塊玩起來了,如果覺得還不過癮,一起來嘗試移植其他的SDL游戲,找找童年的感覺,是不是很有意義呀,期待您的杰作,
如需更多技術支持,可加入釘釘開發者群

更多技術與解決方案介紹,請訪問阿里云AIoT首頁https://iot.aliyun.com/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/243238.html
標籤:其他
上一篇:使用opencv-python快速讀取視頻——進階版
下一篇:我的2020作業與學習總結
