- 选择平台及基础设置
- 选择项目模板(在此代码上进行修改和研究)
- 游戏编写
- 按键检测
- 游戏移植
- 蜂鸣器
- mpu6050与姿态
- 设置不同姿态的屏幕效果
- 最终整合
(以上为个人完成项目的步骤,下面将根据上面列举的每个序号进行较为详细的说明,文档对应硬禾学堂寒假一起练(5))
1.这个项目的起始,自然是选择一个编写代码的平台,由于我在学校的社团中以及对Keil5进行了初步的学习,所以这次STM32项目的实现首选Keil5,并先对其下载好STM32F103的芯片包,确保其能够在板子上运行。
2.项目模板说起来好像很玄乎,其实对于这个项目而言,就是先让这个板子亮起来,我首先在朋友的帮助下决定从屏幕的相关型号入手,果然在相关网店的例程中找到了适合这次项目的代码(当然,与目前项目基本信息中的附件里的相关代码即“03-1.54IPS程序源码.zip”如出一辙,不过在附件的例程选择上,我个人推荐以“02-中景园电子1.54IPS显示屏STM32F103C8T6_SPI例程”作为模板,因为它原本适配的板子和我们的板子STM32F103R8T6相比只有引脚数量的差异,stm32相关产品命名规则可以参考附件)。
在对引脚部分进行修改(修改内容可以参考程序的lcd_init.h和lcd_init.c文件)以及调整Keil5设置中的Max Clock(调整的内容见下图)并在成功使得屏幕能够呈现样例内容。
(引脚需要修改的内容)
(lcd电路图)
3.这是项目的重要组成部分,也是最需要深刻理解代码的部分,因为需要在深刻剖析游戏组成后才能编写出。我首先是选择现在本地的Dev-C++上对于我选定的游戏——贪吃蛇进行编写(当然代码全都是C语言不能有C++否则难以移植)。我先把贪吃蛇所需要的内容剖析开来,一步一步的去实现(思考过程可以参考附件snake.txt),我所用的方式是用一个循环队列去维护蛇每个身体的坐标,每走一步都要考虑蛇头朝向,前方是空地/食物/墙/身体,并进行不同的分支判断,进而保证贪吃蛇的最基本功能——能够移动、能够吃食物并变长、碰墙会死、碰自己身体也会死。而实现走每一步的过程则是通过不断刷新屏幕、停顿和输出来达到。
4.按键检测,因为我们游戏中不是时刻都在按键的,为了避免不必要的时间浪费和增加按键的准确性按键最好利用中断来控制,来我使用的是这个EXTI外部中断/事件控制器,当然还要搭配上NVIC嵌套向量中断控制器。因为贪吃蛇的游戏特色的影响,当蛇头朝向一个方向时,朝向的方向和相对的方向所对应的按键都不会有任何操作,所以我没有进行防抖动的设计(防抖动可以避免对同一按键一次按下时多次识别),甚至将代表着相对朝向的按键放在了同一个中断里。(按键检测的中断服务函数,以改变k的方式判断按键是否已经改变)
5.移植在STM32和在PC的几个显著的区别在于:一是PC以反复刷新屏幕来达到蛇移动的目的而在STM32的屏幕中,下一帧的内容中与本帧相同的部分不需要修改,只需要每次输出有变动的地方即可,这点实际上是非常重要的,因为板子性能有限,如果一次输出内容过多很容易造成卡顿使得其效果不尽人意;
二是输出的方法不同PC可以通过printf或puts等方式输出到屏幕而STM32需要其他的输出到屏幕的函数,这就需要我研究明白模板中带着的输出函数的原理。
三是停顿时间上,PC可以直接sleep但是STM32需要通过其内部时钟来确定停顿的具体时间。
四是操作上,PC的键盘非常轻松给我们提供了操作的方式,而STM32需要我们利用这四个按键,而且最好使用中断的方式实现(我在这次项目中使用了串口的中断,具体代码可参考key.c)。
五是显示上,PC一个格子用一个字符还算是比较方便,而STM32的像素点极小影响观察,所以应当以多个像素点代表一个单元格。
这五点知晓之后,移植将会轻松很多。我的游戏在STM32的实现的秘诀是,用一个数组暗中确定蛇的位置和状态,显示内容和实际的无关,这样在后面显示屏幕旋转后的内容时会更为轻松容易。
这里附带上主函数结构的解释,详细代码可参考附件
6.蜂鸣器,该项目的板子是无源的蜂鸣器,所以如果我们需要使其发出我们所希望的声音,在引脚上我们要手动设置好点平改变的频率和持续的时间,这样才能使其发出我们希望的声音,关于这点的资料在网上可以较容易的找到,尤其推荐硬禾学堂的100步视频中的第31步,也可以参考我代码中buzzer.c的内容。
(蜂鸣器电路图)
(不同音符的频率)
7.mpu6050与姿态。关于mpu6050的使用的代码是一定要移植的,我参考的是野火的相关stm32的例程,移植起来较为轻松容易只需要改动引脚即可(当然关于I2C的原理还是很有必要了解的)。当然,这只是得到了mpu6050的角速度和加速度的原始数据而已,想要知道板子对应的姿态还需要对其进行姿态解算,这一点如果在网上搜索的话,弹出来的方法往往是两种滤波和利用DMP,这些移植起来较为复杂,改动的地方比较多,十分不便。因此我在这里采用了以加速度判断角度的方式,通过把bitch,roll,yaw角得出的方式,判断各个姿态,我在这个项目中利用自己的理解达成了对板子屏幕调整的目的(需要注意的点是,本项目的模板的显示函数上,整数只能在lcd上显示后三位,注意不要误解,否则可能无法判断好姿态)
8.其实就是屏幕转向之后,游戏的表现情况,我为了达到这一点,还特意修改了代表贪吃蛇和食物的格子,使其变成中心对称的正方形,使其表现更稳定。至于坐标的展示的变动的规律,自行在纸上画画即可轻松找到。
9.把屏幕转向效果和姿态结果结合,这一点就比较容易了,只需要在每一步处理前看看姿态有没有变动,然后每次行为都考虑一下姿态就好了。
最后,感谢硬禾学堂给了我参加这次活动,提高自己的机会,自己受益匪浅,十分感谢!