您的位置 首页 被动

51单片机项目实战—贪吃蛇(测试版)

基于51单片机的贪吃蛇实例

一、元器件

1、AT89C51

关于51单片机就不在嗦了,信任咱们都现已很熟悉了。

2、8×8点阵

点阵里边便是一些二极管啦,经过纵横穿插衔接,横8竖8,每个穿插点都接一个二极管。这儿给咱们找到一个点阵的实物图


我想咱们看到这个图就应该知道怎么去点亮一个点阵了。假定要点亮最左上角那个,那么9号引脚拉高,13号引脚拉低,这样既可。

二、原理图



三、项目分析

1、首要界说一个结构体

struct snake{

unsigned char x[20];

unsigned char y[20];

unsigned char length;

unsigned char direction;

}snk;

数组x,y别离寄存每一个点的横纵坐标,length为蛇的长度,direction为蛇行进的方向

2、坐标系:点阵的左下角为点(0,0),横纵坐标都是正向增加,P2操控横坐标;P0操控纵坐标。经过坐标能够找到点阵中点的方位,然后将其点亮

假定现在有第2个点的坐标x[2] = 1, y[2] = 2,那么点亮这个点的方法为

P2 = 0x04; //0000 0100

P0 = 0xfb; //1111 1011

3、按键发生外部中止,在中止里判别按下那个方向get_direction(),而且一起设置坐标set_location()

4、守时器每隔1s就应该更新方位,由于蛇要不断的行进。守时器不需求更新方向,由于方向只需按键才会改动,守时器用前一步的方向

5、关于点的方位更新方法

1)、向上移动

后边的点去掩盖前面的点,第一个点用新坐标表明x[0]不变,y[0]+1

2)、向下移动

后边的点去掩盖前面的点,第一个点用新坐标表明x[0]不变,y[0]-1

3)、向左移动

后边的点去掩盖前面的点,第一个点用新坐标表明x[0]-1,y[0]不变

4)、向右移动

后边的点去掩盖前面的点,第一个点用新坐标表明x[0]+1,y[0]不变

6、关于边界问题:

1)、任何一个点的横坐标 0 = x[i] 8

2)、任何一个点的纵坐标 0 = y[i] 8

3)、第一个点在移动的时分不能和其他点重复,不然就自己追尾了

7、关于原理图按键的规划

贪吃蛇要求体系能敏捷呼应按键,因而轮询的方法并不可取,只需靠外部中止。但是51只需2个外部中止,咱们最少需求4个方向键,这样就不能一个按键配一个外部中止,经过运用4输入与门,将一切按键状况调集在一起,然后送给外部中止0。咱们将4个按键都接在与门,只需有一个按下,那么与门的输出就会发生一个下降沿,然后发生外部中止。

四、源代码

main.c

#include snake.h

int error = 0;

int time=0;

void interrupt_init()

{

EA = 0; //封闭总中止

IT0 = 1; //外部中止0方法 下降沿

EA = 1; //敞开总中止

EX0 = 1; //敞开外部中止

}

void timer_init()

{

EA = 0; //关总中止

ET0 = 1; //开守时器0中止

TMOD = 0x02; //守时器0工作方法2

TL0 = 6; //守时250us

TH0 = 6;

EA = 1; //开总中止

TR0 = 1; //开端守时

}

int main()

{

// unsigned char tempx, tempy;

// unsigned char i,j;

interrupt_init();

timer_init();

snk_init();

while(1)

{

//假如方位错了就从头初始化蛇

if(error)

snk_init();

//点亮点阵

matrix();

}

}

void inter0() interrupt 0

{

//按键发生外部中止,获取新的方向

get_direction();

//设置新的方位

error = set_location();

// matrix();

}

void timer0() interrupt 1

{

time++;

//守时器为250us 堆集4000次便是1s

if(time == 4000)

{

//每隔1s都需求从头设置方位,让蛇行进

error = set_location();

time = 0;

}

}

snake.c

点击(此处)折叠或翻开

#include snake.h

//蛇的结构体,x为横坐标,y为纵坐标,length为蛇的长度,direction为蛇的行进方向

struct snake{

unsigned char x[20];

unsigned char y[20];

unsigned char length;

unsigned char direction;

}snk;

void matrix()

{

unsigned char i;

int count=500;

//封闭一切的点

P2 = 0x00;

P0 = 0xff;

//依据蛇每一个点的坐标,将对应的点阵点亮

for(i=0; i

{

P2 = 1

P0 = ~(1

}

}

void snk_init()

{

//初始化坐标,一共4个点(3,0) (2,0) (1,0) (1,0)

snk.x[0] = 3;

snk.y[0] = 0;

snk.x[1] = 2;

snk.y[1] = 0;

snk.x[2] = 1;

snk.y[2] = 0;

snk.x[3] = 0;

snk.y[3] = 0;

//初始长度4

snk.length = 4;

//初始移动方向 向右

snk.direction = RIGHT;

//点亮点阵

matrix();

}

void get_direction()

{

//经过按键的状况获取方向

if(!up)

snk.direction = UP;

if(!down)

snk.direction = DOWN;

if(!left)

snk.direction = LEFT;

if(!right)

snk.direction = RIGHT;

}

int set_location()

{

unsigned char i;

int err = 0;

if(snk.direction == UP)

{

for(i=snk.length-1; i>0; i–)

{

snk.x[i] = snk.x[i-1];

snk.y[i] = snk.y[i-1];

}

//假如向上运动,第0个点的横坐标不变,纵坐标加1

snk.x[0] = snk.x[0];

snk.y[0] = snk.y[0] + 1;

}

else if(snk.direction == DOWN)

{

for(i=snk.length-1; i>0; i–)

{

snk.x[i] = snk.x[i-1];

snk.y[i] = snk.y[i-1];

}

//假如向下运动,第0个点的横坐标不变,纵坐标减1

snk.x[0] = snk.x[0];

snk.y[0] = snk.y[0] – 1;

}

else if(snk.direction == LEFT)

{

for(i=snk.length-1; i>0; i–)

{

snk.x[i] = snk.x[i-1];

snk.y[i] = snk.y[i-1];

}

//假如向左运动,第0个点的横坐标减1,纵坐标不变

snk.x[0] = snk.x[0] – 1;

snk.y[0] = snk.y[0];

}

else

{

for(i=snk.length-1; i>0; i–)

{

snk.x[i] = snk.x[i-1];

snk.y[i] = snk.y[i-1];

}

//假如向右运动,第0个点的横坐标加1,纵坐标不变

snk.x[0] = snk.x[0] + 1;

snk.y[0] = snk.y[0];

}

err = is_location_error();

return err;

}

int is_location_error()

{

unsigned char i;

//假如第0个点的坐标和其他恣意一个点重复,那么蛇就自己撞自己,犯错

for(i=1; i

{

if((snk.x[0]==snk.x[i]) (snk.y[0]==snk.y[i]))

return 1;

}

//假如蛇的坐标超出范围,也犯错

if(snk.x[0]>7 || snk.y[0]>7)

return 1;

return 0;

}

snake.h

#include

//界说四个方向按键

sbit up = P3^4;

sbit down = P3^5;

sbit left = P3^6;

sbit right = P3^7;

//界说1个游戏等级按键

sbit level = P3^0;

//界说一个复位按键

sbit reset = P3^1;

//界说4个方向的值

#define RIGHT 0

#define UP 1

#define LEFT 2

#define DOWN 3

void delay_us();

void delay_10us();

void delay_ms();

void delay_10ms();

void delay_100ms();

void delay_s();

int is_location_error();

void matrix();

void snk_init();

void set_direction();

int get_location();

int is_location_error();

『本文转载自网络,版权归原作者一切,如有侵权请联络删去』

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/beidong/148032.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部