此项目是基于STM32F103的一款嵌入式系统学习/控制平台移植了一款贪吃蛇游戏。
游戏规则如下:
平台右边四个键代表着左、右、上、下的四个方向,按动这四个方向键就可以控制贪吃蛇游动,使贪吃蛇的头部吃到出现的食物块,吃到食物之后贪吃蛇的长度会变长,移动速度也会变快。在游戏过程中,撞到墙或者是碰到自己身体,也就代表着游戏失败,会结束本局游戏进入新一局游戏的准备界面。
STM32F103特点:
(1)它是基于STM32F103的,虽然是很古老的芯片,我们也可以称之为经典,对于初学者来讲非常合适 - 网上乌央乌央的资料、视频乃至各个出版社出的书,还有无数前辈们做的应用案例,所以学习起来应该毫无压力;
(2)它搭配了一个240 * 240的LCD彩屏,仍然使用了SPI总线,虽然慢,也是我们故意选了个慢的,这样你才会想尽办法让屏幕显示快起来,而且SPI是你必须要掌握的总线,不会软件写SPI的程序,那还叫嵌入式编程?有了这个屏幕和4个按键,就有了一个很好的“人机接口”,你可以控制它,还可以看到控制后的反馈。在几乎任何电子系统中按键和显示都不可缺少的今天,用好这块屏幕、学会通过按键操作菜单也是基本功;
(3)除了LCD显示屏/按键支持信息的输入/输出之外,我们还搭配了一个麦克风输入电路(模拟放大、滤波电路)和一个蜂鸣器输出的功能,声音信号的处理是非常重要的一个课题,可繁可简。我们的这个Mic信号是模拟的,有10倍的增益,放大处理后的信号送给STM32F103的ADC进行采样,因此你可以用这一路信号做一个简单的示波器玩,即便手头没有其它的信号源,仍然可以通过音乐的播放或说话在LCD屏幕上进行波形和频谱的显示;
(4)物联网时代怎么能没有传感器呢?因此大家熟知的MPU6050就必然地放在板子上,除它之外还放置了一个环境光传感器,两颗传感器在板上,你可以玩的东西就比较多了;
(5)安装了一个SD卡,它可以为你提供音乐(做成音乐播放器)、图片(做成数码相框)、还可以为你移植一个小型的操作系统练习文件系统的编写和使用;
(6)板上除了有兼容树莓派生态的40Pin双排插针外,还有一个4Pin的I2C单排插针和支持4路模拟输入的6Pin的单排插针,在练习DIY示波器的项目的时候,除了可以用板上的Mic电路以外,你也可以接外部的模拟信号输入,做成多通道的示波器或电压表等;
(7)我们选用了USB-C给这个板子供电、调试、烧录程序。
STM32F103嵌入式平台移植游戏思路:
在编译平台进行贪吃蛇游戏的代码编辑:制作游戏地图、生成蛇的初始位置、食物的位置自动随机生成、让蛇定时自动前进、前进过程中遇到障碍物(撞墙或者撞到身体)游戏结束、按键可以控制蛇的走位、蛇可以吃到食物且自身长度加一移动速度也加快;将游戏移植到 STM32F103学习平台并且需要解决按键检测、地图大小、蜂鸣器音效等问题。
相关主函数代码:
int main(void)
{
i=0,j=0,t=0;
delay_init();
LED_Init();
LCD_Init();
Key_Init();
BUZZER_Init();
i2c_GPIO_Config();
MPU6050_Init();
LED=0;
LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
while(1)
{
start();
snake_init();
while(1){
LcdOutput();
BUZZER_BEEP1();
snake_delay();
ori_check();
if(ori==4){
eat=0;
front++;
if((snake[front-1]%1000)+1>47){GG();break;}
snake[front]=((snake[front-1]/1000)*1000)+((snake[front-1]%1000)+1);
if(bgg[snake[front]/1000][snake[front]%1000]==2){GG();break;}
if(bgg[snake[front]/1000][snake[front]%1000]==3){foodFlag=0;eat=1;score++;}
bgg[snake[front]/1000][snake[front]%1000]=2;
if(eat==0){
bgg[snake[tail]/1000][snake[tail]%1000]=0;
if(lcd_origin==1)LCD_ShowString((snake[tail]/1000)*5,(snake[tail]%1000)*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==2)LCD_ShowString((snake[tail]%1000)*5,(48-(snake[tail]/1000))*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==3)LCD_ShowString((48-(snake[tail]/1000))*5,(48-(snake[tail]%1000))*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==4)LCD_ShowString((48-(snake[tail]%1000))*5,((snake[tail]/1000))*5,"$",WHITE,WHITE,16,0);
tail++;
}
}
if(ori==3){
eat=0;
front++;
if((snake[front-1]%1000)-1<0){GG();break;}
snake[front]=((snake[front-1]/1000)*1000)+((snake[front-1]%1000)-1);
if(bgg[snake[front]/1000][snake[front]%1000]==2){GG();break;}
if(bgg[snake[front]/1000][snake[front]%1000]==3){foodFlag=0;eat=1;score++;}
bgg[snake[front]/1000][snake[front]%1000]=2;
if(eat==0){
bgg[snake[tail]/1000][snake[tail]%1000]=0;
if(lcd_origin==1)LCD_ShowString((snake[tail]/1000)*5,(snake[tail]%1000)*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==2)LCD_ShowString((snake[tail]%1000)*5,(48-(snake[tail]/1000))*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==3)LCD_ShowString((48-(snake[tail]/1000))*5,(48-(snake[tail]%1000))*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==4)LCD_ShowString((48-(snake[tail]%1000))*5,((snake[tail]/1000))*5,"$",WHITE,WHITE,16,0);
tail++;
}
}
if(ori==2){
eat=0;
front++;
if((snake[front-1]/1000)+1>47){GG();break;}
snake[front]=(((snake[front-1]/1000)+1)*1000)+(snake[front-1]%1000);
if(bgg[snake[front]/1000][snake[front]%1000]==2){GG();break;}
if(bgg[snake[front]/1000][snake[front]%1000]==3){foodFlag=0;eat=1;score++;}
bgg[snake[front]/1000][snake[front]%1000]=2;
if(eat==0){
bgg[snake[tail]/1000][snake[tail]%1000]=0;
if(lcd_origin==1)LCD_ShowString((snake[tail]/1000)*5,(snake[tail]%1000)*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==2)LCD_ShowString((snake[tail]%1000)*5,(48-(snake[tail]/1000))*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==3)LCD_ShowString((48-(snake[tail]/1000))*5,(48-(snake[tail]%1000))*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==4)LCD_ShowString((48-(snake[tail]%1000))*5,((snake[tail]/1000))*5,"$",WHITE,WHITE,16,0);
tail++;
}
}
if(ori==1){
eat=0;
front++;
if((snake[front-1]/1000)-1<0){GG();break;}
snake[front]=(((snake[front-1]/1000)-1)*1000)+(snake[front-1]%1000);
if(bgg[snake[front]/1000][snake[front]%1000]==2){GG();break;}
if(bgg[snake[front]/1000][snake[front]%1000]==3){foodFlag=0;eat=1;score++;}
bgg[snake[front]/1000][snake[front]%1000]=2;
if(eat==0){
bgg[snake[tail]/1000][snake[tail]%1000]=0;
if(lcd_origin==1)LCD_ShowString((snake[tail]/1000)*5,(snake[tail]%1000)*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==2)LCD_ShowString((snake[tail]%1000)*5,(48-(snake[tail]/1000))*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==3)LCD_ShowString((48-(snake[tail]/1000))*5,(48-(snake[tail]%1000))*5,"$",WHITE,WHITE,16,0);
else if(lcd_origin==4)LCD_ShowString((48-(snake[tail]%1000))*5,((snake[tail]/1000))*5,"$",WHITE,WHITE,16,0);
tail++;
}
}
if(!foodFlag)food();
if(front==240)Cqueue();
}
}
}