STM32传感器模块编程实践(十八)DIY电子游戏机模型

文章目录

一.概要

做一个基于STM32的电子游戏机,其意义远不止是"焊一块电路板让它跑起来"。在技术学习、产品思维和个人成长等多个维度上,它都是一个具有很高价值的综合性实践项目。

本文就做一个STM32电子游戏机模型,采用STM32F103C8T6单片机+1.8寸液晶+6个独立按键。按键实现动作输入,液晶实现游戏内容显示,目前实现了贪吃蛇,俄罗斯方块,王牌飞行员飞机游戏。

二.实验模型原理

1.硬件连接原理框图

模型主要分为三部分:主芯片单元,按键输入单元,液晶显示单元。

图中主控芯片为STM32F103C8T6单片机,按键输入单元为6个按键,液晶显示单元为1.8寸TFT液晶显示。

信号线连接:6个按键接到单片机的PB6,PB7,PB8,PB9,PB12,PB13的引脚。液晶显示模块接单片机的PA5,PA7引脚,采用SPI通讯方式。

2.各个传感器模块控制原理

按键输入原理

单片机的PB6,PB7,PB8,PB9,PB12,PB13引脚都配置成GPIO输入上拉,按键按下,对应的引脚就会接地,能读到低电平,通过外部中断下降沿触发,从而判断对应的按键是否被按下。

1.8寸TFT原理

TFT-LCD,全称Thin Film Transistor Liquid Crystal Display,即薄膜晶体管液晶显示器,是多数液晶显示器的一种,使用薄膜晶体管技术改善影象品质。它在液晶显示屏的每一个像素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。TFT-LCD 也被叫做真彩液晶显示器。

1.8寸TFT LCD彩屏是128x160像素的分辨率,我们可以理解为:水平方向分布了128个像素点,垂直方向分布了160个像素点。我们在画点的时候坐标Y的取值为0-159,坐标X的取值为0-127。

下图红色箭头的方向就是坐标递增的方向。

PCtoLCD2002 是专业的取字模软件,采用C语言和汇编语言两种格式,支持逐行、逐列、行列、列行四种取模方式,可以选择字体、大小、文字的长宽,自动生成你想要的字符,能生成字符字模,中文字模。

软件只需要几步就能轻松生成字符

三.电子游戏机程序

复制代码
单片机板子与按键连接:
板子B9-----按键UP
板子B8-----按键DOWN
板子B6-----按键LEFT
板子B7-----按键RIGHT
板子B12----按键EXIT
板子B13----按键START

单片机板子与TFT液晶连接:
板子3.3V------VCC
板子G----------GND
板子A5---------SCL
板子A7---------SDA
板子A2---------RES
板子A1---------DC
板子A4---------CS
板子A0---------BL	

打开STM32CubeMX软件,新建工程

Part Number处输入STM32F103C8,再双击就创建新的工程

配置下载口引脚

配置外部晶振引脚

配置系统主频

PB6,PB7,PB8,PB9,PB12,PB13配成中断输入,而且是上拉,因为要读取按键的低电平信号。

外部中断使能

PA0,PA1,PA2,PA4配置成输出,用于驱动液晶的RES,CS,DC等引脚。

配置SPI1使能,PA5为SPI的SCK引脚,PA7为SPI的MOSI引脚。

配置工程文件名,保存路径,KEIL5工程输出方式

生成工程

用Keil5打开工程

添加代码

添加显示LCD显示驱动,添加俄罗斯方块文件。

main函数中调用显示与俄罗斯方块文件。

按键信息与游戏界面融合。

主要程序:

c 复制代码
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
	LCD_Init();//LCD初始化
	LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
	Game_Init();// 游戏初始化
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
			Game_Run();//游戏运行
  }
  /* USER CODE END 3 */
}
// 游戏初始化
void Game_Init(void)
{
    // 初始化随机种子
    srand(HAL_GetTick());
    
    // 初始化游戏状态
    game.state = GAME_START_SCREEN;
    game.score = 0;
    game.high_score = 0;  // 实际项目中可以从EEPROM读取
    game.level = 1;
    game.lines_cleared = 0;
    game.fall_speed = 100;  // 初始下落速度100ms
    game.last_fall_time = 0;
    game.last_move_time = 0;
    game.game_over_flag = 0;
    game.pause_flag = 0;
    game.FirstStartFlag=0;
    // 清空游戏板
    for(int y = 0; y < BOARD_HEIGHT; y++) {
        for(int x = 0; x < BOARD_WIDTH; x++) {
            game.board[y][x] = 0;
        }
    }
    
    // 生成第一个和下一个方块
    Game_GenerateNextPiece();
    Game_SpawnPiece();
    Game_GenerateNextPiece();
}
// 游戏主循环
void Game_Run(void)
{
    static uint32_t last_update_time = 0;
    uint32_t current_time = HAL_GetTick();
    
    switch(game.state) {
        case GAME_START_SCREEN:
            Game_DrawStartScreen();
            Game_ProcessInput();
            break;
            
        case GAME_PLAYING:
            // 每500ms更新一次游戏逻辑
            if(current_time - last_update_time >= 500) {
                Game_ProcessInput();
							if(game.fall_speed==0)
							{
								Game_Update();
								Game_Update();
							}else
							{
								Game_Update();
							}
							
                Game_Draw();
                last_update_time = current_time;
            }
            break;
            
        case GAME_PAUSED:
            Game_DrawPauseScreen();
            Game_ProcessInput();
            break;
            
        case GAME_OVER:
            Game_DrawGameOverScreen();
            Game_ProcessInput();
            break;
            
        default:
            break;
    }
}
// 绘制游戏
void Game_Draw(void)
{
    Game_DrawBoard();//绘制边框
    Game_DrawCurrentPiece();//绘制当前方块
    Game_DrawNextPiece();//绘制下一个方块
    Game_DrawUI();//绘制分数
}

四.实验效果视频

STM32单片机游戏机

五.小结

在升学或求职时,这个项目的价值往往超乎想象:

面试中的谈资:相比那些千篇一律的跟随式项目,一个亲手打造的、完整的电子游戏机,能让你在面试官面前清晰地讲述"遇到了什么问题、怎么解决的、最后效果如何"。这种项目闭环能力是很多企业看重的。

综合解决问题的能力:调试硬件的玄学问题(比如按键抖动、屏幕花屏)、解决编译器的报错、优化内存占用......这些过程中锻炼出的耐心和排查问题的思路,是光靠看书刷题无法获得的。

相关推荐
古译汉书2 小时前
【IoT死磕系列】Day 3:学习HTTP!实战:STM32手写GET请求获取天气实战(附源码+八股文)
数据结构·stm32·物联网·网络协议·学习·算法·http
風清掦3 小时前
【江科大STM32学习笔记-06】TIM 定时器 - 6.2 定时器的输出比较功能
笔记·stm32·单片机·嵌入式硬件·学习
2023自学中5 小时前
笔记本电脑 连接 手机WIFI,开发板网线连接笔记本,开发板 和 虚拟机 同时上网
linux·单片机·嵌入式硬件·tcp/ip
uran11 小时前
从电磁兼容到代码优化:STM32 GPIO速度与EMI的隐秘关联
stm32·gpio·emc·嵌入式优化
想放学的刺客11 小时前
整理了120道单片机嵌入式面试题与答案,覆盖了硬件电路和C语言等核心领域。
c语言·c++·stm32·单片机·嵌入式硬件·mcu·51单片机
Decksweeper11 小时前
【大一做毕设?十二天四人从零开始手搓智能小车!(基于rdk x5、stm32与yolo v5,小车可实现巡线,避障,识别与夹取特定物块)】
stm32·嵌入式硬件·yolo·课程设计
回不去的bug11 小时前
【STM32】玩转IIC之驱动MPU6050及姿态解算
stm32·单片机·嵌入式硬件·mpu6050
weixin_11223311 小时前
基于单片机的塑料厂房气体检测系统设计
单片机·嵌入式硬件
沐欣工作室_lvyiyi14 小时前
基于单片机的电力系统中多路报警显示装置(论文+源码)
单片机·毕业设计·报警装置