如何做一部基于STM32F4的手持式游戏机

发布时间:2023-10-09  

这是在Hackster.io上发布的一个项目,基于STM32F4 Discovery板制作的游戏机。采用编写游戏的方式来学习嵌入式系统是比较好的方式,寓教于乐,培养成就感,并不需要学习完模电、数电就可以编程。


下面是这个项目的硬件部分,主要的器件:


一个STM32F4 Discovery板

一个3.2寸、320*240分辨率、带触摸的TFT LCD显示屏(ILI9341为控制器)

一个2轴游戏手柄

单通道2.5W D类音频放大器

一只4ohm,3W的喇叭

两个按键

其它电阻、二极管若干

原理图:

关于游戏手柄及按键的功能定义参见原文 - 点击左下角的“阅读原文”即可到达,在这里不再赘述。

下面是板子的正面和背面器件布局示意图:

下图为软件模块的构成及调用关系

下图为数据流:

游戏手柄在两个方向的变化通过其内部两个独立的可变电阻来实现,电阻的改变以变化的电压送到控制器的12位精度的ADC,变换后的数据以40Hz的频度被控制器的游戏引擎读取。

下面是游戏的流程图:

ISR的程序:

void TIM6_DAC_IRQHandler (void){ TIM_intrpt_handler(TIM6); frameUpdate = SET;}

前景:

int main (void){ RTE_init(); RTE_display_start_screen(); while(SHOOT_BUTTON_READ); while(1){ RTE_display_black_background(); RTE_create_player_spaceship(&PlayerSpaceship); RTE_draw_player_spaceship(&PlayerSpaceship); RTE_create_asteroid(&AsteroidVect,Asteroid,numOfAsteroidInWave[currentWa ve],&PlayerSpaceship); RTE_draw_asteroid(&AsteroidVect); RNG_deinit(); RTE_start_update_frame(); while(1){ if(frameUpdate == SET){ RTE_display_score(); RTE_update_player_spaceship(&PlayerSpaceship); RTE_draw_player_spaceship(&PlayerSpaceship); RTE_create_rocket(&RocketVect,Rocket,&PlayerSpaceship); RTE_update_rocket(&RocketVect,&AsteroidVect); RTE_draw_rocket(&RocketVect); RTE_update_asteroid(&AsteroidVect,&PlayerSpaceship); RTE_draw_asteroid(&AsteroidVect); if(PlayerSpaceship.Object_Property.aliveFlag == RTE_ALIVE_FALSE){ PROTOBOARD_GREEN_LED_ON; RTE_display_game_over_screen(); while(SHOOT_BUTTON_READ); RTE_reset_game(); PROTOBOARD_GREEN_LED_OFF; break; } if(AsteroidVect.total == 0){ TIM_ctr(TIM6,STOP); currentWave++; RNG_init(); RTE_create_asteroid(&AsteroidVect,Asteroid,numOfAsteroidInWave[currentWave],&PlayerSpaceship); TIM_ctr(TIM6,START); } frameUpdate = CLEAR; } } }}

第二个周期性的中断产生DAC需要的数据,以产生相应的音频效果:

#ifdef SPEAKER_USE_TIMER7 void TIM7_IRQHandler (void){ TIM_intrpt_handler(TIM7); DAC_write(&DACxHandle,*(soundPtrGlobal++)); if(soundPtrGlobal == soundEnd){ speaker_stop_sound(); } }#endif

创建特殊的空间维度:

/***********************************************************************Private function: Wrap coordinate***********************************************************************/void RTE_wrap_cordinate (int16_t *xPtr, int16_t *yPtr){ if (*xPtr < 0){ *xPtr += ILI9341_config.width; } if (*xPtr >= ILI9341_config.width){ *xPtr -= ILI9341_config.width; } if (*yPtr < 0){ *yPtr += ILI9341_config.height; } if (*yPtr >= ILI9341_config.height){ *yPtr -= ILI9341_config.height; }}

下面的示意 - 右边慢慢消失,出现在左侧

下面的代码就是在左侧重画出图像中右侧消失掉的部分:

/***********************************************************************External function: Overwrite draw pixel function in ILI9341 driver library (in order to draw pixels going off screen)***********************************************************************/void ILI9341_draw_pixel (int16_t x, int16_t y, uint16_t color){ RTE_wrap_cordinate(&x,&y); ILI9341_set_active_area(x,x,y,y); ILI9341_send_command(ILI9341_MEM_WRITE); ILI9341_send_parameter_16_bits(color);}

碰撞检测:

/***********************************************************************Private function: Detect collision between 2 object using AABB algorithm***********************************************************************/uint8_t RTE_collision_detect (Space_Object_t *Object1Ptr, Space_Object_t *Object2Ptr){ int16_t Obj1BottomRight_X = Object1Ptr->Object_Property.x + Object1Ptr->Object_Image.imageWidth; int16_t Obj1BottomRight_Y = Object1Ptr->Object_Property.y + Object1Ptr->Object_Image.imageHeight; int16_t Obj2BottomRight_X = Object2Ptr->Object_Property.x + Object2Ptr->Obje ct_Image.imageWidth; int16_t Obj2BottomRight_Y = Object2Ptr->Object_Property.y + Object2Ptr->Object_Image.imageHeight; if (Object1Ptr->Object_Property.x < Obj2BottomRight_X && Object2Ptr->Object_Property.x < Obj1BottomRight_X && Object1Ptr->Object_Property.y < Obj2BottomRight_Y && Object2Ptr->Object_Property.y < Obj1BottomRight_Y){ return RTE_COLLISION_TRUE; } return RTE_COLLISION_FALSE;}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    奇怪的双界面手持设备名为 DS,并提出“蓝海策略”。有别于和竞争者 Sony、微软正面冲突,任天堂将开拓出一个独树一帜的市场空间。当时,由于游戏机变得越来越复杂,而 DS 和他......
    是当前主流的高清视频接口,广泛应用于智能电视、机顶盒、投影仪等影音设备。对于大部分家庭来说,电视至少需要一个HDMI端口来连接电视盒子、DVD播放器或游戏机等设备。 图源......
    如何做一部基于STM32F4的手持式游戏机;这是在Hackster.io上发布的一个项目,基于STM32F4 Discovery板制作的游戏机。采用编写游戏的方式来学习嵌入式系统是比较好的方式,寓教......
    ,切换比较方便。 如果没有SD卡,也想体验也可以,直接把游戏取模成二进制放在数组里存放到STM32的FLASH里即可,STM32F103ZET6有512K的FLASH,存放一个游戏......
    iQOO 12首发电竞芯片Q1:率先实现游戏内超分插帧并发; 11月2日消息,iQOO宣布iQOO 12首发搭载自研电竞Q1,率先实现行业内首个游戏内的超分和插帧并发。 据悉,自研......
    跟其他玩家交流经验,当知道他是一个大爷后,很多人都说佩服。 他说,自从玩了这个游戏之后,自己的反应能力和注意力也提高了,平时服用的药物也减了量,感觉病都好多了。 在游戏中,Аман Алашбаев更有一个......
    数和 AMD 最新的 Zen 4 核心的使用。一个六核处理器应该足以满足掌上游戏的需求,而且 Ryzen Z1 处理器肯定会胜过为 Valve 的 Steam Deck 提供动力的 AMD 较旧......
    新引入生活质量提升功能,包括改进的定居点存储管理、扩展前哨配送系统、优化的村民行为,以及在单人和合作模式中练习战斗技能的能力等等。观看颂钟长鸣更新预告片: 和   蜗牛游戏的旗舰生存游戏方舟系列的多个游戏......
    针对某个问题的任何训练就能发现新算法。 深度思维研究团队将寻找更优排序算法的任务编成了一个游戏,并训练“阿尔法开发”来玩这个游戏。通过玩这个游戏,“阿尔法开发”发现了超越当前最先进算法的排序算法。这次新发现的排序算法中有一些已与C++库的......
    使接上了外置电源也会出现越充越少的现象,还有不少用户希望用USB-C为自己的游戏电脑供电。 因为现阶段USB-C接口理论上最高只能以5V20A的PD制式供应120W电源,USB-C为游戏......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>