基于STC89C52单片机贪吃蛇做法_第1页
基于STC89C52单片机贪吃蛇做法_第2页
基于STC89C52单片机贪吃蛇做法_第3页
基于STC89C52单片机贪吃蛇做法_第4页
基于STC89C52单片机贪吃蛇做法_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

#ifndef_glb_h_#define_glb_h_#defineucharunsignedchar#defineuintunsignedint#defineLOW0#defineHIGH1//初始化指令#defineCLEAR_SCREEN0x01//清屏指令:清屏且AC值为00H#defineAC_INIT0x02//将AC设置为00H。且游标移到原点位置#defineCURSE_ADD0x06//设定游标移到方向及图像整体移动方向〔默认游标右移,图像整体不动〕#defineFUN_MODE0x30//工作模式:8位根本指令集#defineDISPLAY_ON0x0c//显示开,显示游标,且游标位置反白#defineDISPLAY_OFF0x08//显示关#defineCURSE_DIR0x14//游标向右移动:AC=AC+1#defineSET_CG_AC0x40//设置AC,范围为:00H~3FH#defineSET_DD_AC0x80#defineFUN_MODEK0x36//扩展指令集,8位指令#defineX1address0x80//上半屏X轴起始地址#defineX2address0x88//下半屏X轴起始地址#defineYaddress0x80//Y轴起始地址/*--------------------------------------------------------------------------------------------------- 液晶屏----------------------------------------------------------------------------------------------------*/#defineDataPortP0sbitRS=P3^5;sbitRW=P3^6;sbitE=P3^4;sbitPSB=P3^7;sbitWELA=P2^7;sbitDULA=P2^6;sbitspeed=P2^0;sbitbeep=P2^3;/*#defineDataPortP1sbitRS=P2^0;sbitRW=P2^1;sbitE=P2^3;sbitPSB=P2^4;//sbitWELA=P2^7;//sbitDULA=P2^6;*//*--------------------------------------------------------------------------------------------------- 贪吃蛇----------------------------------------------------------------------------------------------------*///定义复位不自动清零全局变量//#pragmaDATA_SEGNOINIT_RAMsbitLEFT=P2^4;//左sbitRIGHT=P2^1;//右sbitUP=P2^5;//上sbitDOWN=P2^2;//下//sbitLed1=P1^7;//sbitLed2=P1^6;/*sbitLEFT=P0^2;//左sbitRIGHT=P0^3;//右sbitUP=P0^0;//上sbitDOWN=P0^1;//下*/sbitLed7=P1^0;sbitLed6=P1^1;sbitLed5=P1^3;sbitLed4=P1^4;//sbitLed3=P3^3;//sbitLed2=P3^2;//sbitLed1=P3^1;//sbitLed0=P3^0;#endif#ifndef_Init_h_#define_Init_h_/*------------------------------------------------------------------------------------------------------------ Init_12864-------------------------------------------------------------------------------------------------------------*/voidDelayus(unsignedchari);voidDelayms(unsignedinti);voidCheck_Busy();voidWrite_Cmd(unsignedcharCmd);voidWrite_Data(unsignedcharData);//ucharRead_Status();ucharRead_Data();voidInit_IO();voidInit_12864();//voiddisp();voidCGRAM();voidLCD_PutString(unsignedcharx,unsignedchary,unsignedcharcode*s);voidClrScreen();voidClr_GDRAM(void);voidLCD_PutGraphic(unsignedcharcode*img);voidSetGraphicMode();voidKeyscan();voidstatuschange();voidDraw_Point(ucharX,ucharY,ucharclour);voidDraw_zhi(ucharX1,ucharX2,ucharY);voidDraw_shu(ucharX,ucharY1,ucharY2);voidDraw_line(ucharx0,uchary0,ucharx1,uchary1);voidDraw_all_lines();voidStat_Point();voidLast_Point();voidAdd_Point();voidBump_Wall();voidSelf_Bump();/*------------------------------------------------------------------------------------------------------------ Init_Time-------------------------------------------------------------------------------------------------------------*///voidInit_Time();//voidexter0()interrupt1#endif#include<reg52.h>#include"glb.h"uinttimestatus=0;voidInit_Time(){ TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; }voidTimer0()interrupt1{ TH0=(65536-50000)/256; TL0=(65536-50000)%256; timestatus++; if(speed==0) { if(timestatus>2) timestatus=0; } if(timestatus>10) timestatus=0;}#ifndef_Interrupt_h_#define_Interrupt_h_voidInit_Time();#endif#include<reg52.h>#include"glb.h"/*游戏的初始化值*/uchargamestatus=0;ucharflag=1; //折点个数标志uchara[]={20,0,0,0,0,0,0,0}; //其中〔a[0],b[0]〕为初始蛇头坐标,〔a[1],b[1]〕为初始蛇尾坐标,之后蛇尾坐标为〔a[flag],b[flag]〕。ucharb[]={32,32,0,0,0,0,0,0}; //后面〔a[i],b[i]〕记录拐点坐标,其中〔a[flag-1],b[flag-1]〕为第一个拐点的坐标ucharc[]={0,0,0,0,0,0,0,0}; //c[i]记录方向,其中a[0]为当前方向ucharx=54,y=32,pointstatus,allpoints;/*---------------------------------------------------------------------------------延时函数---------------------------------------------------------------------------------*/voidDelayus(unsignedchari){ intj; for(j=2;j>0;j--) for(;i>0;i--);}voidDelayms(unsignedinti){ unsignedintj; for(;i>0;i--) for(j=110;j>0;j--);}/*---------------------------------------------------------------------------------检测忙位---------------------------------------------------------------------------------*/voidCheck_Busy(){E=0; RS=0; RW=1; E=1; DataPort=0xff; while((DataPort&0x80)==0x80); //忙那么等待,忙标志检测BF,可以将BF读到DB7进行检测 E=0;}/*---------------------------------------------------------------------------------写命令---------------------------------------------------------------------------------*/voidWrite_Cmd(unsignedcharCmd){ Check_Busy(); RS=0; RW=0; DataPort=Cmd; Delayus(2); E=1; Delayus(5); E=0;}/*---------------------------------------------------------------------------------写数据---------------------------------------------------------------------------------*/voidWrite_Data(unsignedcharData){ Check_Busy(); RS=1; RW=0; E=1; DataPort=Data; Delayus(2); E=0; Delayus(5);}/*---------------------------------------------------------------------------------读状态---------------------------------------------------------------------------------*//*ucharRead_Status(){ uchari;DataPort=0xff;RW=1;RS=0;E=0;Delayus(2);E=1;Delayus(5);i=DataPort;Delayus(5);E=0;return(i);}*//*---------------------------------------------------------------------------------读数据---------------------------------------------------------------------------------*/ucharRead_Data(){ uchari;//while((Read_Status()&0x80)!=0x00);//忙检测 Check_Busy();RW=1;RS=1;E=0;Delayus(2);E=1;Delayus(5);i=DataPort;Delayus(5);E=0;returni;}/*---------------------------------------------------------------------------------计算并显示得分---------------------------------------------------------------------------------*/voidWrite_Score(ucharx,uchary,ucharshu){uchard1,d2,add,ah;d1=shu/10;d2=shu%10;if(x==0)ah=0x80;elseif(x==1)ah=0x90;elseif(x==2)ah=0x88;elseah=0x98;add=ah+y; //某一行显示分数Write_Cmd(add);Write_Data(d1+'0');Write_Data(d2+'0');}/*---------------------------------------------------------------------------------IO口初始化---------------------------------------------------------------------------------*/voidInit_IO(){ Led4=1; Led5=1; Led6=1; Led7=1;}/*---------------------------------------------------------------------------------液晶屏初始化---------------------------------------------------------------------------------*/voidInit_12864(){ //WELA=0; //DULA=1; Delayms(1); PSB=1; Delayms(1); Write_Cmd(0x30); Delayms(1); Write_Cmd(0x30); Delayms(1); Write_Cmd(0x0f); Delayms(1); Write_Cmd(0x01); Delayms(1); //Write_Cmd(0x06); //DelayVs2x(50);}/*voiddisp(){ unsignedchari; unsignedchara=0x10; Write_Cmd(0x80); for(i=0;i<16;i++) { Write_Data(a); a++; Delayms(2); }}*//*---------------------------------------------------------------------------------用户自定义字符---------------------------------------------------------------------------------*//*voidCGRAM(){ inti; Write_Cmd(0x30); Write_Cmd(0x40); for(i=0;i<16;i++) { Write_Data(0x10); Write_Data(0x10); }}*//*---------------------------------------------------------------------------------显示字符x:横坐标值,范围0-8y:纵坐标值,范围1-4---------------------------------------------------------------------------------*/voidLCD_PutString(unsignedcharx,unsignedchary,unsignedcharcode*s){ switch(y) { case1:Write_Cmd(0x80+x);break; case2:Write_Cmd(0x90+x);break; case3:Write_Cmd(0x88+x);break; case4:Write_Cmd(0x98+x);break; default:break; } while(*s>0) { Write_Data(*s); s++; Delayms(5); }}/*---------------------------------------------------------------------------------清屏---------------------------------------------------------------------------------*/voidClrScreen(){ Write_Cmd(0x01); Delayus(5);}/*---------------------------------------------------------------------------------去除液晶GDRAM内部的随机数据---------------------------------------------------------------------------------*/voidClr_GDRAM(void){ucharx,y,i,j;Write_Cmd(0x34);//鎵撳紑鎵╁睍鎸囦护闆?y=0x80;x=0x80;for(i=0;i<32;i++){Write_Cmd(y);Write_Cmd(x);for(j=0;j<16;j++){Write_Data(0x00);}y++;}y=0x80;x=0x88;for(i=0;i<32;i++){Write_Cmd(y);Write_Cmd(x);for(j=0;j<16;j++){Write_Data(0x00);}y++;}Write_Cmd(0x30);//鍥炲埌鍩烘湰鎸囦护闆?}/*---------------------------------------------------------------------------------显示图片---------------------------------------------------------------------------------*//*voidLCD_PutGraphic(unsignedcharcode*img){ inti,j; //显示上半屏内容设置 for(i=0;i<16;i++) { Write_Cmd(0x80); for(j=0;j<16;j++) { Write_Data(*img); img++; } Write_Cmd(0x90); for(j=0;j<16;j++) { Write_Data(*img); img++; } }//显示下半屏内容设置 for(i=0;i<32;i++) { Write_Cmd(0x88); for(j=0;j<16;j++) { Write_Data(*img); img++; } Write_Cmd(0x98); for(j=0;j<16;j++) { Write_Data(*img); img++; } }}*//*---------------------------------------------------------------------------------设置到绘图模式---------------------------------------------------------------------------------*//*voidSetGraphicMode(){ Write_Cmd(0x36); Delayms(2);}*//*------------------------------------------------------------------------------------------------------------ 按键函数-------------------------------------------------------------------------------------------------------------*/voidKeyscan(){ Led4=1; Led5=1; Led6=1; Led7=1; if(RIGHT==0) { Delayms(5); if(RIGHT==0) { Led4=0; gamestatus=0; } }if(DOWN==0) { Delayms(5); if(DOWN==0) { Led5=0; gamestatus=1; } } if(UP==0) { Delayms(5); if(UP==0) { Led6=0; gamestatus=3; } } if(LEFT==0) { Delayms(5); if(LEFT==0) { Led7=0; gamestatus=2; } }}/*------------------------------------------------------------------------------------------------------------ 状态发生改变处理函数必须跟在按键涵数后面!!!!-------------------------------------------------------------------------------------------------------------*/voidstatuschange(){uchari;if((gamestatus!=c[0])&&((gamestatus%2)!=(c[0]%2))) //只有gamestatus由奇数变为偶数或由偶数变为奇数时,才改变方向{ flag++; //方向改变,折点个数加1 for(i=flag;i>0;i--) { a[i]=a[i-1];b[i]=b[i-1];c[i]=c[i-1];}c[0]=gamestatus;}}/*------------------------------------------------------------------------------------------------------------ 画点函数,在屏幕上画一个点-------------------------------------------------------------------------------------------------------------*/voidDraw_Point(ucharX,ucharY,ucharclour) //clour为0时画点,为其它去除这个点{ucharx_pos,y_pos,x_bit;uintread_H,read_L,data_H,data_L; //计算LCD位置x_pos=X/16; //取16*16首地址if(Y>31) x_pos+=8; //计算该点所属LCD液晶中X坐标位置,上半屏0-7,下半屏8-15x_bit=X%16; //该点位于所在16bit中的第几位y_pos=Y%32; //y坐标32行的第几行Write_Cmd(0x34); //翻开扩展指令集操作GDRAM是扩展指令集 Write_Cmd(0x36); //使用扩充指令集,绘图显示ONWrite_Cmd(0x80+y_pos); // 写入第一行8个32*16模块的垂直起始地址,在写入地址时,要先输入垂直地址,再输入水平地址这是规定好的Write_Cmd(0x80+x_pos); //第一行水平的起始地址为80H //以后写入数据后,地址计数器〔AC〕会自动加一Read_Data(); //此处为什么要中上不知道为什么????read_H=Read_Data(); //高八位!read_L=Read_Data(); //低八位!if(x_bit<8) //该点位于高八位{ if(clour==0) //画点 { data_H=read_H|(1<<(7-x_bit)); //把1左移7-x_bit位 } else { data_H=read_H&~(1<<(7-x_bit)); } data_L=read_L; }else //该点位于低八位 { data_H=read_H; if(clour==0) { data_L=read_L|(1<<(15-x_bit)); } else { data_L=read_L&~(1<<(15-x_bit));}} Write_Cmd(0x80+y_pos);Write_Cmd(0x80+x_pos);Write_Data(data_H); //写高八位数据Write_Data(data_L); //写低八位数据Write_Cmd(0x30); //回到根本指令集 Write_Cmd(0x0c);}/*------------------------------------------------------------------------------------------------------------ 在整个屏幕上画一条直线-------------------------------------------------------------------------------------------------------------*/voidDraw_zhi(ucharX1,ucharX2,ucharY) //X1代表线首横坐标,X2代表线尾横坐标,Y代表纵坐标{ uchari,temp; if(X1>X2) //X轴上,起点大于终点,交换数据 { temp=X2; X2=X1; X1=temp; }for(i=X1;i<=X2;i++) { Draw_Point(i,Y,0); }}/*------------------------------------------------------------------------------------------------------------ 在整个屏幕上画一条竖线-------------------------------------------------------------------------------------------------------------*/voidDraw_shu(ucharX,ucharY1,ucharY2) //Y1代表线首纵坐标,Y2代表线尾纵坐标,X代表横坐标{uchari,temp; if(Y1>Y2) //X轴上,起点大于终点,交换数据 { temp=Y2; Y2=Y1; Y1=temp; } for(i=Y1;i<=Y2;i++) { Draw_Point(X,i,0); }}/*------------------------------------------------------------------------------------------------------------ 在整个屏幕上画一条线-------------------------------------------------------------------------------------------------------------*/voidDraw_line(ucharx0,uchary0,ucharx1,uchary1) //只能是横线或者是竖线,〔x0,y0〕为线首坐标。(x1,y1)为线尾坐标{ intdx,dy; //定义X.Y轴上增加的变量值 dx=x1-x0; //X轴方向上的增量 dy=y1-y0; //Y轴方向上的增量 if(dx==0) Draw_shu(x0,y0,y1); if(dy==0) Draw_zhi(x0,x1,y0);}/*------------------------------------------------------------------------------------------------------------ 画边界函数-------------------------------------------------------------------------------------------------------------*/voidDraw_all_lines(){ uchari; for(i=0;i<flag;i++) { Draw_line(a[i],b[i],a[i+1],b[i+1]); }}/*------------------------------------------------------------------------------------------------------------ 开始点,蛇头-------------------------------------------------------------------------------------------------------------*/voidStat_Point(){ if(c[0]==0) { a[0]=a[0]+1; //如果向右,直线长度加1 } elseif(c[0]==1) { b[0]=b[0]+1; } elseif(c[0]==2) { a[0]=a[0]-1; } else { b[0]=b[0]-1; }}/*------------------------------------------------------------------------------------------------------------ 最后点,蛇尾-------------------------------------------------------------------------------------------------------------*/voidLast_Point(){ if(c[flag-1]==0) //如果第一次拐之前,方向向右 { a[flag]=a[flag]+1; //蛇尾横坐标加1 } elseif(c[flag-1]==1) { b[flag]=b[flag]+1; } elseif(c[flag-1]==2) { a[flag]=a[flag]-1; }else { b[flag]=b[flag]-1; } if((a[flag]==a[flag-1])&&(b[flag]==b[flag-1])) { flag--; }}/*------------------------------------------------------------------------------------------------------------ 加点,如果吃到食物,就产生新的食物,并画上该点,把该点作为蛇头-------------------------------------------------------------------------------------------------------------*/voidAdd_Point(){ if(c[0]==0) { if((a[0]+1)==x&&(b[0]==y)) { a[0]=x; pointstatus=1; allpoints++; } } elseif(c[0]==1) { if((b[0]+1)==y&&(a[0]==x)) { b[0]=y; pointstatus=1; allpoints++; } } elseif(c[0]==2) { if((a[0]-1)==x&&(b[0]==y)) { a[0]=x; pointstatus=1; allpoints++; } } else { if((a[0])==x&&(b[0]-1)==y) { b[0]=y; pointstatus=1; allpoints++; } }Draw_Point(x,y,0); //画上一个点,即产生食物 if(pointstatus) { beep=0; Delayms(10); beep=1; pointstatus=0; //Draw_Point(x,y,1);//去除这个点 //Delayms(5000); //设置断点,用于测试 x=x+16; y=y+18; if(x>127) { x=1; } if(y>63) { y=0; }}}/*------------------------------------------------------------------------------------------------------------ 判断是否撞边框-------------------------------------------------------------------------------------------------------------*/voidBump_Wall(){ if((a[0]>127||a[0]<0)||(b[0]<0||b[0]>63)) { TR0=0; ClrScreen(); //Disp_HZ(0x98,hang4,8); LCD_PutString(0,3,"撞墙死亡了"); Write_Score(3,7,allpoints); }}/*------------------------------------------------------------------------------------------------------------ 判断是否自身相撞-------------------------------------------------------------------------------------------------------------*/voidSelf_Bump(){ uchari,j; for(j=flag-1;j>=3;j--) { if(c[j]==0) { for(i=a[j+1];i<a[j];i++) { if((a[0]==i)&&(b[0]==b[j])) { TR0=0; ClrScreen(); //Disp_HZ(0x98,hang3,7); LCD_PutString(0,4,"死亡"); Write_Score(3,7,allpoints); } } } elseif(c[j]==1) { for(i=b[j+1];i<b[j];i++) { if((a[0]==a[j])&&(b[0]==i)) { TR0=0; ClrScreen(); //Disp_HZ(0x98,hang3,7); LCD_PutString(0,4,"死亡"); Write_Score(3,7,allpoints); }

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论