原创 彬太郎51单片机开发板视频教程之贪食蛇

2011-4-22 12:07 10980 12 12 分类: MCU/ 嵌入式

5c3c5557-87f3-418e-82d7-b6a40535cb26.jpg6c232660-5ab2-4f13-8a90-4e25cc1ea84d.jpg8b436b88-59c4-4678-aa07-1279e3e448d9.jpgattachment download


//**程序:贪食蛇***
//***说明:通过外部中断0可控制蛇的速度****
//***游戏开始是点阵的测试,贪食蛇一开始身长2个点***
//***开始闪烁的那个代表的是蛇头***
//***作者:爱因斯尼@SCUT***
//***时间:2011.04.16***
//***地点:华南理工大学***


//说明:彬太郎51单片机配套电子书也完成了。有CHM和EXE两种格式。其中CHM格式的可以到爱问下载:


//CHM下载链接:http://ishare.iask.sina.com.cn/f/14771225.html


//EXE格式的电子书内容丰富 ,有音乐和视频,但是比较大,看了CHM格式后,如果有兴趣可以联系我


//QQ:945283731免费索取EXE格式单片机配套电子书。感谢你的支持!


//***必要的头文件和宏定义***
#include<reg52.h>//51单片机的头文件
#define uint unsigned int//两个常用的宏定义
#define uchar unsigned char
#include<reg52.h>
#define uint unsigned int//必要的宏定义
#define uchar unsigned char
#define Snake_length 20//最大长度,蛇吃满多少就自动结束程序
#define TIME 20      //显示延时时间
uchar SPEED=40;     //速度控制,在这里设置初始速度
uchar  flag=0;     //方向标志位,
char addx,addy;    //位移偏移量
//***关于595的位定义***
sbit DS=P1^0;//595串口数据输入端
sbit OE=P1^1;//使能端,低电平有效
sbit SH=P1^2;//移位寄存器的时钟输入
sbit ST=P1^3;//存储器的时钟输入


sbit lie=P1^7;//点阵的列扫描


sbit key_gnd=P2^0;//方向使能,默认是低电平


sbit up=P2^4;//定义方向键
sbit down=P2^5;
sbit left=P2^6;
sbit right=P2^7;
uchar x[Snake_length+1];//x坐标
uchar y[Snake_length+1];//y坐标         
uchar time,n,i,e;//延时时间,当前蛇长,通用循环变量,当前速度  
uchar code table_OK[]={
0x7e,0x42,0x7e,0x00,0xff,0x38,0x44,0x82,//OK
0x7E,0x41,0x51,0x31,0x3E,0x41,0x41,0x3E};//GO
uchar code table_hang[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0xff};
uchar code table_lie[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x00};
//****延时子函数****
void delay_ms(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
     for(j=0;j<114;j++);
 }
void delay(uint m)
{uint i,j;
for(i=0;i<m;i++)
     for(j=0;j<1148;j++); }
//***595串转并***
void Disp_hang(uchar hang_num)
{
 uchar i,zf;
 P1=0x90;
 zf=table_hang[hang_num];
 for(i=0;i<8;i++)
 {
  if(zf&0x80)DS=1;
  else DS=0;
  SH=1;//上升沿
  SH=0;
  zf<<=1;
  }
  ST=1;//上升沿
  ST=0;
  OE=0;
 }
//***某行****
void Disp_595(uchar num_595)
{
 uchar i,zf;
 P1=0x90;
 zf=num_595;
 for(i=0;i<8;i++)
 {
  if(zf&0x80)DS=1;
  else DS=0;
  SH=1;//上升沿
  SH=0;
  zf<<=1;
  }
  ST=1;//上升沿
  ST=0;
  OE=0;
 }
//***某列***
void Disp_lie(uchar lie_num)
{
 lie=1;
 P0=table_lie[lie_num];
 lie=0;
 }
//***点阵的初始化**
void Init_dianzhen()
{
 Disp_hang(8);
 Disp_lie(8);
 }
//***带两个形参的点阵函数:行和列***
void Disp_dianzhen(uchar ii,uchar jj)
{
Disp_hang(ii);
Disp_lie(jj);
 }
//***测试点阵***
void Test_dianzhen()
{
 uchar i,j,t;


 for(i=0;i<8;i++)
 {
 flag=~flag;
  for(j=0;j<8;j++)
 {
  if(flag==0) t=7-j;
  else t=j;
  Disp_dianzhen(i,t);
  // Disp_dianzhen(t,i);
  delay(10);
  }
  }  
 for(j=0;j<80;j++)//OK字符停顿的时间
    for(i=0;i<7;i++)
 {
  Disp_lie(i);
 Disp_595(table_OK);
 delay_ms(5);//这里一定要加延时 
 }
 lie=1;P0=0xff;
 for(j=0;j<60;j++)//OK字符停顿的时间
    for(i=8;i<16;i++)
 {
 Disp_lie(i%8);//一共是8列的,要记得取余哦
 Disp_595(table_OK);
 delay_ms(7);//这里一定要加延时 
 }   
 }


//********************
延时程序
*********************
void delay_M(char MS)
{
char us,usn;
while(MS!=0)
{
usn = 0;
while(usn!=0)
{
us=0xff;
while (us!=0){us--;};
usn--;
}
MS--;
}
}
//*******************************************
判断碰撞
*******************************************
bit knock()
{bit k;
 k=0;
if(x[1]>7||y[1]>7)k=1;                             //撞墙
for(i=2;i<n;i++)
    if((x[1]==x)&(y[1]==y))k=1;  //撞自己
return k;
}
//*****************
上下左右键位处理
*****************
void deal_with_key()
{
if(!key_gnd)
{


if(!down)
       {addy=0;if(addx!=-1)addx=1; else addx=-1;}
if(!up)
       {addy=0;if(addx!=1)addx=-1; else addx=1;}
if(!left)
       {addx=0;if(addy!=1)addy=-1; else addy=1;}
if(!right)  
       {addx=0;if(addy!=-1)addy=1; else addy=-1;}
}
}
//*****************
乘方程序
*****************
uchar mux(uchar temp)
{
if(temp==7)return 128;
if(temp==6)return 64;
if(temp==5)return 32;
if(temp==4)return 16;
if(temp==3)return 8;
if(temp==2)return 4;
if(temp==1)return 2;
if(temp==0)return 1;
return 0;
}
//*****************
void timer0(uchar k)
{
while(k--)
{
for(i=0;i<Snake_length+1;i++)
{
Disp_595(mux(x));
P0=255-mux(y);
deal_with_key();//上下左右键位处理
delay_M(TIME); //显示延迟
Disp_595(0x00);
P0=0xff;
}}
}
//***通过外部中断0来控制蛇的速度***
void Wai_int0() interrupt 1 using 1
{
 //delay(2);
 if(SPEED>=20)SPEED-=20;
 else
    {
  if(SPEED>0&SPEED<=20)SPEED-=2;
  else SPEED=80;
  }
 }
//*****************
主程序
//*****************
void main(void)
{
IT0=1;//触发方式是下降沿触发
EX0=1;
EA=1;
e=SPEED;
P0=0x00;
P0=0xff;
P2=0xf0;//在这里通过软件把P2^4--P2^7设置为独立按键,简化按键扫描程序
P3=0x00;
Init_dianzhen();
delay(200);
Test_dianzhen();
lie=1;
while(1)      
 {
 for(i=3;i<Snake_length+1;i++)x=10;
 for(i=3;i<Snake_length+1;i++)y=10;//初始化
 x[0]=4;y[0]=4;  //食物                         
 n=3;            //初始化蛇长n=n-1
 x[1]=0;y[1]=0;  //蛇尾
 x[2]=1;y[2]=0;  //蛇头
 addx=0;addy=0;  //位移偏移
 //k=1;
 while(1){if(!key_gnd)break;timer0(1);}
 while(1)        
  {timer0(e);
   if(knock()){e=SPEED;break;}//判断碰撞
        if((x[0]==x[1]+addx)&(y[0]==y[1]+addy)) //是否吃东西
           {n++;
     if(n==Snake_length+1)
     {n=3;e=e-10;
     for(i=3;i<Snake_length+1;i++)x=100;
           for(i=3;i<Snake_length+1;i++)y=100;
     }
           x[0]=x[n-2];
           y[0]=y[n-2];
           }    


 for(i=n-1;i>1;i--){x=x[i-1];y=y[i-1];}       
    x[1]=x[2]+addx;y[1]=y[2]+addy;//移动
  }      
 }   
}


欢迎登陆我们的淘宝网:http://item.taobao.com/auction/item_detail.htm?item_num_id=944733485760454e0b-fd0b-4da4-bd45-89571834d391.jpg

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
12
关闭 站长推荐上一条 /3 下一条