基于ARM9的贪吃蛇游戏.docx
- 文档编号:29793678
- 上传时间:2023-07-27
- 格式:DOCX
- 页数:41
- 大小:125.55KB
基于ARM9的贪吃蛇游戏.docx
《基于ARM9的贪吃蛇游戏.docx》由会员分享,可在线阅读,更多相关《基于ARM9的贪吃蛇游戏.docx(41页珍藏版)》请在冰豆网上搜索。
基于ARM9的贪吃蛇游戏
基于ARM9的贪吃蛇游戏
摘要
本课程设计是使用我们学习过的嵌入式系统的有关知识,在ARM9嵌入式硬件开发平台和μC/OS-II的软件开发框架下,实现一个还有AD转换,按键,LCD等硬件功能的实时多任务的简单贪吃蛇的设计。
文中首先μC/OSII系统和ARM9进行了介绍,然后对设计要求进行分析,给出了系统总体上设计,并对各个功能模块进行了介绍,紧接着给出了系统软件设计,最后介绍了系统的调试方法和测试结果。
关键词:
μC/OSARM9嵌入式贪吃蛇
一开发环境简介
1、μC/OS-II操作系统
μC/OS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统内核。
它被广泛应用于微处理器、微控制器和数字信号处理器。
uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。
没有提供输入输出管理,文件系统,网络等额外的服务。
但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全可以由用户自己根据需要分别实现。
uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等
μC/OS-II是专门为计算机的嵌入式应用设计的,绝大部分代码是用C语言编写的。
CPU硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU上。
μC/OS-II中最多可以支持64个任务,分别对应优先级0~63,其中0为最高优先级。
63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个,每个任务都有不同的优先级,用户在创建任务的时候定义该任务的优先级。
μC/OS操作系统中每个任务可以有5种状态:
休眠态、就绪态、运行态、等待或挂起状态、中断态,在任一个时候,任务的状态一定是这5种状态之一。
任务在等待消息、邮箱或者信号量等事件的到来的时候会进入挂起状态,当任务接到消息以后,则处于就绪状态。
uC/OS-II的时间管理是通过定时中断来实现的,该定时中断一般为10毫秒或100毫秒发生一次,时间频率取决于用户对硬件系统的定时器编程来实现。
中断发生的时间间隔是固定不变的,该中断也成为一个时钟节拍。
uC/OS-II要求用户在定时中断的服务程序中,调用系统提供的与时钟节拍相关的系统函数,例如中断级的任务切换函数,系统时间函数。
在ANSIC中是使用malloc和free两个函数来动态分配和释放内存。
但在嵌入式实时系统中,多次这样的操作会导致内存碎片,且由于内存管理算法的原因,malloc和free的执行时间也是不确定。
uC/OS-II中把连续的大块内存按分区管理。
每个分区中包含整数个大小相同的内存块,但不同分区之间的内存块大小可以不同。
用户需要动态分配内存时,系统选择一个适当的分区,按块来分配内存。
释放内存时将该块放回它以前所属的分区,这样能有效解决碎片问题,同时执行时间也是固定的。
对一个多任务的操作系统来说,任务间的通信和同步是必不可少的。
uC/OS-II中提供了4种同步对象,分别是信号量,邮箱,消息队列和事件。
所有这些同步对象都有创建,等待,发送,查询的接口用于实现进程间的通信和同步。
uC/OS-II采用的是可剥夺型实时多任务内核。
可剥夺型的实时内核在任何时候都运行就绪了的最高优先级的任务。
uC/os-II的任务调度是完全基于任务优先级的抢占式调度,也就是最高优先级的任务一旦处于就绪状态,则立即抢占正在运行的低优先级任务的处理器资源。
为了简化系统设计,uC/OS-II规定所有任务的优先级不同,因为任务的优先级也同时唯一标志了该任务本身。
随着信息化技术的发展和数字化产品的普及,以计算机技术、芯片技术和软件技术为核心的嵌入式系统再度成为当前研究和应用的热点。
对功能、可靠性、成本、体积和功耗严格要求的嵌入式系统一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以及用户的应用程序等四个部分组成,其中嵌入式微处理器和嵌入式操作系统分别是其硬件和软件的核心。
ARM处理器由于其具有小体积、低功耗、低成本、高性能等特点,广泛应用在16/32位嵌入式RISC解决方案中,几乎占有嵌入式微处理器市场分额的75%,本文选定三星公司生产的一款基于ARM920T核的高性能低功耗SOC芯片S3C2410作为移植方案的硬件平台。
市场上主流的嵌入式实时操作系统有Vxworks、pSos、WinCE、Linux等,基于实时性、成本以及开发难度方面的考虑,我们选择uC/OSII——开放源代码的嵌入式实时操作系统。
采用基于ARM9的S3C2410嵌入式微处理器,可以使系统具备高性能的运算能力的同时便于与各种外设连接扩展,简化了硬件设计,维持小型化的同时降低了系统成本。
uC/OSII作为一个源代码公开的操作系统,在具体应用中稳定可靠,并且支持uIPTCP/IP协议栈、ucGUI等,可扩展性强,功能强大。
本系统采ARM9+uC/OSII开发设计,具有精度高、运行稳定、实时性好、抗干扰能力强、性价比高的特点,可以在各种工业场合中广泛应用,达到了设计的初衷。
2、试验箱基本硬件信息
1.S3C2410-SCore小板:
采用S3C2410X处理器,64MNANDFLASH64RAM。
2.Double100MEtherNet网卡:
均由AX88796构成,采用现有电路但分配不同地址。
3.4HOST/1DEVICEUSB接口:
主USB口扩展为4个,由AT43301构成USBHUB,其中电源管理用MIC2525。
USB从口保持处理器本身的1个。
4.3UART/IrDA:
保持2个RS232串口,增加1个RS485串口,1个IrDA收发器,均从处理器的UART2引出。
5.168PinEXPORT:
有一个168Pin扩展卡插槽,并去掉已经被主板上各模块占用的资源。
网卡部分还在局部总线上,其余电路包括168Pin扩展槽都在外部总线。
6.LCD:
兼容多种LCD,可采用5寸256色屏或8寸16bit真彩屏,同时预留一个24bit接口。
可以支持板外8bit或24bit屏。
7.TouchScr:
采用ADS7843,预备了直接用2410内部ADC构成的转换电路接口
8.AUDIO:
采用UDA1341,具有放音、录音等功能。
9.PS2KEYPAD:
使用ATMEGA8单片机控制2个PS2接口和板载17键小键盘。
两个PS2可接PC键盘和鼠标。
10.LED:
使用ZLG7290只驱动8只小数码管。
同时可作IIC总线实验。
11.POWERSUPPLY、RESET、RTC等必须资源。
12.ADC:
板载3个电位器和选择跳线,同时在板上设模拟电压输入专用接口。
13.IDE/CF卡插座:
支持2.5英尺的笔记本硬盘读写和IDE模式下的CF卡读写。
14.PCMCIA和SD卡插座:
由EPM3128A100CPLD实现。
15.IC卡插座。
由ATMEGA8单片机控制。
16.DC/STEP电机。
步进电机采用74HC573扩展IO,软件形成时序来控制。
同时剩余IO可以控制CAN等电路,以节省CPU的GPIO资源。
17.CANBUS:
设置1个CAN口,采用MCP2510和TJA1050。
18.DoubleDA:
设置两个DAC端口,采用MAX504接SPI总线。
19.GPRS/GPS扩展板不做在主板上,单独设计扩展板。
注意GPS的RS232需要增加MAX3232芯片来转换为TTL才能引到168Pin插座上。
3、ADS1.2集成开发环境
ADS1.2ADS是ARM公司的集成开发环境,他的功能非常强大。
ADS包括了四个模块分别是:
SIMULATOR;C编译器;实时调试器;应用函数库。
ADS1.2提供完整的WINDOWS界面开发环境。
C编译器效率极高,支持c以及c++,使工程师可以很方便的使用C语言进行开发。
提供软件模拟仿真功能,使没有Emulators的学习者也能够熟悉ARM的指令系统。
配合FFT-ICE使用,ADS1.2提供强大的实时调试跟踪功能,片内运行情况尽在掌握。
ADS1.2需要硬件支持才能发挥强大功能。
目前支持的硬件调试器有Multi-ICE以及兼容Multi-ICE的调试工具如FFT-ICE。
ADS由命令行开发工具,ARM实时库,GUI开发环境(CodeWarrior和AXD),适用程序和支持软件组成。
有了这些部件,用户就可以为ARM系列的RISC处理器编写和调试自己的开发应用程序了。
二系统设计要求
贪吃蛇游戏是一款经典的小游戏,它的原型是1976年,Gremlin平台推出了一款经典街机游戏Blockade。
真正走红的是该游戏随诺基亚手机走向世界。
本课程设计有关贪吃蛇的功能描述:
1、可以通过嵌入式平台的键盘控制游戏,键盘中起作用的是方向键(2,4,6,8)和回车键,方向键控制蛇的上下左右运动,回车键控制游戏的继续和暂停。
2、贪吃蛇由若干连续黄色方块构成,程序中随机出现一些“食物”(用蓝色的方块表示),贪吃蛇通过吃“食物”增加自身的长度并增加相应的分值。
3、游戏分三个关口,第一关没有障碍物,第二关有2个障碍物,第三关有四个障碍物。
4、贪吃蛇撞到矩形边界,障碍物或者自己身体的一部分,游戏即结束,重新开始。
5、为了增加难度,加入AD转换器用于控制蛇的运动速度,这也是本设计的创新点。
6、贪吃蛇每吃一个食物分数会增加,屏幕上显示得分和游戏所用时间。
三系统总体设计
本设计需要创建两个任务,系统结构框图如图3-1所示,任务状态切换如图3-2所示。
具体的任务流程和任务所要完成的功能如下:
在系统启动后,同时创建两个任务,任务一main_task和任务二snake_task。
任务一主要功能是等待键盘消息,有键盘消息的时候判断是什么键盘,并对相应的变量重新赋值。
任务二主要功能是控制并在屏幕上显示蛇的移动和速度,并完
图3-1系统结构框图
图3-2任务切换框图
图3-3系统主任务流程框图
成对分数,游戏等级和其他相关参数的记录和显示。
任务一为主任务,在创建任务的时候,赋给它的优先级别比任务二高,所以任务一优先运行,任务二处于就绪状态,因为任务一主要是等待键盘消息,在无键盘消息的时候,任务一被挂起,这时候任务二进入运行状态。
1、任务一程序流程框图
如图3-3所示,该任务完成对键盘消息的接收,识别,并改变相应变量
2、任务二流程图:
如图3-4所示,主要功能是控制蛇的速度并在屏幕上显示蛇的移动,并完成对分数、游戏等级、和游戏用时的记录和显示。
四系统具体功能的实现
1初始化
初始化包括了硬件初始化和软件初始化。
硬件初始化主要有AD转换器的初始化,LCD的初始化,串口初始化,ARM目标板的初始化等,软件初始化包括了系统初始化,游戏初始化。
系统初始化包括了任务的建立,信号量的创建,变量的创建,系统文件初始化,初始化绘图设备上下文,系统实时时钟的初始化和函数的声明等,游戏的初始化,包括了有关参数属性的初始化化和游戏界面的初始化。
硬件初始化:
#defineADCCON_FLAG(0x1<<15)
#defineADCCON_ENABLE_START_BYREAD(0x1<<1)
#definerADCCON(*(volatileunsigned*)0x58000000)
#definerADCDAT0(*(volatileunsigned*)0x5800000C)
#definePRSCVL(49<<6)
#defineADCCON_ENABLE_START(0x1)
#defineSTDBM(0x0<<2)
图3-4游戏任务流程图
#definePRSCEN(0x1<<14)
ARMTargetInit();
voidinit_ADdevice()
{//初始化
rADCCON=(PRSCVL|ADCCON_ENABLE_START|STDBM|PRSCEN);
}
OSInitUart()
软件初始化
1)系统初始化
initOSMessage();
initOSDC();
LoadFont();
OSTaskCreate(Main_Task,(void*)0,(OS_STK*)&Main_Stack[STACKSIZE-1],Main_Task_Prio);
OSTaskCreate(Snake_Task,(void*)0,(OS_STK*)&Snake_Stack[STACKSIZE-1],Snake_Task_Prio);
LCD_ChangeMode(DspGraMode);
OSStart();
enumWN_Type{
TP_Space,
TP_Block,
TP_Cake,
TP_SkBody,//SnakeBody
TP_SkHead,
TP_SkTail
};
enumDirection{Up=0,Down=1,Left=2,Right=3};
2)游戏初始化
游戏的初始化将LCD屏幕以等大小的方块进行划分,并定义每个方块的属性,边框和障碍物的属性相同,还有蛇头的属性,蛇身的属性,蛇尾的属性,食物的属性,空白方块的属性。
并调用绘图上下文设备完成游戏界面的初始化,显示关口,得分和时间。
同时产生随机产生食物。
MoveTo(pdc,20,440);
LineTo(pdc,620,440);
MoveTo(pdc,20,480);
LineTo(pdc,620,480);
MoveTo(pdc,220,440);
LineTo(pdc,220,480);
MoveTo(pdc,420,440);
LineTo(pdc,420,480);
strChar2Unicode(text1,"NO.:
1000201036Name:
ChenZhePing");
TextOut(pdc,20,420,text1,TRUE,FONTSIZE_MIDDLE);
//SnakeHead
xNode=&WorldArray[W_YSize/2][W_XSize/2-1];
xNode->Type=TP_SkHead;
xNode->isBlock=1;
HeadNode=xNode;
UpdateNextNode(xNode,Left);
xNode->PreDir=Left;
//SnakeBody
xNode=&WorldArray[W_YSize/2][W_XSize/2];
xNode->Type=TP_SkBody;
xNode->isBlock=1;
UpdateNextNode(xNode,Left);
xNode->PreDir=Left;
//SnakeTail
xNode=&WorldArray[W_YSize/2][W_XSize/2+1];
xNode->Type=TP_SkTail;
xNode->isBlock=1;
TailNode=xNode;
UpdateNextNode(xNode,Left);
xNode->PreDir=Left;
RandCake();
2判断蛇是否吃到食物
判断蛇是否吃到食物的方法比较简单,只要判断蛇头的属性是否和下一个节点的属性一样。
吃到食物后改变响应的游戏参数,并要让蛇的节数多三节,这时候要让变量lenadd加3,并且还要对蛇补画上一节,本设计采用补上蛇头的方法,要注意根据此时蛇的运动方向来确定新蛇头的坐标。
,以后食物产生子程序能够判断食物已经被蛇“吃到”了,要重新产生食物。
if(HeadNode->Type==TP_Cake)
{
score++;
if(score==5)
flag1=1;
else
if(score==10)
flag2=1;
LenToAdd+=CakeLength;
RandCake();
}
3判断游戏是否结束
(1)蛇头撞到蛇身
判断蛇是否撞到蛇身的方法可以从蛇头开始依次开始判断蛇头的属性是否和下一个方块的属性相同,一样的话即表明蛇撞到蛇身了,此时游戏结束。
(2)蛇头撞到游戏界面边框
判断蛇是否撞到边框的方法,只要比较蛇头的属性是不是同时边框的属性一样,一样的话,即表明蛇撞到边框,游戏结束。
If(HeadNode->isBlock)
{
nRet=1;//HitaBlock
gotoSnakeStep_End;
}
4蛇移动功能
这部分功能是游戏的主体,实现蛇移动的方式是首先擦除蛇尾,擦除的方发是改变蛇尾的属性,通过调用绘图上下文设备,蛇尾就变成白色底色不可见,然后从蛇尾开始,依次改变下一个节点的属性。
例如刚开始蛇是5节,这时候依次把第2四节的属性给第1节;把第3节(即蛇头)的属性给第2节;把第4四节的属性给第3节;把第4节(即蛇头)的属性给第3节;把第5节(即蛇头)的属性给第4节。
擦除蛇尾和转移坐标这两个顺序不能颠倒。
这时候蛇头的属性和第4节的属性是一样的,这时候需要判断蛇的方向变量的值,根据蛇的方向变量的值补画上蛇头。
If(LenToAdd!
=0)
{
LenToAdd--;
}
else
{
TailNode->Type=TP_Space;
TailNode->IsBlock=0;
DrawPoint(TailNode);//oldtail
TailNode=TailNode->Next;
TailNode->Type=TP_SkTail;
DrawPoint(TailNode);//newtail
}
HeadNode->Type=TP_SkBody;//oldhead
DrawPoint(HeadNode);
HeadNode->Next->PreDir=HeadNode->Dir;//savepredir
HeadNode=HeadNode->Next;//newhead
5食物的产生
食物的产生主要要注意食物产生之前,我们必须要判断画面上面是已经存在食物,如有已经存在食物了,就不再产生食物,如果食物被蛇吃到了,那就要重新画上食物。
本设计是通过在每次吃完食物后调用随机产生食物函数,另外还要保证食物不能超出蛇的活动界面,并要保证食物能被蛇吃到,所以需要指定食物坐标的范围,被通过舍去食物坐标个位的方法保证食物坐标是整十,这样就能被蛇吃到。
本设计用一个矩形方框来代表食物,所以通过上面介绍的方法产生食物坐标后,对应在该坐标的位置画上一个矩形方框。
voidRandCake(void)
{
//Getanewrandcakeposition
INT32Ux,y;
While
(1)
{
X=rand()%W_XSize;
Y=rand()%W_YSize;
if(!
WorldArray[y][x].isBlock)
break;
}
CakeNode=&WorldArray[y][x];
CakeNode->Type=TP_Cake;
DrawPoint(CakeNode);
}
5、监听键盘动作:
任务通过等待消息而处于挂起状态,当任务接到消息以后,则处于就绪状态,然后开始判断所接受到的这个消息是不是需要处理,如果是执行相应的处理函数,最后,删除所接收到的消息,继续挂起等待下一条消息。
voidMain_Task(void*Id)
{
POSMSGpMsg=0;//定义消息结构
ClearScreen();//清屏
WorldSem=OSSemCreate
(1);
GameRun=OSSemCreate
(1);
Pdc=CreateDC();
SetLCDUpdata(pdc,FALSE);
//消息循环
For(;;)
{
pMsg=WaitMessage(0);//等待消息
switch(pMsg->Message)
{
caseOSM_KEY:
//键盘消息
onKey(pMsg->WParam,pMsg->LParam);
break;
}
DeleteMessage(pMsg);//删除消息
}
DestoryDC(pdc);
}
6AD控制蛇速度
在每次蛇前进一步后,通过刷新LCD屏幕来显示画面和相关参数,紧接着占用系统信号量,占用的时间是同过当前游戏的关口和调用AD采样函数来确定的额,游戏关口越高,蛇的前进速度越快,AD采样值越小,蛇的前进速度越快。
OSTimeDly(GetSpeed(gamelevel));
INT32SGetSpeed(U8level)
{intADData;
U16lastData;
ADData=GetADresult(0);
lastData=ADData*3.3*50/1023;
if(level==1)return300+lastData;
else
{
if(level==2)return200+lastData;
elsereturn100+lastData;
}
}
四程序下载与调试
1、把程序下载到试验箱中:
(1)执行菜单Project|Make对工程进行编译连接。
在出现的错误/警告窗口中选择某错误/警告信息,ADS会自动打开相应源文件并用箭头指向出错的文本行。
如果某个源文件被修改,重新编译时ADS会自动同步各文件的日期信息。
(2)在ADS中执行菜单Project|Debug启动ADS1.2的调试工具AXD。
(3)在AXD中执行菜单Options|ConfigureTarget对AXD进行设置。
选择ADP即远程调试,点Configure按钮进一步设置具体参数。
(4)点Select按钮选择远程连接为ARMethernetdriver,点Configure按
钮输入仿真器的IP地址。
如果用户使用的是并行口仿真器,请输入127.0.0.1即可。
(5)等待程序装载完毕以后,通过Execute|Go菜单以及Execute|Stop(或者工具栏中
的相应按钮)运行或暂停程序。
程序暂停后在窗口中将显示出程序暂停的位置。
(6)通过Execute|Step菜单(或者工具栏中的相应按钮)可以单步运行程序。
也可以
使用StepIn、StepOut菜单命令进入或者跳出函数的调用。
RunToCursor命令运行到光标位置。
(7)程序停止后可以通过ProcessorViews|Sources菜单查看源文件,并可在适当位置
按F9设置端点。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 ARM9 贪吃 游戏
![提示](https://static.bdocx.com/images/bang_tan.gif)