推箱子游戏51单片机课设计最全.docx
《推箱子游戏51单片机课设计最全.docx》由会员分享,可在线阅读,更多相关《推箱子游戏51单片机课设计最全.docx(85页珍藏版)》请在冰点文库上搜索。
推箱子游戏51单片机课设计最全
《51单片机》
课程设计
题目:
基于51单片机的推箱子游戏设计
1、课程设计目的1
2、课程设计题目和实现目标1
3、设计方案1
4、Proteus仿真原理图7
5、程序设计9
6、调试总结28
7、设计心得体会28
参考文献29
附录:
程序代码------------------------------------------------------------------29
1、课程设计目的
《MCS-51单片机》课程设计是与《MCS-51单片机》课程相配套的实践教学环节。
《MCS-51单片机》是一门实践性很强的专业基础课,通过课程设计,达到进一步理解单片机的硬件、软件和综合应用方面的知识,培养实践能力和综合应用能力,开拓学习积极性、主动性,学会灵活运用已经学过的知识,并能不断接受新的知识。
培养大胆发明创造的设计理念,为今后就业打下良好的基础。
通过课程设计,掌握以下知识和技能:
1.单片机应用系统的总体方案的设计;
2.单片机应用系统的硬件设计;
3.单片机应用系统的软件程序设计;
4.单片机开发系统的应用和调试能力
2、课程设计题目和实现目标
2.1课程设计题目:
基于51单片机的推箱子游戏设计
2.2实现目标
设计一款在以51单片机为核心的硬件系统中运行的推箱子游戏。
游戏一共9关,功能包括:
(1)显示游戏开机界面和游戏界面;
(2)按键处理包括移动小人和移动箱子,通过移动上下左右键来控制小人的移动,通过小人推动箱子,把箱子推到指定的目的地为过关,箱子只能推不能拉;
(3)用于可以任意选关,并能随时退出、进入游戏;
(4)每一关都有时间计时,显示当前玩家的游戏耗时。
3、设计方案
根据设计目标,整个系统框图如下:
图1系统框图
3.1控制模块
选用ATMEL公司生产的AT89C52为主控芯片,它是是一个低电压,高性能CMOS8位单片机,主要功能特性如下:
1、兼容MCS51指令系统;
2、8k可反复擦写(大于1000次)Flash
7、2个串行中断,可编程UART串行通道;
8、2个外部中断源,共8个中断源;
9、2个读写中断口线,3级加密位;
10、低功耗空闲和掉电模式,软件设置睡眠和唤醒功能;
本次课设选用PDIP封装的AT89C52芯片,其引脚功能如图2所示,图3为最小系统:
图2引脚功能
图3最小系统
U1:
AT89C52,DIPf封装;C1,C2:
22pf瓷片电容
C3:
10uf电解电容;X1:
12M晶振
R1:
10K金属膜电阻
3.2显示模块
选用内置T6963C控制控制器的12864图形点阵液晶(以下简称Lcd12864)做为显示模块。
T6963C控制器的最大特点具是有硬件初始值设置功能,显示驱动所需的参数,例如:
占空比系数、每行驱动传输的字节数、字符的字体选择等均由引脚电平设置。
所以,液晶显示模块在上电时T6963C控制器就进行初始化设置,软件操作的主要精力就可以全部用于显示界面的设计上。
市场上出售此控制器的液晶很多,本次课设选用深圳市晶日达科技有限公司生产KXM12864F.
LCD12864和单片机以模拟方式连接,即通过模拟操作时序的方法控制液晶显示。
具体的接线图如图4所示
图4显示模块
RP1:
1k排阻,用于做P0口的上拉电阻;LCD1:
KXM12864F
3.3按键模块
16个轻触按键连接成4*4矩阵键盘,做为按键模块,如图5所示
图54*4矩阵键盘
最终系统的硬件系统如下:
图6硬件系统
4、Proteus仿真原理图
在proteus搭建的仿真原理图如下:
图7硬件系统
图8开机画面
图9游戏画面
图10游戏画面
5.程序设计
5.1Lcd12864显示驱动程序
图11读写指令/数据时序图
准备向Lcd12864进行操作时,首先要读取lcd12864的当前的状态,只有lcd12864不忙的时候才能读写操作和数据。
相关程序如下:
/**************************************************
函数名:
status_bit_01()
功能:
状态位sta1(读/写指令),sta0(读/写数据)判断
入口参数:
返回值:
状态值i
***************************************************/
unsignedcharstatus_bit_01()
{
unsignedchari;
P0=0xff;
cd=1;
rd=0;
for(i=10;i>0;i--)
{
if((P1&0x03)==0x03)
break;
}
rd=1;
returni;
}
/*********************************************
函数名:
write_data(unsignedchardat)
功能:
写数据
入口参数:
8位数据dat
返回值:
*********************************************/
voidwrite_data(unsignedchardat)
{
while(status_bit_01()==0);
rd=1;cd=0;wr=0;
P0=dat;
wr=1;cd=1;
}
/*********************************************
函数名:
write_cmd1(unsignedcharcmd)
功能:
写命令,无参数
入口参数:
8位命令cmd
返回值:
*********************************************/
voidwrite_cmd1(unsignedcharcmd)
{
while(status_bit_01()==0);
rd=1;cd=1;wr=0;
P0=cmd;
wr=1;cd=0;
}
/*********************************************
函数名:
write_cmd2(unsignedcharcmd)
功能:
写单参数命令
入口参数:
8位数据dat,8位命令cmd
返回值:
*********************************************/
voidwrite_cmd2(unsignedchardat,unsignedcharcmd)
{
write_data(dat);
write_cmd1(cmd);
}
/************************************************
函数名:
write_cmd2(unsignedcharcmd)
功能:
写双参数命令
入口参数:
8位数据data1,8位数据data2,8位命令cmd
返回值:
*************************************************/
voidwrite_cmd3(unsignedchardata1,unsignedchardata2,unsignedcharcmd)
{
write_data(data1);
write_data(data2);
write_cmd1(cmd);
}
图12为Lcd12864的指令集,向Lcd12864写入相关的指令,即可控制其显示。
图12Lcd12864的指令集
使用液晶前必须对其进行初始化操作,初始化的内容包括光标指针设置,图形区首地址,图形区宽度,显示方式设置,图形方式显示,标形状设置。
相关程序如下:
/************************************************
函数名:
init_12864()
功能:
初始化lcd12864
入口参数:
返回值:
*************************************************/
voidinit_12864()
{
wr=1;rd=1;cd=1;rst=1;//初始化
write_cmd3(0x01,0x00,0x21);//光标指针设置
write_cmd3(0x00,0x00,0x42);//图形区首地址
write_cmd3(16,0x00,0x43);//图形区宽度
write_cmd1(0x88);//显示方式设置,正常显示
write_cmd1(0x98);//图形方式显示,不显示字母,只打点
write_cmd1(0xa0);//光标形状设置10100N2N1N0
}
5.2按键扫描程序
初始P1的电平为0x0f,当有按键下时,电平发生变化,开始程序开始扫描判断哪个按键被按下,并返回按键号,相关程序如下:
/********************************
函数名:
keys_scan()
功能:
按键扫描
入口参数:
返回值:
按键号keyno
*********************************/
unsignedcharkeys_scan()
{
unsignedchartmp;
unsignedcharkeyno;
if(P1!
=0x0f)
{
P1=0x0f;
delayms
(1);
tmp=P1^0x0f;
switch(tmp)
{
case1:
keyno=0;break;
case2:
keyno=1;break;
case4:
keyno=2;break;
case8:
keyno=3;break;
default:
keyno=16;
}
P1=0xf0;
delayms
(1);
tmp=(P1>>4)^0x0f;
switch(tmp)
{
case1:
keyno+=0;break;
case2:
keyno+=4;break;
case4:
keyno+=8;break;
case8:
keyno+=12;break;
}
P1=0x0f;
returnkeyno;
}
}
5.3游戏元素设计
出现在显示画面中的游戏元素总共有6种:
墙壁,箱子,小人,目的地,空白,箱子在目的地。
每个元素在液晶上以一个字符显示,即8×8的点阵。
在字模提取软件设计各个元素,并获得元素的显示码。
显示码的每8位构成字符的一行,8就行有8个字节。
其中1表示该点显示,0表示该点不显示。
图13-是在字模提取软件设计的各个元素,
图13小人图14墙壁图15箱子
图16目的地图17箱子在目的地图18空白
定义一个二维数组elements[][8],存储这些点阵信息。
其中第一个地址为元素代号
unsignedcharcodeelements[][8]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//0空白
0x3C,0x7E,0x66,0x3C,0x7E,0x99,0x3C,0x66,//1人物
0x7F,0x7F,0x7F,0x00,0xEF,0xEF,0xEF,0x00,//2砖头
0xFF,0xC3,0xA5,0x99,0x99,0xA5,0xC3,0xFF,//3箱子
0x00,0x18,0x24,0x4A,0x52,0x24,0x18,0x00,//4目标
0xFF,0xBD,0xDB,0xE7,0xE7,0xDB,0xBD,0xFF,//5箱子到达目标
};
5.4元素的显示
由于T6963c液晶是按以列1字符(8点),行1点来定位的,所以显示时,要先定位显示字符位的列字符和行字符首地址,即行*0x80+列;再定义一个循环变量i,从0,到7,定位该字符位的8个点行,即行*0x80+列+i*0x10,定位到每个点行后,写入对应的元素字节,即elements[元素代号][i],就可以在液晶的指定字符位置上显示该元素了。
相关元素显示子函数如下:
/************************************************
函数名:
printelement()
功能:
指定字符位置,显示元素
入口参数:
列字符地址xh,行字符地址yh,元素代码elnum
返回值:
*************************************************/
voidprintelement(unsignedcharxh,unsignedcharyh,unsignedcharelnum)
{
unsignedchari;
inttemp;
for(i=0;i<8;i++)//行地址加+1
{
temp=yh*0x80+i*0x10+xh;
write_cmd3(temp&0xff,temp/0xff,add_pos);
write_cmd2(elements[elnum][i],noc_wr);
}
}
调用如下程序,对显示元素进行测试,图19为显示效果:
printelement(0,1,1);//在第0列,第1行,显示1号元素(小人)
printelement(1,1,2);//在第1列,第1行,显示2号元素(墙壁)
printelement(2,1,3);//在第2列,第1行,显示3号元素(箱子)
printelement(3,1,4);//在第3列,第1行,显示4号元素(目的地)
printelement(4,1,5);//在第4列,第1行,显示5号元素(箱子在目的地上)
图19显示效果
5.5游戏关卡界面设计
游戏每关都是在8×8个字符组成的区域中进行的,只要在每一个字符显示相应的元素,就可以组成游戏界面。
定义一个三维数组codelevel[][8][8],存储每一关每一个字符位上要显示的元素。
各关卡的界面如下:
/*第1关*/
0,0,2,2,2,2,2,0,
2,2,2,0,0,0,2,0,
2,0,3,0,2,0,2,2,
2,0,2,0,0,4,0,2,
2,0,0,0,0,2,0,2,
2,2,0,2,0,0,0,2,
0,2,1,0,0,2,2,2,
0,2,2,2,2,2,0,0,
图20第1关游戏画面
/*第2关*/
2,2,2,2,2,2,2,2,
2,0,0,0,0,0,1,2,
2,0,0,0,5,0,0,2,
2,0,0,2,2,2,2,2,
2,2,0,0,2,0,0,0,
2,0,3,0,2,0,0,0,
2,0,0,4,2,0,0,0,
2,2,2,2,2,0,0,0,
图21第2关游戏画面
/*第3关*/
0,0,2,2,2,2,0,0,
0,0,2,4,4,2,0,0,
0,2,2,0,4,2,2,0,
0,2,0,0,3,4,2,0,
2,2,0,3,0,0,2,2,
2,0,0,2,3,3,0,2,
2,0,0,1,0,0,0,2,
2,2,2,2,2,2,2,2,
图22第3关游戏画面
/*第4关*/
0,0,0,2,2,2,2,0,
0,2,2,2,0,1,2,0,
0,2,0,0,3,0,2,0,
2,2,0,2,0,2,2,2,
2,0,0,2,0,2,4,2,
2,0,2,0,0,3,4,2,
2,0,0,0,0,0,0,2,
2,2,2,2,2,2,2,2,
图23第4关游戏画面
/*第5关*/
0,0,0,2,2,2,2,0,
0,2,2,2,0,1,2,0,
0,2,0,0,3,0,2,0,
2,2,0,2,0,2,2,2,
2,0,0,2,0,2,4,2,
2,0,2,0,0,0,0,2,
2,0,0,0,0,0,0,2,
2,2,2,2,2,2,2,2,图24第5关游戏画面
/*第6关*/
0,0,0,2,2,2,2,0,
0,2,2,2,0,1,2,0,
0,2,0,0,3,0,2,0,
2,2,0,2,0,2,2,2,
2,0,0,2,0,2,4,2,
2,0,2,0,0,3,4,2,
2,0,3,0,0,0,4,2,
2,2,2,2,2,2,2,2,图25第6关游戏画面
/*第6关*/
0,0,2,2,2,2,2,0,
2,2,2,0,0,0,2,0,
2,0,3,0,2,0,2,2,
2,0,2,0,0,4,0,2,
2,0,0,0,0,2,0,2,
2,2,3,2,4,0,0,2,
0,2,1,0,0,2,2,2,
0,2,2,2,2,2,0,0,图26第7关游戏画面
/*第7关*/
0,2,2,2,2,0,0,0,
2,2,0,0,2,0,0,0,
2,1,3,0,2,0,0,0,
2,2,3,0,2,2,0,0,
2,2,0,3,0,2,0,0,
2,4,3,0,0,2,0,0,
2,4,4,5,4,2,0,0,
2,2,2,2,2,2,0,0,图27第8关游戏画面
/*第9关*/
0,0,0,2,2,2,2,0,
0,2,2,2,0,0,2,0,
2,2,0,1,3,0,2,0,
2,0,4,3,0,0,2,0,
2,0,4,5,0,2,2,0,
2,0,4,3,0,2,0,0,
2,2,0,0,2,2,0,0,
0,2,2,2,2,0,0,0,图28第9关游戏画面
};
5.6开机画面
开机画面是用画图程序制作的一个128像素×64像素的单色位图,并用取模软件提取该图像的点阵信息,共1024字节。
使用t6963c的写数据地址自动加1的命令写入上述全部1024字节的数据,显示开机画面。
图29开机界面
图30字模提取
图31proteus中显示效果
图像的点阵码:
/*--宽度x高度=128x64--*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x7C,0xC0,0x06,0x30,0xC6,0x00,0x1F,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x01,0x86,0xC7,0xF0,0x06,0x1F,0xC7,0xF8,0x30,0x00,0x01,0xC0,0x00,0x00,0x00,0x00,0x01,0x87,0x86,0x18,0x0C,0x01,0x80,0x0C,0x30,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x01,0x87,0x82,0x18,0x1C,0x01,0x80,0x0E,0x30,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x01,0x87,0x06,0x0C,0x18,0x01,0x00,0x06,0x30,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x0F,0x87,0x07,0x0F,0x10,0x03,0x00,0x0C,0x30,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x0C,0x06,0x00,0x01,0x90,0x43,0x00,0x0C,0x1F,0xFF,0x01,0x80,0x00,0x00,0x00,0x00,0x0C,0x06,0x00,0x01,0x98,0xC3,0x08,0x38,0x00,0x3E,0x03,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x01,0x8F,0xC3,0x1C,0x38,0x00,0x3C,0x06,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x03,0x1F,0xC7,0xFC,0x7C,0x7F,0xF6,0x0F,0xE0,0x00,0x00,0x00,0x00,0x0F,0x88,0x1E,0x1F,0x1C,0x7F,0x67,0xDC,0xC0,0x03,0x18,0x30,0x00,0x00,0x00,0x00,0x01,0x8C,0x00,0x03,0x18,0x01,0x80,0x0C,0xC0,0x01,0xF0,0x30,0x00,0x00,0x00,0x00,0x03,0x87,