好文档 - 专业文书写作范文服务资料分享网站

Atmega16单片机贪吃蛇小游戏 

天下 分享 时间: 加入收藏 我要投稿 点赞

Atmega16单片机贪吃蛇小游戏

程序原创,好用!

缺少财富值的可以私信我,我发给你。代码中有qq

代码基于Atmega16 芯片,晶振采用8M,LCD12864采用并行通信,四个独立按键,以下是相关的原理图。

控制贪吃蛇前进的核心思路是:点亮头部,熄灭尾部。

关于蛇身子的点可以采用一个数组来存储。把数组变成一个循环队列,前进头部数据入队,尾部数据出队,这种方法控制起来简单一些,但是比较消耗内存(嗯,有点奢侈)单片机RAM仅1k,蛇的最大长度500左右。

另外我们可以只存下蛇身子的拐点,记录下拐点的方向,就可以得出蛇身子位置信息。(本代码采用此种记录方式)。

现在举例说明一下数据的值,如图所示表示一条蛇,2表示蛇头,1表示蛇尾 structsnake_type //定义一个砖块的结构体每次只写八位数据 {

unsigned char x_head; //头x坐标 0~63

unsigned char y_head; //头y坐标 0~63(为偶数) unsigned char direc_head; //头前进的方向

unsigned char x_end; //尾x坐标 0~63 unsigned char y_end; //尾y坐标 0~63 unsigned char direc_end; //尾前进的方向 } snake;

则数据值如下:

snake.x_head = 1; snake.y_head = 4 ;snake.direc_head = 2; Snake.x_end = 2; snake.y_end = 0;snake.direc_end = 1;

三大重要函数,这三个函数与硬件打交道,为上层游戏编写提供了便利。 snake_data_add()点亮两个像素点 snake_data_dele()熄灭两个像素点

snake_read_data()读取像素点是否已经点亮

简单演示一下效果

VID_20180304_123454.mp4

行了,不多说了,上干货吧!

******************************************************************************************************************************************

Main.c

****************************************************************************************************************************************** #include #include #define uint unsigned int

#define uchar unsigned char #include\#include\#include\

voiddelay_nms(uintnms) { uinti,j; for(i=0;i

voidscan_deal(void) { //返回值:0 不可移动 // 1 可以移动 // 2 吃到苹果 switch(move_forward()) { case 0: show_picture(game_over); //死亡,游戏结束 break; case 2:

//可以在此嵌入计分数据代码并减小times的值可以提高难度的功能 appel_add(suiji_data); //产生苹果,游戏继续 break; default: break; } }

void main(void) { uchari=0,b=8; lcd_init(); lcd_delay_nms(10); display(); //画空图 snake_init(); snake_data_add(0,0); snake_data_dele(0,0); while(1)

{

snake_move_scan(100); //多次扫描按键, scan_deal(); } }

******************************************************************************************************************************************

12864_bing_xing.h

******************************************************************************************************************************************

/******************************************************************************/

/* Name: LCD12864(St7920/St7921) */ /* */

/* Designed by : Date:2016/5/9 */

/* 开发环境:ICCAVR */ /* QQ:1460467003 飘 */

/******************************************************************************/

#define set_bit(register1,bits) (register1|=(1<<(bits))) #define clr_bit(register1,bits) (register1&=~(1<<(bits))) #define get_bit(register1,bits) (register1&=(1<<(bits))) #define lcd_clr 0x01

#define lcd_rs_hset_bit(PORTA,0) #define lcd_rs_lclr_bit(PORTA,0) #define lcd_rw_hset_bit(PORTA,1) #define lcd_rw_lclr_bit(PORTA,1) #define lcd_en_hset_bit(PORTA,2) #define lcd_en_lclr_bit(PORTA,2) #define lcd_data_i PINB #define lcd_data_o PORTB #include\

voidlcd_delay_nms(uintnms) { uinti,j; for(i=0;i

//读状态

voidlcd_check_busy(void) { DDRB=0X00; lcd_data_o=0xFF; //lcd_delay_nms(1); lcd_rs_l; lcd_rw_h; lcd_en_l; lcd_en_h; }

while (lcd_data_i&0X80); //检测忙信号 lcd_en_l;

DDRB=0XFF; lcd_data_o=0xff;

// lcd_delay_nms(1);

// 1表示数据 0表示命令

void lcd_write_data(ucharon_data,uchar data) //发送指令或数据 {

lcd_check_busy(); if(on_data) lcd_rs_h; else lcd_rs_l; lcd_rw_l; lcd_data_o=data; lcd_delay_nms(2);//等待当前工作完成 lcd_en_h; lcd_delay_nms(2);//等待当前工作完成 lcd_en_l; }

//读数据

ucharlcd_read_data(void) { uchar data; lcd_check_busy(); lcd_data_o=0xFF; DDRB=0X00; lcd_rs_h; lcd_rw_h; lcd_en_h; lcd_delay_nms(1); data=lcd_data_i; lcd_en_l;

return(data); } /*

以屏幕的左上角为原点,X 左——右增大 0——7 两个字节为单位 Y 上——下增大 0——63 位为单位 */

voidlcd_set_xy(ucharx,uchar y) { if(y>31) { lcd_write_data(0,0x80+y-32); //y 轴 lcd_write_data(0,0x88+x); //x 轴 } else { lcd_write_data(0,0x80+y); //y 轴 lcd_write_data(0,0x80+x); //x 轴 } }

void lcd_init(void) //LCM初始化 {

DDRA|=0X7; PORTA|=0X07; DDRB=0XFF; PORTB=0XFF;

set_bit(DDRC,0); set_bit(PORTC,0); //并行模式 lcd_write_data(0,0x30); //八位数据端口,进入基本指令集 lcd_write_data(0,0x01); //显示清屏 lcd_write_data(0,0x06); //光标自增,画面不动 lcd_write_data(0,0x0c); //整体显示,游标关,不反白 }

//写内存,为空

void display(void) //图形方式12864显示字模逐行式顺向 { unsigned char i,j;

lcd_write_data(0,0x34); //图形方式 for(i=0;i<32;i++) { lcd_write_data(0,0x80+i); //Y lcd_write_data(0,0x80); //X for(j=0;j<16;j++) { lcd_write_data(1,0x00); }

}

}

for(i=0;i<32;i++) { lcd_write_data(0,0x80+i);//Y lcd_write_data(0,0x88); //X for(j=0;j<16;j++) { lcd_write_data(1,0x00); } }

//lcd_write_data(0,0x80+22); //lcd_write_data(0,0x88); //for(j=0;j<16;j++)

// lcd_write_data(1,0xff); lcd_write_data(0,0x36);

//显示图片,逐行式顺向

voidshow_picture(const unsigned char tu[]) { unsigned char i,j; uint k=0; }

lcd_write_data(0,0x34); //图形方式 for(i=0;i<32;i++) { lcd_write_data(0,0x80+i); //Y lcd_write_data(0,0x80); //X for(j=0;j<16;j++) { lcd_write_data(1,tu[k]); k++; } }

for(i=0;i<32;i++) { lcd_write_data(0,0x80+i);//Y lcd_write_data(0,0x88); //X for(j=0;j<16;j++) { lcd_write_data(1,tu[k]); k++; } }

lcd_write_data(0,0x36);

/*

void LCDClear(void) //清屏 { lcd_write_data(0,0x01); //显示清屏 }

void LCDFlash(void) //闪烁效果 {

lcd_write_data(0,0x08); //显示清屏 lcd_delay_nms(4);

lcd_write_data(0,0x0c); // 显示开及光标设置 lcd_delay_nms(4);

lcd_write_data(0,0x08); //显示清屏 lcd_delay_nms(4);

lcd_write_data(0,0x0c); // 显示开及光标设置 lcd_delay_nms(4);

lcd_write_data(0,0x08); //显示清屏 lcd_delay_nms(4); }

voidlcd_draw_jpg(void) {

lcd_write_data(0,0x34); //绘图模式设置 lcd_set_xy(0,34); //设置坐标 x y lcd_write_data(1,0xff); //高八位 lcd_write_data(1,0xf1); //低八位 lcd_write_data(0,0x36); } */ /*

并行通信开始信号代码发送数据:0XFA 发送命令:0XF8 接收数据:0XFE 指令代码 进入基本指令集 0x30 清屏 0x01 光标右移 0x06

显示打开游标关游标位置关 0x0c 进入扩充指令集设定状态、关闭显示 开启绘图显示 0x36 配置lcd必须先进入相关的指令集

0X34

设置地址先垂直后水平读写都会改变AC的值

显示图片之前必须对对所有的GDRAM赋值,否则乱码

据网友说,读取数据只支持并行通信,试了多次,感觉网友说的没有错 读取数据之前必须空读一次 */

******************************************************************************************************************************************

game.h

******************************************************************************************************************************************

/******************************************************************************/

// Name: 游戏主函数 */ */ /* Designed by : Date:2016/5/25 */ /* 开发环境:ICCAVR */ /* QQ:1460467003 飘 */

/******************************************************************************/

//坐标点设定方块的左上方点 //方向参考屏幕正放

structsnake_type //定义一个砖块的结构体每次只写八位数据 {

unsigned char x_head; //头x坐标 0~63 unsigned char y_head; //头y坐标 0~63 unsigned char direc_head; //头前进的方向

unsigned char x_end; //尾x坐标 0~63 unsigned char y_end; //尾y坐标 0~63 unsigned char direc_end; //尾前进的方向 } snake;

//随机数据的缓存指针 unsignedintsuiji_num=0;

#define DOT_NUMBER_MAX 40

//x 0~63 两位为单位 y(偶数) 0~63 //点亮坐标对应的像素点

voidsnake_data_add(ucharx,uchar y) {

uchardata_h,data_l; switch(x & 0x07) { case 0:

{

lcd_set_xy(x >> 3, y); lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h|0xc0);

//lcd_write_data(1,data_l|(data<<6)); break; } case 1: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h|0x30);

//lcd_write_data(1,data_l|(data<<6)); break; } case 2: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h|0x0c);

//lcd_write_data(1,data_l|(data<<6)); break; } case 3: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h|0x03);

//lcd_write_data(1,data_l|(data<<6)); break; } case 4:

{

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l|0xc0); break; } case 5: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l|0x30); break; } case 6: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l|0x0c); break; } case 7: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l|0x03); break; } default :

break; } }

//x 0~63 两位为单位 y(偶数) 0~63 //熄灭坐标对应的像素点

voidsnake_data_dele(ucharx,uchar y) {

uchardata_h,data_l; switch(x & 0x07) { case 0: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h&0x3f);

//lcd_write_data(1,data_l&(~(data<<6))); break; } case 1: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h&0xcf);

//lcd_write_data(1,data_l&(~(data<<6))); break; } case 2: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h&0xf3);

//lcd_write_data(1,data_l&(~(data<<6))); break; } case 3:

{

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data();

//data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h&0xfc);

//lcd_write_data(1,data_l&(~(data<<6))); break; } case 4: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l&0x3f); break; } case 5: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l&0xcf); break; } case 6: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l&0xf3); break; } case 7:

{

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h = lcd_read_data(); data_l = lcd_read_data(); lcd_set_xy(x >> 3,y);

lcd_write_data(1,data_h);

lcd_write_data(1,data_l&0xfc); break; } default : break; } }

//x 0~63 两位为单位 y(偶数) 0~63 //读取坐标对应的像素点的值数据长度 2 ucharsnake_read_data(ucharx,uchar y) {

uchardata_h,data_l; switch(x & 0x07) { case 0: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); return (data_h>>6); break; } case 1: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); return ((data_h>>4)&0x03); break; } case 2: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); return ((data_h>>2)&0x03); break;

} case 3: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); return (data_h&0x03); break; } case 4: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); return (data_l>>6); break; } case 5: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); return ((data_l>>4)&0x03); break; } case 6: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); return ((data_l>>2)&0x03); break; } case 7: {

lcd_set_xy(x >> 3,y); lcd_read_data();

data_h=lcd_read_data(); data_l=lcd_read_data(); return (data_l&0x03); break;

} default : return 0; break; } }

//判断是否为障碍物返回值: 0无数据 // 1 苹果 // 2 障碍物 ucharcheck_down(ucharx,uchar y) {

if(snake_read_data(x,y+2)==0) return 0; else {

if(x>1&&snake_read_data(x-1,y+2)==3) return 2;

if(x<63&&snake_read_data(x+1,y+2)==3) return 2;

if(y<60&&snake_read_data(x,y+4)==3) return 2; return 1; } }

//判断是否为障碍物返回值: 0无数据 // 1 苹果 // 2 障碍物 ucharcheck_up(ucharx,uchar y) {

if(snake_read_data(x,y-2)==0) return 0; else {

if(x>1&&snake_read_data(x-1,y-2)==3) return 2;

if(x<63&&snake_read_data(x+1,y-2)==3) return 2;

if(y>3&&snake_read_data(x,y-4)==3) return 2; return 1; } }

//判断是否为障碍物返回值: 0无数据

// 1 苹果 // 2 障碍物 ucharcheck_right(ucharx,uchar y) {

if(snake_read_data(x+1,y)==0) return 0; else {

if(y>1&&snake_read_data(x+1,y-2)==3) return 2;

if(y<62&&snake_read_data(x+1,y+2)==3) return 2;

if(x<62&&snake_read_data(x+2,y)==3) return 2; return 1; } }

//判断是否为障碍物返回值: 0无数据 // 1 苹果 // 2 障碍物 ucharcheck_left(ucharx,uchar y) {

if(snake_read_data(x-1,y)==0) return 0; else {

if(y<62 &&snake_read_data(x-1,y+2)==3) return 2;

if(y>1&&snake_read_data(x-1,y-2)==3) return 2;

if(x>1&&snake_read_data(x-2,y)==3) return 2; return 1; } }

//记录转折点的位置及转折方向

//方向值 0,1,2,3 表示的方向为上左下右 struct {

unsigned char xy[DOT_NUMBER_MAX][4];//反指向正指向 x坐标 y坐标

signed char num_start; //指向蛇尾要更新的位置num_start与num_end一致时说明没有没有了转折点

signed char num_end; //指向下次新的转折点存储的位置

unsigned char dir; //值 0:反指向,数据递减更新 1:正指向,数据递增更

新 } p;

//蛇初始化

voidsnake_init(void) {

uchari;

p.num_start = 0; p.num_end = 0; p.dir = 1; //正向存储

for(i=0; i<3; i++) //画蛇 {

snake_data_add(i,62); snake_data_add(i,63); }

snake.x_head=2;

snake.y_head=62; //x轴 0~63 //y轴 snake.direc_head=3;

snake.x_end=0; snake.y_end=62; snake.direc_end=3; snake_data_add(10,62);//增加苹果 snake_data_add(10,63); }

//求两个数的差的绝对值 uchardiat(uchara,uchar b) {

if(a < b) return b - a; else

return a - b; }

//交换数据

voidswap_data(uchar *p1, uchar *p2) {

uchar data; data = *p1; *p1 = *p2; *p2 = data; }

//指针自加运算,越界处理 voiddata_add(signed char *p) {

++*p;

if(*p > DOT_NUMBER_MAX - 1) *p = 0; }

//指针自减运算,越界处理 voiddata_dec(signed char *p) {

--*p; if(*p < 0)

*p = DOT_NUMBER_MAX - 1; }

//头尾互换

void head_end_swap(void)//头尾互换 {

swap_data(&snake.x_head, &snake.x_end); //互换头尾的x swap_data(&snake.y_head, &snake.y_end); //互换头尾的y

swap_data(&snake.direc_head, &snake.direc_end); //互换头尾的方向

snake.direc_head=(snake.direc_head + 2) & 0x03; //头方向取反 snake.direc_end=(snake.direc_end + 2) & 0x03; //尾方向取反 }

//添加一个转折点 voidp_add(uchardir) { if(p.dir) //正向移动 {

//加载数据

p.xy[p.num_end][0] = (snake.direc_head + 2) & 0x03; //反指向 p.xy[p.num_end][1] = dir; //正指向 p.xy[p.num_end][2] = snake.x_head; //加载x坐标 p.xy[p.num_end][3] = snake.y_head; //加载y坐标

//更新缓存指针 data_add(&p.num_end); }

else //反向移动 {

//加载数据

p.xy[p.num_start][0] = dir; //反方向

p.xy[p.num_start][1] = (snake.direc_head + 2) & 0x03; //正方向

p.xy[p.num_start][2] = snake.x_head; //加载x坐标 p.xy[p.num_start][3] = snake.y_head; //加载y坐标

//更新缓存指针 data_dec(&p.num_start); } }

//转折点顺序取反 voidp_inverse(void) {

//更新缓存指针

if(p.dir) //之前正向移动 {

data_dec(&p.num_start); data_dec(&p.num_end); } else {

data_add(&p.num_start); data_add(&p.num_end); }

p.dir ^= 0x01; //取反 }

//输入:按键值 3 4 5 6 //表示的方向为上左下右 //改变方向,不改变坐标

ucharsnake_head_change(uchar key) {

uchar temp;

temp = diat(key, snake.direc_head); //获得方向差switch(temp) {

//同向 case 0: return 1;

//左转或右转 case 1:

p_add(key);//把当前数据加载到拐点缓存区 snake.direc_head = key; //更新蛇头方向 return 0;

//反方向

0 同向 1 左右拐2 反向 case 2:

p_inverse();//更改转折点

head_end_swap();//更换蛇头和蛇尾 return 0; //左转或右转 case 3:

p_add(key);//把当前数据加载到拐点缓存区 snake.direc_head = key; //更新蛇头方向 return 0; default : return 0; } }

//熄灭尾灯,更新尾部坐标 voidsnake_end_deal(void) {

//熄灭当前位置的点

snake_data_dele(snake.x_end,snake.y_end); snake_data_dele(snake.x_end,snake.y_end+1); if(p.dir) //正方向 { if(snake.x_end == p.xy[p.num_start][2] && snake.y_end == p.xy[p.num_start][3] &&

p.num_end != p.num_start) //蛇尾处在转折点处 {

snake.direc_end = p.xy[p.num_start][1]; //赋值改变尾巴方向 data_add(&p.num_start); } } else //反方向 { if(snake.x_end == p.xy[p.num_end][2] && snake.y_end == p.xy[p.num_end][3] &&

p.num_end != p.num_start) //蛇尾处在转折点处 { snake.direc_end = p.xy[p.num_end][0]; //赋值改变尾巴方向 data_dec(&p.num_end); } }

//改变坐标

switch(snake.direc_end)

{ case 0:

snake.y_end-=2; break; case 1:

snake.x_end--; break; case 2:

snake.y_end+=2; break; case 3:

snake.x_end++; break; } }

//方向值 0,1,2,3 表示的方向为上左下右 /* 函数功能:移动蛇遇到苹果则吃苹果遇到障碍物停下来 返回值:0 不可移动 1 可以移动 2 吃到苹果 */

ucharmove_forward(void) {

uchar data , flag = 2;

switch(snake.direc_head) {

case 0: //头朝上

data=check_up(snake.x_head,snake.y_head); if(snake.y_head< 1 || data==2)//不能移动 flag = 0; else

{

snake.y_head -= 2;

if(data==0) //可以移动 {

snake_data_add(snake.x_head,snake.y_head); snake_data_add(snake.x_head,snake.y_head+1); snake_end_deal(); flag = 1;

} } break;

case 1: //头朝左

data=check_left(snake.x_head,snake.y_head);

if(snake.x_head< 1 || data == 2)//不能移动 flag = 0; else

{

snake.x_head--;

if(data == 0)//可以移动 {

snake_data_add(snake.x_head,snake.y_head); snake_data_add(snake.x_head,snake.y_head+1); snake_end_deal(); flag = 1;

} } break;

case 2: //头朝下

data=check_down(snake.x_head,snake.y_head); if(snake.y_head>61 || data==2)//不能移动 flag = 0; else

{

snake.y_head+=2;

if(data==0)//可以移动 {

snake_data_add(snake.x_head,snake.y_head); snake_data_add(snake.x_head,snake.y_head+1); snake_end_deal(); flag = 1;

} } break; case 3: //头朝右

data=check_right(snake.x_head,snake.y_head);

if(snake.x_head>62 || data == 2)//不能移动 flag = 0; else

{

snake.x_head++;

if(data==0)//可以移动 {

snake_data_add(snake.x_head,snake.y_head); snake_data_add(snake.x_head,snake.y_head+1); snake_end_deal(); flag = 1;

} } break; default: break; } return flag; } /* 函数功能: 画一个有效的苹果然后退出 */

voidappel_add(constuint *data) {

ucharxx,yy; while(1) {

xx = data[suiji_num] & 0x1f; //获得新的苹果的坐标x yy = data[suiji_num+1] & 0x1f; //获得新的苹果的坐标y if(yy& 0x01) yy--;

//判断新的苹果所在位置是否已经点亮,已经点亮:重新计算获得坐标 // 熄灭:画苹果,退出while(1) if(snake_read_data(xx,yy)==0) {

snake_data_add(xx,yy); snake_data_add(xx,yy+1); break; }

suiji_num++;

if(suiji_num==125) suiji_num=0; } }

******************************************************************************************************************************************

key.h

******************************************************************************************************************************************

/******************************************************************************/ /* Name: key */ /* PD2 PD3 PA4 PA5 对应S1~S4 */

/* Designed by : Date:2016/5/25 */

/* 开发环境:ICCAVR */ /* QQ:1460467003 飘 */

/******************************************************************************/

#define uchar unsigned char #define uint unsigned int

uchar times=14; //产生延迟函数 voids_us(unsigned int t) {

for(;t>1;t--); }

ucharkey_scan(void) { uchar key; DDRD|=0X0C; PORTD|=0X0C; DDRD&=0XF3; DDRA|=0X30; PORTA|=0X30; DDRA&=0XCF; key=(PINA&0X30)|(PIND&0x0c); if(key==0x3c) return 0; else return 1; }

ucharkey_press(void) { uchar key1; if(key_scan) s_us(500); key1=(PINA&0X30)|(PIND&0x0c); switch(key1) { case 0x38:s_us(500); //while(key_scan()); return 0; //key3 上 case 0x34: s_us(500);

}

}

//while(key_scan());

return 2; //key4 下 case 0x2c:s_us(500); //while(key_scan()); return 1; //key5 左 case 0x1c: s_us(500); //while(key_scan()); return 3; //key6 右 default : // s_us(100); return 4;

//循环多次扫描按键,在此期间,蛇没有发生变化,所以只进行一次数据读取,有效数据为

//最后按下的按键

voidsnake_move_scan(uchar time) {

uint i,j,k1 = 5,k2 = 4; for(j=0;j

****************************************************************************************************************************************** Picture_library.h

****************************************************************************************************************************************** const signed char direc5[4]={1,-1,2,-2}; //伪随机函数值

const unsigned char rand_data1[31]={7,3,5,5,9,6,5,4,6,7,9,6,6,6,2,4,0,2,3,2,3,9,5,7,0,4,3,2,3,4,7};

const unsigned intsuiji_data[260]={

462,682,342,054,674,842,918,524,728,674,672,354,118,312,276,448,662,394,436,142, 714,694,544,838,968,142,118,802,184,688,530,152,862,972,136,718,486,384,134,248, 756,734,254,824,460,668,580,518,938,474,298,924,808,688,184,834,382,140,626,276, 124,562,242,538,860,428,866,914,718,416,948,819,792,640,636,648,118,380,758,404,

638,626,214,842,196,464,926,188,792,214,214,884,308,388,106,072,470,214,578,422, 378,670,114,424,382,356,242,146,494,426,298,572,464,192,284,344,484,292,494,282, 678,846,914,932,952,154,572,238,346,662,612,144,498,970,522,592,958,358,582,354, 966,196,464,764,618,264,444,328,958,224,143,182,634,570,418,474,850,690,896,118, 496,786,936,264,548,192,378,896,158,948,218,178,518,316,644,176,916,832,494,378, 196,696,404,114,852,514,988,878,134,614,802,858,324,986,294,984,666,354,660,436, 846,310,764,344,128,328,168,624,826,730,722,054,828,874,684,188,168,370,360,498, 616,754,494,634,860,326,268,718,198,846,114,348,888,512,196,978,282,178,952,938, 666,374,176,984,324,972,344,458,544,846,312,680,324,586,852,616,024,118,694,780, };

//游戏结束画面

const unsigned char game_over[]={

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x1F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x01,0xC0,0x01,0x80,0x14,0x00,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x03,0x20,0x00,0x80,0x12,0x03,0x00,0x40,0x10,0x00,0x00,0x03,0xBB,0x7C,0x00, 0x00,0x06,0x00,0x08,0x80,0x12,0x03,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x04,0x00,0x10,0x40,0x32,0x05,0x00,0x80,0x30,0x00,0x00,0x00,0x00,0x10,0x00, 0x00,0x04,0x00,0x10,0x40,0x21,0x09,0x00,0x80,0x60,0x00,0x00,0x00,0x00,0x10,0x00, 0x00,0x04,0x00,0x10,0x40,0x21,0x09,0x00,0x83,0xC0,0x00,0x00,0x38,0x18,0x18,0x00, 0x00,0x04,0x00,0x10,0x40,0x21,0x11,0x00,0xBE,0x00,0x00,0x01,0x06,0x1E,0x08,0x00, 0x00,0x04,0x00,0x37,0xE0,0x21,0x21,0x80,0x80,0x00,0x00,0x01,0x02,0x33,0x08,0x00, 0x00,0x04,0x00,0x20,0x20,0x20,0xA0,0x80,0x80,0x00,0x00,0x01,0x82,0x31,0x08,0x00, 0x00,0x06,0x08,0x20,0x30,0x20,0xC0,0x80,0x80,0x00,0x00,0x00,0x82,0x11,0x0C,0x00, 0x00,0x03,0x08,0x60,0x10,0x20,0xC0,0x80,0xC0,0x00,0x00,0x00,0xC6,0x17,0x04,0x00, 0x00,0x01,0x88,0x60,0x18,0x20,0xC0,0x80,0x40,0x00,0x00,0x00,0xCE,0x00,0x04,0x00, 0x00,0x00,0xF8,0x60,0x18,0x20,0x00,0x00,0x60,0x00,0x00,0x00,0xFC,0x00,0x04,0x00, 0x00,0x00,0x10,0x00,0x18,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x28,0x00,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x38,0x00,0x00,0x00,0x00,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x00,0x06,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x84,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC8,0x00, 0x00,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x00, 0x00,0x03,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00, 0x00,0x01,0x0C,0x30,0x00,0x81,0xF8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x01,0x04,0x10,0x00,0x81,0x0C,0x01,0x00,0x00,0x00,0x00,0x3F,0xFF,0xFE,0x00, 0x00,0x01,0x02,0x08,0x01,0x83,0x06,0x01,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x01,0x02,0x08,0x01,0x02,0x02,0x01,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x01,0x82,0x0C,0x01,0x02,0x06,0x01,0x70,0x00,0x00,0x00,0x00,0x00,0x10,0x00, 0x00,0x00,0x82,0x04,0x03,0x07,0xFC,0x00,0xC0,0x00,0x00,0x3F,0xC0,0x00,0x10,0x00, 0x00,0x00,0x82,0x04,0x0C,0x04,0x00,0x00,0xC0,0x00,0x00,0x10,0x40,0x00,0x18,0x00, 0x00,0x00,0xC2,0x02,0x08,0x04,0x00,0x00,0x80,0x00,0x00,0x10,0x40,0x00,0x08,0x00, 0x00,0x00,0x62,0x03,0x30,0x04,0x00,0x00,0x80,0x00,0x00,0x10,0x40,0x78,0x08,0x00, 0x00,0x00,0x1E,0x01,0x20,0x02,0x00,0x00,0x80,0x00,0x00,0x18,0x40,0x48,0x08,0x00, 0x00,0x00,0x00,0x01,0xC0,0x03,0x00,0x00,0xC0,0x00,0x00,0x0F,0xC0,0xC8,0x08,0x00, 0x00,0x00,0x00,0x00,0x80,0x01,0xFF,0x80,0xC0,0x00,0x00,0x0C,0x00,0x48,0x08,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x48,0x08,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x78,0x08,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x10,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x10,0x00, 0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x30,0x00, 0x00,0xE1,0x80,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x20,0x00, 0x1F,0x87,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x06,0x20,0x00, 0x33,0x1C,0x00,0x03,0xF8,0x00,0x01,0x00,0x00,0x1C,0x0A,0x00,0x00,0x02,0x20,0x00, 0x01,0x04,0x00,0x00,0x22,0x00,0x01,0x7C,0x00,0x14,0x12,0x00,0x80,0x01,0x20,0x00, 0x01,0x07,0xF0,0x00,0x26,0x00,0x01,0x06,0x00,0x12,0x12,0x00,0x80,0x10,0xE0,0x00, 0x01,0x02,0x00,0x00,0x2C,0x01,0x81,0x01,0x80,0x12,0x21,0x00,0x80,0x10,0xC0,0x00, 0x01,0x03,0xC0,0x00,0x30,0x01,0x81,0x00,0xC0,0x12,0x21,0x00,0x80,0x10,0x00,0x00, 0x01,0x02,0x30,0x0F,0xFF,0xE0,0x01,0x00,0x20,0x11,0x41,0x00,0x40,0x10,0x00,0x00, 0x01,0x07,0x80,0x03,0xF8,0x00,0x01,0x00,0x20,0x11,0x40,0x00,0x40,0x10,0x00,0x00, 0x01,0x06,0xF8,0x1E,0x27,0x00,0x01,0x00,0x20,0x11,0x41,0x00,0x40,0x10,0x00,0x00, 0x01,0x06,0x00,0x30,0x61,0x00,0x01,0x00,0x20,0x11,0xC1,0x00,0x40,0x10,0x00,0x00, 0x00,0x06,0x00,0x00,0x6F,0x00,0x01,0x00,0x20,0x10,0xC0,0x80,0x60,0x10,0x00,0x00, 0x00,0x06,0x00,0x00,0x21,0x01,0x81,0x00,0x20,0x10,0xC0,0x80,0x20,0x10,0x00,0x00, 0x00,0x00,0x00,0x00,0x21,0x01,0x81,0x00,0x20,0x00,0x40,0x80,0x20,0x30,0x00,0x00, 0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0x00,0x60,0x00,0x00,0x80,0x30,0x20,0x00,0x00, 0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0xC0,0x00,0x00,0x80,0x0F,0xC0,0x00,0x00, 0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, };

两年前编的,最近整理了一下,做了一些优化。修复了一些bug,希望对读者有所帮助。 喜欢的话就好评,谢谢!

Atmega16单片机贪吃蛇小游戏 

Atmega16单片机贪吃蛇小游戏程序原创,好用!缺少财富值的可以私信我,我发给你。代码中有qq代码基于Atmega16芯片,晶振采用8M,LCD12864采用并行通信,四个独立按键,以下是相关的原理图。控制贪吃蛇前进的核心思路是:点亮头部,熄灭尾部。关于蛇身子的点可以采用一个数组来存储。把数组
推荐度:
点击下载文档文档为doc格式
5dsor58ch999g5n13tny9pg7z7hdvh00te7
领取福利

微信扫码领取福利

微信扫码分享