嵌入式系统课程设计报告.docx
- 文档编号:10400353
- 上传时间:2023-02-10
- 格式:DOCX
- 页数:23
- 大小:74.49KB
嵌入式系统课程设计报告.docx
《嵌入式系统课程设计报告.docx》由会员分享,可在线阅读,更多相关《嵌入式系统课程设计报告.docx(23页珍藏版)》请在冰豆网上搜索。
嵌入式系统课程设计报告
嵌入式系统课程设计报告
课程设计报告
俄罗斯方块游戏
班级:
vb
风格
姓名:
发的根本
教师评语:
教师签名:
2013年9月
俄罗斯方块游戏课程设计题目
本次课程设计的主要内容是通过前8次小实验中完成的任务和实现的功能,综合前面的设计方法,利用学到的LCD接口控制、中断控制以及所学的I/O控制的知识等完成本次所选课程设计实验题目----俄罗斯方块游戏,俄罗斯方块游戏是在博创UP-NETARM3000实验平台上综合应用前序课程嵌入式课程实验
主要内容中的串口、键盘、LED接口、A/D、定时器中断、LCD接口及触摸屏驱动控制等模块设计而成,其整体设计包括四个不同层次:
功能层、软件层、中间层、硬件层,实验中用到了图形库,并利用多任务嵌入式操作系统对多任务进行有效地调度。
同时通过这次课设的体会应该总结到自己在实践中的不足和欠缺的知识,及时的补充和完善个人能力,争取学到更多的知识和实践技能。
硬件:
ARM嵌入式开发平台、用于ARM7TDMI的JTAG仿真器、PC机Pentium100以上、示波器。
软件:
PC机操作系统win98、Win2000或WinXP、ARMSDT2.51或ADS1.2集成开发环境、仿真器驱动程序、超级终端通讯程序。
采用的工具方法
1.第一次实验:
俄罗斯方块游戏的需求分析与概要设计2.第二、三次实验:
相关功能模块的划分,及其设计3.第四至第六次实验:
编写各部分代码,与调试各个模块功能
进度安排4.第七次实验:
整体调试并修改BUG
5.第八、九次实验:
添加新的功能例如:
添加对应动作下的音效,调节游戏速度
1、武俊鹏、张国印、姚爱红、赵国冬,基于ARM的嵌入式系统
设计实验与实践教程,清华大学出版社2011
2、吴学智,基于ARM的嵌入式系统设计与开发,人民邮电出版社2007参考资料
1.题目
俄罗斯方块游戏
2.系统简介
俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,最初由前苏联游戏制作人AlexPajitnov制作的,无数人进入游戏编程的世界都是从编写俄罗斯方块游戏开始的,它能极大的检验一个人对开发语言、环境和基本数据结构知识的熟练程度,其设计过程涉及到如何使用图形库,如何利用多任务嵌入式操作系统对多任务进行有效地调度等内容。
本次课程设计要求开放一个简单的俄罗斯方块游戏,并达到以下基本要求:
【1】实验台上的小键盘的要求
(1)按“*”键重新开始游戏,随机产生方块并自动下落;
(2)按“/”键可以暂停游戏,再次按键开始游戏;
(3)用“8”键变换方块角度,用“4”实现左移,用“6”实现右移,用“5”实现方块加速下移;
【2】触摸屏上的功能要求
(1)按START键开始游戏,随机产生方块并自动下移。
(2)按PAUSE键可以暂停游戏,再次按键可以重新开始游戏。
(3)按T键可以转换方块角度。
(4)按L、R键实现向左移动和向右移动。
(5)按D键实现方块加速下移。
系统能够正确判断是否满行,并对已经填充满的行进行消行和计分。
以上是基本要求,我们在实现了以上的基本要求后,我们又增加了一些新的功能,首先,我们在游戏中加入了音乐,当你重新开始游戏时、或者游戏得分时、方块下落时都有不同的音乐出现,增加了趣味性。
其次,我们设置了不同的游戏级别(级别通过速度来表示),当你觉得太难或者太简单时,都可以根据你的需要通过小键盘上的按键(+、,)来调节游戏难度,使更人性化。
3.系统设计
3.1体系结构设计
游戏设计的体系结构应分为4个不同的层次:
硬件层、功能层、软件层、中间层。
整个设计需要完成在不同的层次上完成不同的设计要求。
硬件层:
选择博创UP-NETARM3000实验平台。
功能层:
在这一层上要实现俄罗斯方块游戏的应用代码、算法实现等,我们组选择了博创UP-NETARM3000的硬件实验平台,那么主要工作就主要集中在这一层次上,因为其他的层次已经由硬件平台的提供商基本实现了。
软件层:
提供用户图形几口、实现多任务调度管理、移植一个RTOS(实时操作系统),本设计是基于uC/OS这一嵌入式实时操作系统实现的。
中间层:
硬件抽象层和板级支持包,这一般由硬件平台提供商实现。
如果选择从头设计一个俄罗斯方块游戏,自己去实现硬件体系结构,还是需要考虑这一部分的,但我们组的设计不需要这一部分。
-1-
俄罗斯方块游戏设计
图形用户界面多任务管理
实时操作系统
BSP/HAL板级支持包/硬件抽象包
GPIOD/A
ARMROMA/D处理器
RAMI/O
人机交互界面
图3.1体系结构图
1)整个游戏界面的设计和控制:
设计一个左边是带有框格的游戏界面。
右边为控制和
显示的界面,控制自然是绘制按键图案通过触屏控制来实现。
显示的内容有START、
PAUSE、SCORE、LEVEL、L、R、T、D。
2)方块的移动:
通过定时器1,改变方块左右移动的地址来实现。
3)方块的变形:
可通过运用三维数组储存7个基本方块形状,采用线性代数转置的思
路改变数组的值并设定一个缓冲区储存变形数组,从而达到变形的效果。
4)方块的碰边处理:
可设定一个二维数组储存整个游戏界面的最新状态,有方块为1,
没有则为0,并在游戏界面周围填入1,通过方块地址和数组位置的转换判定数组中
的值,为0说明可走,为1则不能通过,从而实现碰边处理。
5)方块的嵌套:
与碰边原理相似,可将之前停止在界面上的方块位置对应数组中的值
赋1,再判断当前方块每一列的最后一行下是否有方块,实现方块嵌套。
6)方块的随机出现:
当方块到达最后一行或嵌套成功后停止,然后将出现下一个方块,
可通过定时器取出末尾三位实现随机性。
并在右边显示下一个方块的形状。
7)消行处理:
可通过处理界面的数组判断某一行是否都为1,若为1就执行将上一行
赋给下一行,并将第一行赋为0。
8)分数及等级的计算:
当方块到达最后一行或嵌套成功后停止分数加1分,当消一行
成功加1,当分数超过5分时等级加1。
3.2功能层模块
根据需求分析的结果,以及针对在需求分析中总结出来的具体要求,对整个功能层做出的进一步划分,如图3.2所示:
-2-
俄罗斯方块游
戏设计
游戏界面方块处理消息循环绘制
绘制API随机触摸方块接口调动动态键盘产生屏消自动绘制静态刷新消息新方息落下框架块
消行图3.2功能层模块划分碰撞与计因此我们可以将俄罗斯方块设计分为3个部分:
游戏界面绘制、消息循环和方块处理。
检测分
3.3绘图API数据结构
首先,进行游戏界面的绘制,在uC/OS-II系统环境下,绘图必须通过使用绘图设备上下文(DC)来实现。
绘图设备上下文(DC)中包括了与绘图相关的信息,比如画笔宽度、绘图的原点等。
这样在多任务的系统中,不同的任务通过不同的绘图设备上下文(DC)绘图才不会相互影响。
同时要使μC/OS,II内核能够正常工作,处理器必须满足:
处理器的C编译器能产生可重入代码,在程序中可以打开或者关闭中断,处理器支持中断,并且能产生定时中断,处理器能够容纳一定量数据的硬件堆栈以及处理器有将堆栈指针和其他CPU寄存器存储和读出到堆栈(或内存)的指令。
在移植μC/OS,II内核时,只需修改OS_CPU.H、OS_CPU_C.C、OS_CPU_A.ASM这三个文件的内容。
μC/OS,II的所有系统服务均有内核提供,内核将应用系统和底层硬件结合成一个完整的实时系统。
μC/OS,II提供的服务有:
任务调度和管理,时间管理,内存管理及任务间的通信与同步。
绘图设备上下文(DC)中包括了与绘图有关的相关信息,比如,画笔的宽度、绘图的原点等。
这样早多任务的系统中,不同任务通过不同的绘图设备上下文(DC)绘图才不会相互影响。
绘图设备上下文(DC)的结构定义如下:
typedefstruct{
intdrawPointx;
intDrawPointy;//绘图所使用的坐标点
intPenWidth;//画笔宽度
U32PenMode;//画笔模式
COLORREFPenColor;//画笔颜色
intDrawOrgx;//绘图的坐标原点位置
intDrawOrgy;
intWndOrgx;//绘图的窗口坐标位置
intWndOrgy;
intDrawRangex;//绘图的区域范围
intDrawRangey;
-3-
structRECTDrawRect;//绘图的有效范围
U8bUpdateBuffer;//是否更新后台缓冲区及显示
U32Fontcolor;//字符的颜色
}DC,*PDC;
遵照国际通用流行的俄罗斯方块游戏设计,我们把方块设计成7种(方形、长条形、7形、反7形、Z形、反Z形、T形)如下:
3.4消息循环机制
通常在多任务操作系统中,人物之间的通信是通过发送消息来实现的。
消息队列是操作系统uC-OS的一种通信机制,他可以是一个任务或者中断服务程序向另一个任务发送指针定义的变量。
程序中可以用OSCreateMessage()函数为某个控件创建消息,用SenMessage()函数将消息发送到消息队列中,用WaitMessage()函数等待消息,用DeleteMessage()函数删除消息。
消息的数据结构定义如下:
typedefstruct{
POS_CtrlpOSCtrl;
U32Message;
U32WParam;
U32LParam;
}OSMSG,*POSMSG;
3.5方块处理模块
(1)通过仔细地规划屏幕,规划出一个20行10列的游戏区域,每个小方块用10X10的像素来构成。
intBoardArray[10][20];//定义一个10x20的游戏区域
(2)标准的俄罗斯方块共有7种基本方块及其变换体有19种形式,每个形状划分为4种角度且有四个小方块组成,每个小方块的坐标由(x,y)确定,小方块的坐标的表示是根据下面的方块形状图中的方块定位点来确定的,即以方块定位为原点建立坐标系,以此来表示每个形状,所以数组定义如下:
intBlockInfo[7][4][4][2]=
{
{
{{0,0},{1,0},{0,1},{1,1}},
{{0,0},{1,0},{0,1},{1,1}},
{{0,0},{1,0},{0,1},{1,1}},
{{0,0},{1,0},{0,1},{1,1}}
}(正方形),
-4-
{
{{0,0},{-1,0},{1,0},{2,0}},
{{0,0},{0,-1},{0,1},{0,2}},
{{0,0},{-1,0},{1,0},{2,0}},
{{0,0},{0,-1},{0,1},{0,2}}
}(长方形)
......};
这里只给出正方形的和长方形的,具体见下图3.3方块形状图。
图3.3方块形状图
(3)判断方块碰撞:
先把背景比喻成大盒子,前面在给大盒子(背景)建模的时候,给大盒子的四周都围了1层1。
那我们可以这样来判断小盒子与大盒子的碰撞。
小盒子的数组与其在大盒子数组中的对应位置的值相与,显然若与后的值为1,证明大盒子与小盒子在此处的值都为1,即表明在此处发生了碰撞。
或者当小盒子的值大于大盒子的值时,表明了方块超过了大盒子边界,即表明在此处也发生了碰撞。
而在最首先背景(大盒子)中都为0,只有边界层1。
当小盒子降落到大盒子底部后,将小盒子的内容对应写入大盒子数组中(即存储该方块信息到对应的数组中),这样大盒子(背景)就得以更新。
换句话说,方块处理主要功能是不停更新方块位置。
每次更新还需判断游戏是否暂停,是否结束,是否过关,方块是否碰到下界,如果暂停则延时等待释放暂停的键盘消息,如果游戏介绍则延时等待重新游戏的消息,如果碰到下界则方块不再下移同时判断是否有某行被填满,如果填满则清除,然后产生新的方块(用rand()产生随机数,从而产生与之对应随机方块)。
(4)方块消行加分:
方块满一行自动消除,同时加一分,分数不设上限。
3.6程序流程图
经过系统设计,设计出程序流程图,如图3.4所示:
:
-5-
图3.4程序流程图
4.系统实现
4.1程序任务处理流程
主任务,它主要来完成一些初始化工作,要初始化游戏界面,必须创建一个绘图用的DC,主任务通过DC绘制游戏界面调用API函数显示相应的文字。
初始化工作完成后,主任务进入消息循环机制来等待来自键盘或触摸屏的消息,获得消息后发送到消息处理机制中。
主任务创建方式及流程图如下:
创建方式:
voidMain_Task(void*Id);
#defineMain_Task_Prio
OSTaskCreate(Main_Task,(void*)0,(OS_STK*)&Main_Stack[STACKSIZE*8-1],
Main_Task_Prio);
流程图:
-6-
定义消息循环机制
所需参数
创建绘图PDC
绘制游戏界面
进入消息循环机制
等待消息
根据触摸点位置做相应的处理:
开判断触摸点位始、暂停、左移、触屏信息右移、快速下落、置调节游戏速度
判断消
息类型
根据键值作相应的的处理:
开始、暂停、左移、右移、键盘信息判断键值快速下落、调节游
戏速度
图4.1俄罗斯方块主任务流程图
1)方块自动下落任务,主要完成当前方块的动态显示,不停的更新方块的位置,另外还要判断系统的运行状态,方块是否发生碰撞等。
自由下落任务的创建方式与流程图如下:
创建方式:
voidAutoDrop_Task(void*Id);
#defineAutoDrop_Task_Prio
OSTaskCreate(AutoDrop_Task,(void*)0,(OS_STK*)&AutoDrop_Task_Stack[STACKSIZE
-1],AutoDrop_Task_Prio);
2)键盘消息捕捉任务:
在此任务中,除了可以捕捉键盘输入信息:
方块的左、右移动,方块的快速下落,方块的变形,游戏的暂停、开始,游戏的重新启动;还可以试试调节方块下落速度:
在此由慢到快分别设置了四种不同的方块下落速度,增加游戏的趣味性与挑战性。
voidonKey(intnkey,intfnkey){
switch(nkey)
{
case0:
//动态调节游戏中方块的下落速度
delay=1000;
return;
case1:
delay=500;
return;
-7-
case2:
delay=300;
return;
case3:
delay=100;
return;
case14:
Play("1.wav");
newGame();//游戏的重新启动
Zlg7289_Reset();//zlg7289复位
return;
case15:
pause();//暂停游戏,保存
return;
case8:
moveLeft();//方块的左移动
return;
case10:
moveRight();//方块的向右移动
return;
case12:
drop();//当前方块快速落下
Play("653.wav");
return;
case9:
rotateClockwise();//实现当前方块的变形
return;
default:
//若无按键动作,跳出
return;
}
}
4.2任务的实现
1)主任务:
voidMain_Task(void*Id)
{
POSMSGpMsg;//定义消息指针
structPOINTTouch_Position,*pTouch_Position;
ButtonCtrlNewGame_Button,Pause_Button,Left_Button,
Right_Button,Down_Button,Rotate_Button;
PButtonCtrlpNewGame_Button,pPause_Button,pLeft_Button,
pRight_Button,pDown_Button,pRotate_Button;
//定义创建按钮和窗体的属性
WndMainDraw_Wnd,PieceDraw_Wnd,ScoreDraw_Wnd;
PWndpMainDraw_Wnd,pPieceDraw_Wnd,pScoreDraw_Wnd;
charNewGame_Button_Caption_8[]="Start";
charMainDraw_Wnd_Caption_8[]="MainDraw";
-8-
charScore_Caption_8[]="Score";
U16Score_Caption_16[10];
U16NewGame_Button_Caption_16[10];
pTouch_Position=&Touch_Position;
pNewGame_Button_RECT=&NewGame_Button_RECT;
//把字符转化成Unicode字符
strChar2Unicode(NewGame_Button_Caption_16,NewGame_Button_Caption_8);
strChar2Unicode(Score_Caption_16,Score_Caption_8);
//在指定的位置画图形,用坐标来定位
NewGame_Button_RECT.bottom=40;
NewGame_Button_RECT.left=180;
NewGame_Button_RECT.right=230;
NewGame_Button_RECT.top=10;
pNewGame_Button=CreateButton(NewGame_Button_ID,pNewGame_Button_RE
CT,FONTSIZE_SMALL,CTRL_STYLE_3DDOWNFRAME,
NewGame_Button_Caption_16,NULL);//创建按钮
pMainDraw_Wnd=CreateWindow(
MainDraw_Wnd_ID,pMainDraw_Wnd_RECT,
FONTSIZE_SMALL,WND_STYLE_MODE,
MainDraw_Wnd_Caption_16,NULL);//创建窗体
DrawButton(pNewGame_Button);//在屏幕上划出创建好的按钮
DrawWindow(pMainDraw_Wnd);//在屏幕上划出创建好的窗体
pdc=CreateDC();//创建devicecontext绘图
pdc->DrawRect=ScoreDraw_Wnd_RECT;
//在指定的位置输出文本
TextOut(pdc,190,60,Score_Caption_16,TRUE,FONTSIZE_SMALL);
SetScoreText(pdc);
pdc->DrawRect=MainDraw_Wnd_RECT;
DrawMainFrame(pdc);
//消息循环
for(;;)
{
pMsg=WaitMessage(0);
switch(pMsg->Message)
{
caseOSM_TOUCH_SCREEN:
//触摸屏
Touch_Position.x=pMsg->WParam&0xffff;
Touch_Position.y=pMsg->WParam>>16;
if(IsInRect2(pNewGame_Button_RECT,pTouch_Position))
{
newGame();
}elseif(IsInRect2(pPause_Button_RECT,pTouch_Position))
{
pause();
}elseif(IsInRect2(pLeft_Button_RECT,pTouch_Position))
{
-9-
moveLeft();
}elseif(IsInRect2(pRight_Button_RECT,pTouch_Position))
{
moveRight();
}elseif(IsInRect2(pDown_Button_RECT,pTouch_Position))
{
drop();
}elseif(IsInRect2(pRotate_Button_RECT,pTouch_Position))
{
rotateClockwise();
}
caseOSM_KEY:
//键盘
onKey(pMsg->WParam,pMsg->LParam);
break;
}
DeleteMessage(pMsg);
OSTimeDly(100);
}
DestroyDC(pdc);
}
2)绘制方块
设计了一个三维数组储存7个基本方块形状,通过数组里的数将方块绘制出来。
voidDrawblock(U16x,U16y,U16z){
U16i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
if(block[z][j][i]==1)
{Set_Color(GUI_BLACK);//边框黑色
Draw_VLine(x+i*32+1,y+j*30+1,y+(j+1)*30-1);//竖线
Draw_VLine(x+(i+1)*32-1,y+j*30+1,y+(j+1)*30-1);
Draw_HLine(y+j*30+1,x+i*32+1,x+(i+1)*32-1);//横线
Draw_HLine(y+(j+1)*30-1,x+i*32+1,x+(i+1)*32-1);
Set_Color(GUI_BLUE);//填充蓝色
Fill_Rect(x+i*32+2,y+j*30+2,x+(i+1)*32-2,y+(j+1)*30-2);//填充
}
}
}
3)擦除方块
通过将当前有方块的地方填充成白色达到擦除效果。
voidEraseblock(U16x,U16y,U16z){
-10-
U16i,j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
if(block[z][j][i]==1)
{
Set_Color(GUI_WHITE);//填充白色
Fill_Rect(x+i*32+1,y+j*30+1,x+(i+1)*32-1,y+(j+1)*30-1);
}
}
}
4)随机生成一个方块
通过取出定时器1的后三位值产生随机值,为了避免取值时间几乎相同随机值相近的概率比较高,所以采用当前时刻取出的值与之前相加达到更加随机的效果。
并且在右侧下一个中显示出
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 系统 课程设计 报告