单片机设计_俄罗斯方块游戏(AT89C51 LCD12864)

51单片机游戏(俄罗斯方块)

想要更多项目私wo!!!

一、电路设计

此电路由AT89C51最小系统、12864显示模块和独立按键组成。
可实现类似俄罗斯方块的游戏。

二、运行效果

在这里插入图片描述

三、部分代码

/*想要更多项目私wo!!!*/
#include <REGX52.H>
#include"pic.c"
#include <intrins.h>
#define LCD_DATA P2
#define button_delay 150  //按键延时
#define button_acceleration 65  //按键加速度阈值
#define GAME_LOCATION 30
sbit button_a = P3^4;	 //变形
sbit button_b = P3^5;	//开始
sbit up = P3^2;	   //暂停开始
sbit down = P3^0;
sbit left = P3^1;
sbit right = P3^3;
sbit speaker=P3^6; 

sbit LCD_RS=P1^0;
sbit LCD_RW=P1^1;
sbit LCD_E=P1^2;
sbit LCD_CS2=P1^4;		//右屏选择(左右屏有时候相反)
sbit LCD_CS1=P1^3;		//左屏选择
sbit LCD_RST=P3^7;

unsigned int up_reg=button_delay;       //按键up累加器
unsigned int down_reg=button_delay;     //按键down累加器
unsigned int left_reg=button_delay;     //按键left累加器
unsigned int right_reg=button_delay;    //按键right累加器
unsigned int button_a_reg=button_delay; //按键button_a累加器
unsigned int button_b_reg=button_delay; //按键button_b累加器
unsigned int right_acceleration=0;		//按键right加速度寄存器
unsigned int left_acceleration=0;		//按键left加速度寄存器

unsigned int idata Box_Ram[19];//定义游戏点阵缓存10*16
unsigned char box_down_reg;//定义方块下落累加寄存器
unsigned char time0_reg;//定义定时器0累加寄存器
unsigned char next_mode;//定义下一个方块的类型
unsigned char next_shape;//定义下一个方块的形状
unsigned int destroy_row_num=0;//定义所消的行数
unsigned char speed_num=0;//定义游戏速度等级
unsigned char level_num;//定义游戏难度等级
bit game_over_flag;//游戏结束标志位置0表示游戏未结束
bit pause_game_flag;//游戏暂停标志位置0表示游戏未暂停

struct
{
	unsigned char mode;//类型
	unsigned char shape;//形状
	unsigned char x;//x坐标
	unsigned char y;//y坐标
	unsigned int box;//定义方块缓存
}s_box;	//定义方块结构体
//LCD检测忙状态函数
void LCD_check_busy()
{
	unsigned char temp;
	LCD_RS=0;
	LCD_RW=1;
	do
	{
		LCD_DATA=0xff;
		LCD_E=1;
		temp=LCD_DATA;
		LCD_E=0;
	}while((temp&0x80)==0x80);		
}
//写指令代码(cs为0选左屏,cs为1选右屏)
void LCD_W_code(unsigned char tpcode,bit cs)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_CS2=~cs;
	LCD_CS1=cs;
	LCD_DATA=tpcode;
	LCD_E=1;
	_nop_();
	LCD_E=0;
}
//写显示数据(cs为0选左屏,cs为1选右屏)
void LCD_W_data(unsigned char tpdata,bit cs)
{
	LCD_check_busy();
	LCD_RS=1;
	LCD_RW=0;
	LCD_CS2=~cs;
	LCD_CS1=cs;	
	LCD_DATA=tpdata;
	LCD_E=1;	
	_nop_();
	LCD_E=0;
}

//LCD初始化函数
void LCD_initialize()
{
	LCD_RST=0;
	_nop_();
	_nop_();
	LCD_RST=1;
	LCD_W_code(0x3f,0);		//开显示设置	
	LCD_W_code(0xc0,0);		//设置显示起始行为第一行	
	LCD_W_code(0xb8,0);		//页面地址设置	
	LCD_W_code(0x40,0);		//列地址设为0
	LCD_W_code(0x3f,1);
	LCD_W_code(0xc0,1);	
	LCD_W_code(0xb8,1);
	LCD_W_code(0x40,1);
}
//LCD清屏函数
void LCD_clear()
{
	unsigned char i,j;
	for(j=0;j<8;j++)
	{
		LCD_W_code(0xb8+j,0);
		LCD_W_code(0x40,0);
		LCD_W_code(0xb8+j,1);
		LCD_W_code(0x40,1);
		for(i=0;i<64;i++)
			{	
				LCD_W_data(0x00,0);	
				LCD_W_data(0x00,1);
			}
	}
}
//LCD显示字符串函数(word表示要显示的字符串,
 //length表示要显示的字符串宽度,
 //x表示首字符所在行数,
 //y表示首字符所在列数)
void LCD_display_word(unsigned char word[],
                      unsigned int length,
					  unsigned char x,
					  unsigned char y)
{
	unsigned char i;
	for(i=0;i<length;i++)
	{
		
		LCD_W_code(0xb8+x,0);
		LCD_W_code(0xb8+x,1);
		if(y+i<64)
		{
			LCD_W_code(0x40+y+i,0);	
			LCD_W_data(word[i],0);
		}
		else
		{
			LCD_W_code(y+i,1);	
			LCD_W_data(word[i],1);
		}
	}
}
//LCD画全屏函数
void LCD_full_draw(unsigned char word[])
{
	unsigned char i,j;
	for(i=0;i<8;i++)
	{
		LCD_W_code(0xb8+i,0);
		LCD_W_code(0x40,0);	
		for(j=0;j<64;j++)
		{
			LCD_W_data(word[i*128+j],0);
		}
		LCD_W_code(0xb8+i,1);
		LCD_W_code(0x40,1);	
		for(j=0;j<64;j++)
		{
			LCD_W_data(word[i*128+64+j],1);
		}			
	}
}
//LCD显示一个字节函数(
  //x表示x坐标,
  //y表示y坐标,
  //tpdata表示要显示的数据)
void LCD_display_byte(unsigned char x,
					  unsigned char y,
					  unsigned char tpdata)
{
	if(x<64)
	{
		LCD_W_code(0xb8+y,0);
		LCD_W_code(0x40+x,0);
		LCD_W_data(tpdata,0);	
	}
	else
	{
		LCD_W_code(0xb8+y,1);
		LCD_W_code(x,1);
		LCD_W_data(tpdata,1);	
	}
} 

void LCD_draw(unsigned char word[])
{
  unsigned char i,j;
  for(i=0;i<8;i++)
  {
    LCD_W_code(0xb8+i,1);
	LCD_W_code(0x40+20,1);
	for(j=0;j<44;j++)
	{
	  LCD_W_data(word[i*44+j],1);
	}
  }
}
//基本界面显示函数
void display_basic()
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		LCD_display_byte(GAME_LOCATION,i,0xff);
		LCD_display_byte(GAME_LOCATION+41,i,0xff);
	}
}
//刷新游戏区域函数
void refurbish_display()
{
	unsigned char i,j,tpdata;
	for(i=0;i<8;i++)
	{
		for(j=0;j<10;j++)
		{
			tpdata=0x00;
			if(  (Box_Ram[2*i]>>(12-j))&0x0001==1  )
			{
				tpdata=0x0f;
			}
			if(  (Box_Ram[2*i+1]>>(12-j))&0x0001==1  )
			{
				tpdata|=0xf0;
			}
			LCD_display_byte(GAME_LOCATION+1+j*4,i,tpdata);
			LCD_display_byte(GAME_LOCATION+2+j*4,i,0xbb&tpdata);
			LCD_display_byte(GAME_LOCATION+3+j*4,i,0xdd&tpdata);
			LCD_display_byte(GAME_LOCATION+4+j*4,i,tpdata);
		}
	}
}
  • 9
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值