资源描述
广东工业大学华立学院
课 程 设 计(论文)
课程名称 微机原理与单片机技术综合设计与实践
题目名称 贪吃蛇游戏机
学生系部 机电工程学部
专业班级 09电气3班
学 号 12030903039
学生姓名
指导教师 王 赟
2012年06月5日
1
广东工业大学华立学院
课程设计(论文)任务书
题目名称
贪吃蛇游戏机
学系学部
机电工程学部
专业班级
09电气3班
姓 名
12030903039
学 号
一、课程设计(论文)的内容
设计一款贪吃蛇游戏机。主要功能有:
(1) 进行经典的贪吃蛇游戏;
(2) 显示玩家当前关卡;
(3) 记录玩家分数;
(4) 游戏暂停,重新开始;
(5) 上下颠倒画面,以适应习惯左手或右手操作的玩家。
二、课程设计(论文)的要求与数据
(1) 方案论证;
(2) 系统原理图或各功能模块的硬件电路原理框图;
(3) 主程序流程图;
(4) 系统调试与分析;
(5) 源程序清单。
三、课程设计(论文)应完成的工作
(1) 完成方案论证;
(2) 完成器件选型;
(3) 给出硬件电路原理图;
(4) 给出程序流程图;
(5) 完成源程序设计及调试;
(6) 完成课程设计报告的撰写。
四、课程设计(论文)进程安排
序号
设计(论文)各阶段内容
地点
起止日期
1
选择课题,明确设计要求,查阅资料
校内
5.26
2
方案论证、系统总体设计
校内
6.07
3
硬件电路原理图设计
校内
6.07
4
程序流程图设计、源程序的编制及调试
校内
6.07~6.10
5
系统调试及分析
校内
6.10
6
课程设计报告的撰写
校内
6.10
五、应收集的资料及主要参考文献
[1] 孙育才.MCS-51系列单片微型计算机及其应用[M].东南大学出版社,2004.6
发出任务书日期: 2012年 05月19 日 指导教师签名:
计划完成日期: 2012年 06 月5 日 教学单位责任人签章:
目录
1系统分析 1
2系统设计 2
2.1系统硬件设计 2
2.1.1系统硬件接线图 2
2.1.2单片机引脚接线表 2
2.1.3TFT液晶屏引脚功能 3
2.1.4微动开关功能 4
2.2系统软件设计 5
2.2.1系统MAIN程序设计 5
2.2.2系统SNAKE程序设计 6
2.2.3系统KEY程序设计 7
2.3.4 MAIN源程序 7
2.3.5 SNAKE源程序 8
2.3.6 KEY源程序 13
3元件清单 14
参考文献 15
1系统分析
本文设计一款贪吃蛇游戏机,以STC 12C5A60S2芯片为控制核心,24MHz晶振,并采用一块2.4英寸,以ILI9325为控制器,分辨率为320*240的TFT彩色显示屏,保证了显示效果细腻流畅。由于显示屏自带的背光,使得画面在黑暗中也能清晰地展现出来。作品基于一块7cm*9cm的玻璃纤维万能版制作,体积重量与一般智能手机相当,并集成了独立移动电源,便于携带。
游戏机外观如图1.1所示。左边为显示屏,右边是总开关和游戏键盘,屏幕下方焊接有单片机,晶振以及两块3V的CR2032纽扣电池。作品主要功能有:
(6) 进行经典的贪吃蛇游戏
(7) 显示玩家当前关卡
(8) 记录玩家分数
(9) 游戏暂停,重新开始
(10) 上下颠倒画面,以适应习惯左手或右手操作的玩家
图1.1 贪吃蛇游戏机外观图
3
2系统设计
2.1硬件设计
本系统的硬件主要由12C5A60S2单片机、24MHz晶振、2.4英寸TFT显示屏、若干微动开关组成。单片机的作用是运行游戏程序,驱动显示屏,识别微动开关;显示屏的作用是显示游戏画面、微动开关的作用是控制蛇的运动方向等设置。
2.1.1系统硬件接线图
图2.1 系统硬件接线图
2.1.2单片机引脚分配
单片机引脚
对应元件引脚
P1.0
微动开关REVERSE
P1.7
微动开关PAUSE/RESTART
P3.1
微动开关DOWN
P3.5
微动开关RIGHT
P3.6
微动开关UP
P3.7
微动开关LEFT
XTAL2
24MHz晶振
XTAL1
24MHz晶振
VSS
GND
VCC
+5V DC
P0.0
TFT DB0
P0.1
TFT DB1
P0.2
TFT DB2
P0.3
TFT DB3
P0.4
TFT DB4
P0.5
TFT DB5
P0.6
TFT DB6
P0.7
TFT DB7
P2.6
TFT RD
P2.5
TFT WR
P2.4
TFT RS
P2.2
TFT CS
P2.1
TFT RESET
2.1.3TFT液晶屏引脚功能
符号
功能说明
CS
-选通
RESET
-复位
DB7
高4位三态、双向数据总线4位
DB6
高4位三态、双向数据总线4位
DB5
高4位三态、双向数据总线4位
DB4
高4位三态、双向数据总线4位
DB3
低4位三态、双向数据总线4位
DB2
低4位三态、双向数据总线4位
DB1
低4位三态、双向数据总线4位
DB0
低4位三态、双向数据总线4位
RD
通过读数据寄存器从GRAM读取18位数据
WR
-写
RS
为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器
NC
悬空
VCC
+5V DC
GND
GND
2.1.4微动开关功能
本系统硬件选用了6个微动开关,分布在显示屏的同一侧,其作用分别为:
微动开关名称
功能说明
UP
令蛇向上走
DOWN
令蛇向下走
LEFT
令蛇向左走
RIGHT
令蛇向右走
PAUSE/RESTART
游戏暂停/重新开始
REVERSE
颠倒屏幕
单片机识别微动开关动作的原理是判断引脚置零与否。把所有微动开关常开引脚的一端接地,另一端接单片机相应的引脚,当微动开关触点闭合,则相当于把单片机相应的引脚接地,输入了“0”信号,于是单片机能识别到该微动开关闭合,在程序运行上作出预先设定好的改变。
2.2软件设计
本系统的软件系统主要可分为MAIN,KEY,SNAKE程序三大模块。
2.2.1系统MAIN程序设计
主程序的任务是对系统进行初始化,清屏,运行SNAKE和KEY程序。
程序框图如图2.2示。
图2.2 主程序流程图
2.2.2系统SNAKE程序设计
SNAKE程序是本系统的核心程序,此程序的正常运行与否直接影响到游戏的显示和操作效果。其作用为:
(1) 绘制游戏界面
(2) 显示死亡界面
(3) 显示过关界面
(4) 控制蛇的运动
(5) 判断蛇是否碰壁
(6) 判断蛇是否咬到自己
(7) 判断蛇是否吃到豆
程序框图如图2.3所示。
图2.3 SNAKE程序流程图
2.2.3系统KEY程序设计
KEY程序是本系统唯一的玩家操控程序,通过识别玩家对六个独立开关的操作,控制游戏里蛇的走向等。
程序框图如图2.4示。
图2.4 KEY程序流程图
2.3.4 MAIN源程序
#include "STC12C5A60S2.h"
#include "KEY_SWEEP.H"
#include "SNAKE.h"
#include "9325tp.h"
main()
{
ILI9325_Initial();
CLR_Screen(0XFFFF);
Init_SNAKE();
P3=0XFF;
P1=0XFF;
while(1)
{
Run_SNAKE();
Key();
}
}
2.3.5 SNAKE源程序
#include "STC12C5A60S2.h"
#include <KEY_SWEEP.H>
#include"9325tp.h"
#include "SNAKE.h"
#define uchar unsigned char
struct
{
uchar X;
uchar Y;
uchar Yes;
}Food; //食物结构体
#define SNAKE_Max_Long 3
struct
{
uchar X[SNAKE_Max_Long];
uchar Y[SNAKE_Max_Long];
uchar Long;
uchar Life;
uchar Score;
uchar Level;
} idata Snake;
uchar idata Key_V_temp=0; extern unsigned char xdata Key_flag;
void Delay_1mS(unsigned int n)
{
unsigned int xdata i;
unsigned char xdata j;
for(i=0;i<n;i++)
for(j=0;j<120;j++);
}
void Init_time0 (void)
{
EA=1;
// ET1=1;
TMOD|=0x20;
TH1=0X00;
TL1=0X00;
TR1=1;
}
void Trun_On_Point (uchar x,uint y,uchar color)
{
Bar((2*(x+2)),(2*(y+2)),(2*(x+4)),(2*(y+4)),color);
}
void Trun_Off_Point (uchar x,uint y)
{
Bar((2*(x+2)),(2*(y+2)),(2*(x+4)),(2*(y+4)),0xBE5F);
}
void Init_SNAKE(void)
{
uchar xdata i;
Init_time0();
CLR_Screen(0xBE5F);
Rectangle(8,8-1,231,270,0x8a);//绘制一个矩形框, 0-127
Rectangle(7,7-1,232,271,0x8a);//绘制一个矩形框, 0-127
Rectangle(6,6-1,233,272,0x8a);//绘制一个矩形框, 0-127
LCD_PutString(50,275,"SCORE",0x00ff,0xBE5F);
LCDShow_uCharNumber(56,290,Snake.Score,0x00ff,0xBE5F);
LCD_PutString(150,275,"LEVEL",0x00ff,0xBE5F);
LCDShow_uCharNumber(156,290,Snake.Level,0x00ff,0xBE5F);
Snake.Long=16;
Snake.Life=0;
Snake.Score=0;
Snake.Level=0;
Food.Yes=1;
Key_Value=0;
Key_V_temp=0;
for(i=0;i<Snake.Long;i++)
{
Snake.X[i]=i+6;
Snake.Y[i]=6;
}
for(i=0;i<Snake.Long;i++)
{
Trun_On_Point(Snake.X[i],Snake.Y[i],0xa8);
}
}
void Display_dead(void)
{
LCD_PutString(80,80,"GAME OVER",0x00ff,0xBE5F);
while(Key_Value!=Key_Enter)
{
Key();
}
Init_SNAKE();
}
void Display_Pass(void)
{
Snake.Level++;
LCD_PutString(68,80,"You are",0xcc88,0xBE5F);
LCD_PutString(74,100,"WIN!",0xcc88,0xBE5F);
while(Key_Value!=Key_Enter)
{
Key();
}
Init_SNAKE();
}
void Run_SNAKE(void)
{
uchar xdata i=0;
if((Key_Value==Key_Right&&Key_V_temp!=Key_Left)||(Key_Value==Key_Left&&Key_V_temp==Key_Right))
{
Trun_Off_Point(Snake.X[0],Snake.Y[0]);
for(i=0;i<Snake.Long-1;i++) {
Snake.X[i]=Snake.X[i+1];
Snake.Y[i]=Snake.Y[i+1];
}
Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+1;
Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0;
for(i=0;i<Snake.Long;i++) {
Trun_On_Point(Snake.X[i],Snake.Y[i],0xaa);
}
Key_V_temp=Key_Right;
}
if(Key_flag)
{
if((Key_Value==Key_Left&&Key_V_temp!=Key_Right)||(Key_Value==Key_Right&&Key_V_temp==Key_Left))
{
Trun_Off_Point(Snake.X[0],Snake.Y[0]);
for(i=0;i<Snake.Long-1;i++) {
Snake.X[i]=Snake.X[i+1];
Snake.Y[i]=Snake.Y[i+1];
}
Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]-1;
Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0;
for(i=0;i<Snake.Long;i++) {
Trun_On_Point(Snake.X[i],Snake.Y[i],0xaa);
}
Key_V_temp=Key_Left;
}
}
if(( Key_Value==Key_Up&&Key_V_temp!=Key_Down)||( Key_Value==Key_Down&&Key_V_temp==Key_Up))
{
Trun_Off_Point(Snake.X[0],Snake.Y[0]);
for(i=0;i<Snake.Long-1;i++)置
{
Snake.X[i]=Snake.X[i+1];
Snake.Y[i]=Snake.Y[i+1];
}
Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]-1;
for(i=0;i<Snake.Long;i++)
{
Trun_On_Point(Snake.X[i],Snake.Y[i],0xaa);
}
Key_V_temp=Key_Up;
}
if(( Key_Value==Key_Down&&Key_V_temp!=Key_Up)||( Key_Value==Key_Up&&Key_V_temp==Key_Down))
{
Trun_Off_Point(Snake.X[0],Snake.Y[0]);
for(i=0;i<Snake.Long-1;i++) {
Snake.X[i]=Snake.X[i+1];
Snake.Y[i]=Snake.Y[i+1];
}
Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+1;
for(i=0;i<Snake.Long;i++) {
Trun_On_Point(Snake.X[i],Snake.Y[i],0xaa);
}
Key_V_temp=Key_Down;
}
if(Snake.X[Snake.Long-1]>=111||Snake.Y[Snake.Long-1]>=131 ||Snake.X[Snake.Long-1]<=2 ||Snake.Y[Snake.Long-1]<=2)
{
Snake.Life=1;
}
for(i=Snake.Long-2;i>0;i--)
{
if(Snake.X[i]==Snake.X[Snake.Long-1]&&Snake.Y[i]==Snake.Y[Snake.Long-1])
{
Snake.Life=1;
}
}
if(Snake.Life==1) {
Display_dead();
}
{
Display_Pass();
}
if(Snake.X[Snake.Long-1]-1<=Food.X && Snake.X[Snake.Long-1]+1>=Food.X && Snake.Y[Snake.Long-1]-1<=Food.Y && Snake.Y[Snake.Long-1]+1>=Food.Y)//
{
//Trun_Off_Point(Food.X,Food.Y);
Snake.Long++;
Snake.X[Snake.Long-1]=Food.X;
Snake.Y[Snake.Long-1]=Food.Y;
Snake.Score+=5;
LCDShow_uCharNumber(56,290,Snake.Score,0x00ff,0xBE5F);
Food.Yes=1;
}
if(Food.Yes==0)
{
Trun_On_Point(Food.X,Food.Y,0xaa);
}
if(Food.Yes==1)
{
while(1)
{
Food.X=((TL1+60)>>2);
Food.Y=((TL1+85)>>2);
for(i=0;i<Snake.Long;i++)
{
if((Food.X==Snake.X[i])&&(Food.X==Snake.Y[i]))
break;
}
if(i==Snake.Long)
{
Food.Yes=0;
break;
}
}
}
Delay_1mS(300-Snake.Level*200);
}
2.3.6 KEY源程序
void Key (void)
{
if((P3!=0XFF) || (P1!=0XFF))
{
Delay(10);
if(P3!=0XFF)
{
if(K_UP==0){Key_Value=1;Key_flag =1;}
if(K_DOWM==0){Key_Value=2;Key_flag =1;}
if(K_LEFT==0){Key_Value=3;}
if(K_RIGHT==0){Key_Value=4;Key_flag =1;}
}
if(P1!=0XFF)
{
if(K_RETURN==0){Key_Value=5;}
if(K_ENTER==0){Key_Value=6;}
}
}
void Key (void)
if(P1!=0XFC)
{
Delay(10);
if(P1!=0XFC)
{
if(K_UP==0 && K_DOWM!=0){Key_Value=1;Key_flag =1;}
if(K_DOWM==0 && K_UP!=0){Key_Value=2;Key_flag =1;}
if(K_LEFT==0){Key_Value=3;}
if(K_DOWM==0 && K_UP==0){Key_Value=4;Key_flag =1;}
}
}
*/
/*
if(Key_Port!=0X0f)
{
//Delay();
if(Key_Port!=0X0f)
{
KeyV_l=Key_Port&0x0f;
Key_Port=0XF0;
KeyV_h=Key_Port&0xf0;
KeyV=KeyV_h+KeyV_l;
for(i=0;i<16;i++) {
if(Key_code[i]==KeyV)
Key_Value=(i+1);
}
Key_Port=0X0f;
}
}
Key_flag =1;
}
3元件清单
元件
型号
数量
单片机
12C5A60S2
1
IC插口
40P
1
方口排母
16P
1
圆口排母
3P
1
纽扣电池
CR2032
2
微动开关
6
按钮开关
1
晶振
24MHz
1
万用板
7*9cm
1
参考文献
[1] 张毅刚,彭喜源,谭晓昀.MCS-51系列单片机实用设计[M].哈尔滨工业大学出版社,2008.
[2] 楼苗然,李光飞.单片机课程设计指导[M].北京航空航天大学出版社,2007.
心
得
体
会
教
师
评
语
年 月 日
成
绩
及
签
名
年 月 日
展开阅读全文