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

来源:本站
导读:目前正在解读《51单片机项目实战---贪吃蛇(测试版)》的相关信息,《51单片机项目实战---贪吃蛇(测试版)》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《51单片机项目实战---贪吃蛇(测试版)》的详细说明。
简介:本文为51单片机项目实战---贪吃蛇,附有原理图和程序代码,希望对你的学习有所帮助。

一、元器件

1、AT89C51单片机,随便网上一搜索就是一大堆的介绍。

2、8x8点阵

点阵里面就是一些二极管,通过纵横交叉连接,横8竖8,每个交叉点都接一个二极管。通过高低电平控制二极管点亮和熄灭。点阵的实物图实例:

二、原理图

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

三、原理分析

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

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

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< 8

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

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

7、关于原理图按键的设计

贪吃蛇要求系统能迅速响应按键,因此轮询的方式并不可取,只有靠外部中断。然而51只有2个外部中断,我们起码需要4个方向键,这样就不能一个按键配一个外部中断,通过使用4输入与门,将所有按键状态集合在一起,然后送给外部中断0。我们将4个按键都接在与门,只要有一个按下,那么与门的输出就会产生一个下降沿,从而产生外部中断。

四、源代码(main.c)

<font face="微软雅黑" size="4">#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<snk.length; i++) { P2 = 1<<snk.x[i]; P0 = ~(1<<snk.y[i]); }}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<snk.length; 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 <reg51.h>//定义四个方向按键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 3void 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();</font>

提醒:《51单片机项目实战---贪吃蛇(测试版)》最后刷新时间 2024-03-14 00:52:09,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《51单片机项目实战---贪吃蛇(测试版)》该内容的真实性请自行鉴别。