基于51单片机的打地鼠游戏机1602和led显示模拟(源码齐全)
- 格式:doc
- 大小:1.69 MB
- 文档页数:45
.《现代通信技术》课程设计基于51单片机的模拟打地鼠游戏设计院系:工学院专业班级:通信工程10秋2班姓名:钟丽薇学号:10032202小组成员:陆韵指导教师:徐振、赵兰完成日期2013年10月目录1 设计任务 (1)1.1设计题目及材料 (1)1.2设计要求 (1)1.3设计进度安排 (2)2 总体方案 (3)2.1硬件设计 (3)2.1.1 主控芯片 (3)2.1.2 数码管模块 (4)2.1.3 LED模块 (5)2.1.4 独立按键模块 (5)2.2软件设计 (6)3 功能调试 (7)3.1调试过程 (7)3.2调试中遇到的问题 (7)4 设计总结 (8)5 致谢 (9)1 设计任务通过本次课程设计,运用已学的课程知识,自主设定题目及要求,进行软硬件系统的设计和调试,对《现代通信技术》课程中涉及的芯片结构、控制原理、硬件和编程等方面有一定的感性认识和实践操作能力,从而加深对本课程知识点的理解,使应用知识能力、设计能力、调试能力以及报告撰写能力等方面有显著提高。
1.1 设计题目及材料我们的课程设计选题定为《基于51单片机的模拟打地鼠游戏设计》。
将所掌握的的元器件组合在一起,设计出具有可玩性的实用小制作,不仅巩固了已学习的知识,更能拓展自己的思维能力。
所用到的材料:表1.1 材料列表STC89C52单片机开发板1块4位8段数码管(共阳)1个LED灯5个轻触按键5个100Ω电阻5个0.5kΩ电阻4个9013三极管4个杜邦线若干1.2 设计要求要求作品完成后,可以实现简易打地鼠游戏的功能。
具体如下:接通电源后,游戏开始,数码管显示“0”,同时随意点亮一个LED,在2秒时间内按下对应的按键,则数码管示数加一,游戏继续;反之,则示数归零,游戏结束1.3 设计进度安排表1.2 设计进度安排10月21日(周一) 收集资料,确定选题,大致设计方案10月22日(周二) 设计电路图,采购所需材料10月23日(周三) 完成具体设计,组装电路板10月24日(周四) 完成硬件部分,完成部分论文编写程序;软硬件调试10月28日(周一) 至10月29日(周二)10月30日(周三) 最终调试,完成论文2 总体方案2.1 硬件设计采用AT89S52为主控芯片的单片机开发板,选取共阳四位八段数码管作为计分显示,以及5个LED和5个独立按键分别制作模块,通过杜邦线连接到单片机上,使其成为一个为简易的游戏机。
基于51单片机的红外遥控+液晶LCD1602显示程序源代码/*******************红外遥控+液晶LCD1602测试程序源代码******************** 单片机型号:STC15W4K56S4,内部晶振:22.1184M。
功能:红外遥控+液晶LCD1602显示功能测试。
操作说明:按下红外遥控器上的“CH-”键,液晶LCD1602上显示“CH-”。
按下红外遥控器上的“CH”键,液晶LCD1602上显示“CH”。
按下红外遥控器上的“CH+”键,液晶LCD1602上显示“CH+”。
按下红外遥控器上的“|<<”键,液晶LCD1602上显示“|<<”。
按下红外遥控器上的“>>|”键,液晶LCD1602上显示“>>|”。
按下红外遥控器上的“>||”键,液晶LCD1602上显示“>||”。
按下红外遥控器上的“-”键,液晶LCD1602上显示“-”。
按下红外遥控器上的“+”键,液晶LCD1602上显示“+”。
按下红外遥控器上的“EQ”键,液晶LCD1602上显示“EQ”。
按下红外遥控器上的“0”键,液晶LCD1602上显示“0”。
按下红外遥控器上的“100+”键,液晶LCD1602上显示“100+”。
按下红外遥控器上的“200+”键,液晶LCD1602上显示“200+”。
按下红外遥控器上的“1”键,液晶LCD1602上显示“1”。
按下红外遥控器上的“2”键,液晶LCD1602上显示“2”。
按下红外遥控器上的“3”键,液晶LCD1602上显示“3”。
按下红外遥控器上的“4”键,液晶LCD1602上显示“4”。
按下红外遥控器上的“5”键,液晶LCD1602上显示“5”。
按下红外遥控器上的“6”键,液晶LCD1602上显示“6”。
按下红外遥控器上的“7”键,液晶LCD1602上显示“7”。
按下红外遥控器上的“8”键,液晶LCD1602上显示“8”。
51单片机驱动1602液晶显示器c程序/*程序效果:单片机控制液晶显示器1602 显示字母数字,用户自行更改io程序原创安全:51hei*/#includereg52.h //头文件#define uchar unsigned char //宏定义#define uint unsigned intuchar code table[]=“51HEI XING XING “ ; //显示的字母uchar code table1[]=“51HEI MCUXUE YUAU” ;sbit lcdrs=P1; //寄存器选择引脚sbit lcdwr=P1;//读写引脚sbit lcde=P1 ; //片选引脚void delay(uchar x) //延时子函数{uchar i,j;for(i=x;i0;i--) for(j=110;j0;j--);}void write_com(uchar com) //写指令子函数{ //根据1602 液晶显示器协议编写P2=com; lcdrs=0;lcdwr=0;delay(5);lcde=0; delay(5);lcde=1; }void write_dat(uchar dat) //写数据子函数{P2=dat; lcdrs=1;lcdwr=0;delay(5);lcde=0;delay(5);lcde=1;}void init() //初始化子函数{write_com(0x01); //清屏write_com(0x3f); //功能设置write_com(0x0d); //显示控制write_com(0x06); //输入方式设置}void main(){ uchar i; //定义局部变量init();write_com(0x80+0x02+0x10); //指针的位置for(i=0;i15;i++) //显示{ write_dat(table[i]); delay(50); //延时,用于调节速度不匹配}write_com(0x80+0x40+0x10);for(i=0;i16;i++){ write_dat(table1[i]); delay(50);}for(i=0;i16;i++){ write_com(0x18); delay(50);} while(1);}tips:感谢大家的阅读,本文由我司收集整编。
LCD显示电路#include<reg51.h>sbit RS=P3^7; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P3^6; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^7; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,将BF位定义为P0.7引脚#define Lcd_Data P0#include <string.h>#include<intrins.h> //包含_nop_()函数定义的头文件unsigned char code string1[ ]={0x77,0x75,0x20,0x79,0x61,0x6E,0x67,0x20,0x79,0x61,0x6E,0x67,0x20,0x20,0x20,0x20}; //第一行显示的字符void Lcd_delay1ms() // 函数功能:延时1ms//注:不同单片机不同晶振需要对此函数进行修改{ unsigned char i,j;for(i=0;i<90;i++)for(j=0;j<33;j++);}void Lcd_delay(unsigned int n) // 函数功能:延时若干毫秒,入口参数:n{ unsigned int i;for(i=0;i<n;i++)Lcd_delay1ms();}/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。
result=1,忙碌;result=0,不忙***************************************************/bit Lcd_BusyTest(void)bit result;RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态RW=1;E=1; //E=1,才允许读写_nop_(); //空操作_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间result=BF; //将忙碌标志电平赋给resultE=0;return result;}/*****************************************************函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictate***************************************************/void Lcd_WriteCom (unsigned char dictate){ while(Lcd_BusyTest()==1); //如果忙就等待RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令RW=0;E=0; //E置低电平(写指令时就是让E从0到1发生正跳变,所以应先置ぜ? _nop_();_nop_(); //空操作两个机器周期,给硬件反应时间Lcd_Data=dictate; //将数据送入P0口,即写入指令或地址_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:指定字符显示的实际地址x入口参数:注:此函数已经加上了0x80,故只需写上实际地址就行***************************************************/void Lcd_WriteAddress(unsigned char x){ Lcd_WriteCom(x|0x80); //显示位置的确定方法规定为80H+地址码x/*****************************************************函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y(为字符常量)***************************************************/void Lcd_WriteData(unsigned char y){while(Lcd_BusyTest()==1);RS=1; //RS为高电平,RW为低电平时,可以写入数据RW=0;E=0; //E置低电平(写指令时就是让E从0到1发生正跳变所以应先置ぜ?Lcd_Data=y; //将数据送入P0口,即将数据写入液晶模块_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:对LCD的显示模式进行初始化设置***************************************************/void Lcd_Int(void){Lcd_delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间Lcd_WriteCom(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口Lcd_delay(5); //延时5msLcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);设置模式次写9// Lcd_WriteCom(0x38);Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x38); //9次写设置模式Lcd_delay(5);Lcd_WriteCom(0x0C); //显示模式设置:显示开,有光标,光标闪烁Lcd_delay(5);Lcd_WriteCom(0x06); //显示模式设置:光标右移,字符不移Lcd_delay(5);Lcd_WriteCom(0x01); //清屏幕指令,将以前的显示内容清零Lcd_delay(5); }void hanying_show(void){unsigned char Lcd_i;Lcd_WriteCom(0x01);//清显示:清屏幕指令Lcd_delay(2);Lcd_WriteAddress(0x00); // 设置显示位置为最左侧Lcd_delay(2);Lcd_i=0;while(string1[Lcd_i]!='\0') //'\0'是数组结束标志需先将字符存入{Lcd_WriteData(string1[Lcd_i]); // 显示字符Lcd_i++;Lcd_delay(4);}}void main(){Lcd_Int(); //1602初始化while(1){hanying_show();}}。
51单片机好学1602全过程C语言编程显示很全的哦阿拉教你轻松学51系列〔就抽精品〕发布: 2021-2-05 16:03 | 作者: tiankai | 来源: 电子园51单片机学习网阿拉1602液晶的正面(绿色背光,黑色字体)1602液晶反面(绿色背光,黑色字体)另一种1602液晶模块,显示屏是蓝色背光白色字体字符型LCD1602通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,引脚定义如下表所示:HD44780内置了DDRAM、CGROM 和CGRAM。
DDRAM就是显示数据RAM,用来存放待显示的字符代码。
共80个字节,其地址和屏幕的对应关系如下表:也就是说想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A〞字的代码就行了。
但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。
那么一行可有40个地址呀?是的,在1602中我们就用前16个就行了。
第二行也一样用前16个地址。
对应如下:DDRAM地址与显示位置的对应关系〔事实上我们往DDRAM里的00H地址处送一个数据,譬如0x31(数字1的代码)并不能显示1出来。
这是一个令初学者很容易出错的地方,原因就是如果你要想在DDRAM 的00H地址处显示数据,那么必须将00H加上80H,即80H,假设要在DDRAM的01H 处显示数据,那么必须将01H加上80H即81H。
依次类推。
大家看一下控制指令的的8条:DDRAM地址的设定,即可以明白是怎么样的一回事了〕1602液晶模块内部的字符发生存储器〔CGROM)已经存储了160个不同的点阵字符图形,如下表所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比方大写的英文字母“A〞的代码是01000001B〔41H〕,显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A〞上表中的字符代码与我们PC中的字符代码是根本一致的。
C语言源代码//======================================================依次可以从键盘输入0-f,在1602LCD上显示出来(此程序在所买开发板上验证通过)//======================================================//******** 小波电子工作室All rights reserved******//******** 个人主页:/niejinbo **//******** 文件名:lcd_key.1.c ************//******** 功能概要:4*4矩阵键盘扫描***********//******** MCU: STC89C52 晶振:11.0592Mhz **********//******** 设计者:聂金波************//******** 完成日期:2008-07-14 ************//******** 当前版本:0714.1 ************//******** 改进说明:暂无************//******** 补充说明: 从键盘输入0-F,在LCD上显示出来//*********头文件区*******************#include<reg52.h>#include<math.h>#include<absacc.h>#define uchar unsigned char#define uint unsigned int//*********定义变量区*******************sbitdula=P2^6; //关闭数码管显示之用sbitwela=P2^7;sbitlcden=P3^4; //LCD使能信号sbitlcdrs=P3^5; //LCD数据/命令选择信号uchartab_key[50];uchar code tab[]="0123456789abcdef";uchar n=0,temp,key;//*********函数声明区********************void lcd_disp(); //LCD显示函数void lcd_init(); //LCD初始化函数void write_com(uchar); //写命令函数void write_data(uchar); //写数据函数void delay(uint); //延迟函数void key_scan(); //键盘扫描函数void key_manage1(); //键盘功能分配函数void key_manage2();void key_manage3();void key_manage4();void key_manage5();void key_manage6();void key_manage7();void key_manage8();void key_manage9();void key_manage10();void key_manage11();void key_manage12();void key_manage13();void key_manage14();void key_manage15();void key_manage16();//**********主函数开始**********void main(){lcd_init();write_com(1);while(1){key_scan();lcd_disp();}}//**********LCD显示函数开始***********voidlcd_disp(){uchara,i=0;write_com(0x80);for(i=0;i<n;i++){a=tab_key[i];write_data(tab[a]);}}//**********LCD初始化函数开始*********voidlcd_init(){dula=0;wela=0; // 关闭数码管显示lcden=0;write_com(0x38); //设置显示模式:16X2,5X7,8位数据接口write_com(0x0c); //开显示,显示光标,光标闪烁write_com(0x06); //读写一个字符后,地址指针及光标加一,且光标加一整屏显示不移动write_com(0x80); //设置光标指针}//**********写命令函数开始************voidwrite_com(uchar com){lcdrs=0; //低电平写命令P0=com; //写入命令delay(3); //延时约3mslcden=1; //LCD使能端置高电平delay(5); //延时约5mslcden=0; //LCD使能端拉低电平}//**********写数据函数开始************voidwrite_data(uchardat){lcdrs=1; //低电平写数据P0=dat; //写入命令delay(3); //延时约3mslcden=1; //LCD使能端置高电平delay(5); //延时约5mslcden=0; //LCD使能端拉低电平}//**********键盘扫描函数开始****voidkey_scan()//**********扫描第一行********* P3=0xfe;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(100);if(temp!=0xf0){temp=P3;switch(temp){case 0xee:key_manage1();break;case 0xde:key_manage2();break;case 0xbe:key_manage3();break;case 0x7e:key_manage4();break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//**********扫描第二行********* P3=0xfd;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(100);if(temp!=0xf0)temp=P3;switch(temp){case 0xed:key_manage5();break;case 0xdd:key_manage6();break;case 0xbd:key_manage7();break;case 0x7d:key_manage8();break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//**********扫描第三行********* P3=0xfb;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(100);if(temp!=0xf0){temp=P3;switch(temp){case 0xeb:key_manage9();break;case 0xdb:break;case 0xbb:key_manage11();break;case 0x7b:key_manage12();break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//**********扫描第四行********* P3=0xf7;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(100);if(temp!=0xf0){temp=P3;switch(temp){case 0xe7:key_manage13();break;case 0xd7:key_manage14();break;case 0xb7:key_manage15();break;case 0x77:break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}}//*********延时函数开始************** void delay(uint k){uinti,j;for(i=k;i>0;i--)for(j=50;j>0;j--);}//******键盘功能分配函数群开始******** // 键盘功能示意图// 设计者:聂金波//** 1 ** 2 ** 3 ** 4 **//** 5 ** 6 ** 7 ** 8 **//** 9 ** 0 ** s ** c **//** M1** M2** M3** M4**void key_manage1(){tab_key[n]=0;n++;}void key_manage2(){tab_key[n]=1;n++;}void key_manage3() {tab_key[n]=2;n++;}void key_manage4() {tab_key[n]=3;n++;}void key_manage5() {tab_key[n]=4;n++;}void key_manage6() {tab_key[n]=5;n++;}void key_manage7() {tab_key[n]=6;n++;}void key_manage8() {tab_key[n]=7;n++;}void key_manage9() {tab_key[n]=8;n++;}void key_manage10()tab_key[n]=9;n++;}void key_manage11(){tab_key[n]=10;n++;}void key_manage12(){tab_key[n]=11;n++;}void key_manage13(){tab_key[n]=12;n++;}void key_manage14(){tab_key[n]=13;n++;}void key_manage15(){tab_key[n]=14;n++;}void key_manage16(){tab_key[n]=15;n++;}Proteus仿真图依次从键盘输入:abcd 277817639 (本人QQ号)4X4矩阵键盘-Proteus截图。
编号:桂林电子科技大学信息科技学院单片机原理及串口技术实训论文说明书题目:打地鼠游戏机系别:机电工程系专业:机械电子工程学生姓名:朱子任学号:1453200122指导教师:莫荣职称:教授题目类型:理论研究实验研究软件开发应用研究2015 年6月20 日独创性声明本人郑重声明:所呈交的学位论文,是本人在导师的指导下,独立进行研究工作所取得的成果。
除文中已经注明引用的内容外,本论文不含任何其他个人或集体已经发表或撰写过的作品成果。
对本文的研究做出重要贡献的个人和集体,均已在文中以明确方式标明。
本人完全意识到本声明的法律结果由本人承担。
学位论文作者签名:日期:关于学位论文版权使用授权的说明本人完全了解桂林电子科技大学信息科技学院关于收集、保存、使用学位论文的以下规定:学院有权采用影印、缩印、扫描、数字化或其它手段保存论文;学院有权提供本学位论文全文或者部分内容的阅览服务;学院有权将学位论文的全部或部分内容编入有关数据库进行检索、交流;学院有权向国家有关部门或者机构送交论文的复印件和电子版。
学位论文作者签名:日期:导师签名:日期:摘要随着电子科技的飞速发展,单片机在电子及自动控制领域均得到了广泛的应用。
MCS-51单片机经历了几十年的发展之后,目前在技术、配套教材及资料上均已十分成熟。
通过对51单片机进行系统设计,同学们可以更好的掌握单片机的基本原理与设计开发过程。
本次实训的内容为打地鼠游戏机的设计与制作,来实现:利用led灯亮灭表示“地鼠”进出地鼠洞,通过光敏元件代表锤子实现信号的转化,并由单片机控制led的亮灭,数码管的显示。
实训设计制作共耗时一周,实训作品可实现“地鼠”随机出现,数码管显示,光敏原件检测是否“击中”,单片机自行判断与通关等功能,作品运行稳定,完全达到了实训要求。
通过实训,本人已对C51单片机基本了解,并有了较深刻的认识。
关键词:led随机显示;光敏原件;数码管显示;单片机;目录引言 (2)1方案设计 (2)1.1软件设计方案 (2)1.2硬件设计方案 (2)2总设计 (2)2.1软件设计 (2)2.2硬件设计 (3)3.硬件设计 (2)3.1单片机系统设计 (2)3.1.1单片机的选择 (2)3.1.2单片机引脚功能 (4)3.1.3单片机最小系统 (5)3.2数码管显示模块设计 (6)3.3“地鼠洞”模块电路 (7)3.4信号转换模块电路 (7)3.4.1L M358电压比较器 (7)3.4.2光敏电阻 (7)3.4.3光电信号转换 (7)4.软件设计 (8)4.1主程序设计 (8)4.2程序展示 (9)5.总结 (11)辞谢...........................................................................1 1 参考文献 (11)引言随着电子科技的飞速发展,单片机在电子及自动控制领域均得到了广泛的应用。
基于51单片机24小时可调时钟1602液晶显示程序#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit key5=P1^4;sbit key6=P1^5;sbit rs=P0^0; //液晶的第4端RS由开关独立s2 p3^5控制高电平写数据,低电平写命令。
sbit lecdn=P0^1; //使能端需控制LECDN,p3^6控制。
根据硬件电路而定uchar miao ,fen ,shi,num;uchar miao1,miao2,shi1,shi2,fen1,fen2;uchar table[]="0123456789";void delay(uint x){uint i,j;for(i=x;i>0;i--)for(j=10;j>0;j--);}void write_com(uchar com )//写指令{P2=com;//RW=0;写指令位定义一个io口控制lecdn=0; //起初为低电平时序图rs=0; //写指令rs为低delay(10); //简短延时lecdn=1; //给以高脉冲delay(5);lecdn=0;}void write_data(uchar shu ) //写数据{P2=shu; //将数据送给控制数据位的io口//RW=0;写指令位定义一个io口控制lecdn=0;rs=1; //写数据rs为低区别delay(10);lecdn=1;delay(5);lecdn=0;}void init() //初始化{write_com(0x38); //显示模式设置delay(20);write_com(0x0f); // 显示开关,和光标设置,开关必开,光标不开ox0c,开并闪烁0x0fdelay(20);write_com(0x06); //写完一个数据,数据地址指针自动往后移动一位delay(20);write_com(0x01); //清屏指令,按下复位键上次的结果变清掉。
作品名称:基于AT89S52以LCD1602为显示屏的打地鼠游戏作品简介:采用AT89S52单片机为主控芯片,选取LCD1602作为显示屏,通过一个拨动开关控制液晶屏的开启与关闭。
带有红外接收头,同时可用红外遥控器进行控制。
选取了基于I2C-BUS 的串行EEPROM存储器件24C02作为游戏数据存储器,可以掉电保存游戏记录。
配有无源蜂鸣器,可播放开场音乐及提示音。
本游戏硬件部分的电路原理图均是自行设计,全部为手工布线与焊接;软件部分为原创的基于1602液晶屏的打地鼠(Whac-A-Mole)游戏。
操作说明:1.插上电源后,打开作品左下角的拨动开关启动(左边为“关”,右边为“开”)。
如在光线差且电池电量充足的情况下,可打开上方液晶屏下的背光控制开关(左边为“开”,右边为“关”)。
2.系统启动后,会出现一个过场动画,随后显示游戏等待画面:液晶屏第一排前8位随机显示地鼠(Ö)或地雷(*),右边显示最高分;液晶屏第二排显示游戏的英文名称——Whac A Mole(打地鼠)。
3.按下遥控器上的“开/关”键进入游戏(此时独立键盘无效)。
4.在开场音乐伴随下显示“Ready Go!!!”之后正式进入游戏。
游戏从Level 01开始,共20关。
5.进入游戏界面后,随机产生地鼠和地雷(地雷产生的概率为10%),上下两行四列分别对应独立键盘的8个按键。
按下某个键即代表击打相应位置。
6.游戏界面的右侧上下两行分别显示分数($XXX)和生命数(L XX)。
游戏初始的生命数为3。
7.若击中地鼠:正常情况下分数加1,播放提示音1;若在较短时间(实际为地鼠产生到消失的前一半时间内)击中,则“快速反应,双倍加分”,即分数加2,播放提示音2,但与正常得分的提示音1不同。
8.若击中地雷,则生命数减1,分数不变,播放提示音3。
9.当地雷出现时,若未按下相应键,则分数加1,播放提示音1。
10.当地鼠出现时,若未按下相应键,则生命数减1,分数不变,播放提示音3。
目录一、摘要 (3)二、流程图 (4)三、电路原理 (5)四、操作说明 (7)五、演示图片 (8)六、程序代码 (11)一、摘要本作品采用STC89C52单片机作为主控芯片,选取LCD1602液晶作为显示屏,选用24C02芯片作为外部EEPROM存储得分等数据。
游戏程序应用C语言编译,主要使用函数为显示主界面函数,选择模式函数,随机函数,键盘扫描函数和众多界面函数。
系统配有开机音乐和led短暂特效;以及关闭游戏音乐效果。
目前配有三个难度等级,可以随时添加。
游戏中可以实时显示得分、时间等数据。
能够通过led显示和LCD1602同时显示地鼠的出现。
题目要求中所有内容均已完成,且加入了很多额外显示环节。
二、流程图三、电路原理1、主控芯片2、地鼠led和3*3键盘3、蜂鸣器和buzzer4、1602环节5、24C02芯片四、操作说明1.插上电源后,打开作品左下角的自锁开关启动。
2.系统启动后,会次显示“welcome”字样,以及本队伍的名称,并伴随着短暂的旋律,led闪烁效果。
紧接着便进入游戏选择界面,分别是:1.start 2.s core 3.exit分别对应着开始游戏,进入历史分数菜单,以及结束的功能。
通过button1 和button2键可以进行功能选择的切换和选取,button1用于切换,button2用于确认。
3.选择start选项之后会有5秒钟的准备时间,之后即可进入游戏,游戏分为3个关卡,难度依次上升,具体表现为地鼠产生的时间间隔依次减少,第一次为3秒间隔,往后依次递减。
以9个灯泡作为地鼠,每次随机亮一个灯泡,游戏者需要在另一个3*3的矩阵上在灯泡亮的时间内按下相应的按钮即代表击打相应位置,从而实现打地鼠的模拟功能。
4.游戏界面的上方有左右两行,分别对应显示剩余时间(每次游戏的时间为30秒),以及所获得的分数。
下方也有左右两行,分别对应当前所示洞的序数,5.若击中地鼠:正常情况下分数加1,播放提示音1;6.每关有(30/地鼠实现时间) 个地鼠(或地雷),击打完成后若分数大于等于level*10则进入下一关。
7.游戏失败时,显示“GAME OVER”。
8.顺利通过3关或游戏失败后均导致游戏结束,此时显示你的得分并检测,若比存储的纪录分数高,则刷新纪录并存储。
9.显示作者信息及其他相关信息后回到游戏开始的等待画面。
补充说明:1.本版本中进入游戏后只能用按键控制,在下一版本中会添加红外遥控控制。
2.液晶显示屏背光环节设置为接电即启用的状态,可以换增电池模块。
3. LCD1602显示图片上略有难度,下一环节将使用12864或者触屏板进行设计。
4. 蜂鸣器声音过于单调,下一环节将启用PM50100语音芯片进行播报。
五、演示图片仿真图片实际图片六、程序代码#include<reg52.h>#include<stdlib.h>sbit RS=P2^0;sbit EN=P2^1;sbit Speak=P2^2;sbit button1=P2^3; //选择模式键sbit button2=P2^4; //确认键、返回键、暂停键、下一关开始键sbit Buzzer=P2^6;sbit hole1=P2^7; //1号洞sbit SDA=P1^1; //24c02数据线sbit SCL=P1^0; //24c02时钟线unsigned char Count; //Play_Song使用unsigned char i,j;unsigned char temp; //随机数种子unsigned char result; //随机数临时变量unsigned char score; //保存临时分数unsigned char tempname[2];//保存临时分数的名字unsigned char time; //保存时间(30秒倒计时)unsigned char num; //1秒钟判断变量unsigned char flag1; //1标识得分,led全灭,不进行scankey操作unsigned char flag2; //1标识得分Buzzer响方式1unsigned char flag3; //1标识地鼠出洞时间到,开始下一轮地鼠出洞unsigned char flag4; //1标识关卡时间到unsigned char flag5; //1标志暂停unsigned char level; //关卡等级unsigned char holenum; //保存随机生成的洞号unsigned char topscore[3]={0}; //保存3个最高分unsigned char name[3][2]={"AA","BB","CC"}; //保存3个最高分名字unsigned char code hole[]={0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//P3口控制的洞unsigned char code str1[]={"Welcome!"}; //欢迎标语unsigned char code str2[]={"1.start 2.score"};unsigned char code str3[]={"3.exit"};unsigned char code str4[]={"See You! "}; //exit界面unsigned char code str5[]={"Ready?"};unsigned char code str6[]={"GO!"};unsigned char code str7[]={"Your Soccer: "}; //查看分数unsigned char code str8[]={"Time: Score: "};unsigned char code str9[]={" Team: SONGE "}; //队名unsigned char code str10[]={"Game Over!"};unsigned char code str11[]={"You Win! GO?"};unsigned char code str12[]={"You Lose!"};unsigned char code str13[]={"top1:"};unsigned char code str14[]={"Congratulations"};unsigned char code str15[]={"hole: level:"};unsigned char code str16[]={"top2:"};unsigned char code str17[]={"top3:"};unsigned char code str18[]={"Your Name:"}; //记录姓名//*************************1602函数声明*******************************//void displayWelcome(); //显示欢迎界面void displayPrepare(); //显示选项void Game(); //游戏真正进行void displayGame(); //开始游戏void displayExit(); //显示退出界面void displaytime();void displayChoose(); //显示选择界面void displayover();void scankey();void pause();void displayScoreNext();//***************************基础函数*****************************//void delayms(unsigned int xms) //延时xms 毫秒{unsigned int i,j;for(i=xms; i>0; i--)for(j=110; j>0; j--);}void delayus(unsigned int ums) //延时ums 个3微秒{unsigned int i,j;for(i=0; i<ums; i++)for(j=0; j<3; j++);}void Time_init() //定时器初始化,11.0592MZ晶振初始选择:定时器0用于播放音乐,定时器1关闭{ //进入游戏:定时器1用于LCD显示分数TMOD = 0x11; //16位定时器退出游戏:定时器0播放音乐,定时器1关闭TH0 = 0xDC;TL0 = 0x00;TH1=(65536-45872)/256;TL1=(65536-45872)%256;EA=1; //开总中断ET0=1; //开定时器0中断ET1=1; //开定时器1中断}void Time0() interrupt 1 //定时器0中断播放音乐{TH0 = 0xDC;TL0 = 0x00;Count++; //长度加1}void Time1() interrupt 3 //定时器1中断游戏中显示分数{TH1=(65536-45872)/256;TL1=(65536-45872)%256; //每50ms中断一次num++;if(num%20==0) //近似1秒钟{time--;}if(num==(60-20*level)) //出洞结束,level1:3s; level2:2s; level3:1s{num=0;flag3=1;}if(time==0) //一关结束{time=30;flag4=1;}}//***********************播放音乐*********************************//unsigned char code SONG[] ={ //祝你平安0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20, 0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x00, //27个数字//0x20,0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,//0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,//0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20, //0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10, //0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20, //0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20, //0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20, //0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10, //0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80, //0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20, //0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,//0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10, //0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,//第217个数字//路边的野花不要采//0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,0x18,0x10,0x20,0x10,0x1C,0x10,0x18,0x40,0x1C, // 0x20,0x20,0x20,0x1C,0x20,0x18,0x20,0x20,0x80,0xFF,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20, 0x30,0x80,0xFF,0x20,0x20,0x00,//0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30, //0x20,0x2B,0x40,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30, //0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26, //0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1C,0x10,0x20, //0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x15,0x1F, //0x05,0x20,0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20, //0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,//0x20,0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1C,0x10,0x18,0x40,0x1C,0x20,0x20, //0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,0x80,};void Play_Song(unsigned char i) //i=1 播放路边的野花不要采{ //i=0 播放祝你平安unsigned char Temp1,Temp2;unsigned int Addr;Count = 0; //中断计数器清0Addr = i * 27; //音乐地址TR0=1; //开启定时器0while(1){Temp1 = SONG[Addr++];if (Temp1 == 0xFF) //休止符{TR0 = 0; //关闭定时器0delayus(100);}else if (Temp1 == 0x00) //歌曲结束符{TR0=0; //关闭定时器0return;}else //正常播放歌曲{Temp2 = SONG[Addr++];TR0 = 1;while(1){Speak = ~Speak;delayus(Temp1);if(Temp2 == Count){Count = 0;break;}}}}}void playBuzzer(){if(flag2==1) //得分响{Buzzer=0;delayms(30);Buzzer=1;}else{}}//******************************24C02环节*************************************// void init(){SDA=1;delayms(5);SCL=1;delayms(5);}void start() //开始信号{SDA=1;delayms(5);SCL=1;delayms(5);SDA=0;delayms(5);}void stop() //停止信号{SDA=0;delayms(5);SCL=1;delayms(5);SDA=1;delayms(5);}void respons() //应答{unsigned char i;SCL=1;delayms(5);while((SDA==1)&&(i<250))i++;SCL=0;delayms(5);}void write_byte(unsigned char date)//写字节{unsigned char i,temp,j;temp=date;for(i=0; i<8; i++){j=0x80&temp;temp=temp<<1;SCL=0;delayms(5);SDA=(bit)j;delayms(5);SCL=1;delayms(5);}SCL=0;delayms(5);SDA=1;delayms(5);}unsigned char read_byte()//读字节{unsigned char i,k;SCL=0;delayms(2);SDA=1;for(i=0; i<8; i++){SCL=1;delayms(5);k=(k<<1)|SDA;SCL=0;delayms(5);}return k;}void write_add(unsigned char address,unsigned char date)//往地址写数据{start();write_byte(0xa0); //控制字写1010 000 0(写操作)respons();write_byte(address);//存储单元地址respons();write_byte(date);respons();stop();}unsigned char read_add(unsigned char address) //往地址中读数据{unsigned char date;start();write_byte(0xa0); //控制字写respons();write_byte(address); //单元地址respons();start();write_byte(0xa1); //控制字读1010 000 1(读操作)respons();date=read_byte(); //数据SDA=1; //非应答delayus(5);SCL=1;delayus(5);stop();return date;}void getRecord() //读取前三名分数{topscore[0]=read_add(0);//第一名name[0][0]=read_add(1);name[0][1]=read_add(2);topscore[1]=read_add(3);//第二名name[1][0]=read_add(4);name[1][1]=read_add(5);topscore[2]=read_add(6);//第三名name[2][0]=read_add(7);name[2][1]=read_add(8);}void Record() //更新前三并记录分数{write_add(0,topscore[0]);//第一名write_add(1,name[0][0]);write_add(2,name[0][1]);write_add(3,topscore[1]);//第二名write_add(4,name[1][0]);write_add(5,name[1][1]);write_add(6,topscore[2]);//第三名write_add(7,name[2][0]);write_add(8,name[2][1]);}void Judge() //判断分数高低{if(score>topscore[0]){topscore[2]=topscore[1];//第二名赋给第三名name[2][0]=name[1][0];name[2][1]=name[1][1];topscore[1]=topscore[0];//第一名赋给第二名name[1][0]=name[0][0];name[1][1]=name[0][1];topscore[0]=score; //临时变量赋给第一名name[0][0]=tempname[0];name[0][1]=tempname[1];}else if(score>topscore[1]){topscore[2]=topscore[1];//第二名赋给第三名name[2][0]=name[1][0];name[2][1]=name[1][1];topscore[1]=score; //临时变量赋给第二名name[1][0]=tempname[0];name[1][1]=tempname[1];}else if(score>topscore[2]){topscore[2]=score; //临时变量赋给第三名name[2][0]=tempname[0];name[2][1]=tempname[1];}}//*******************************1602环节*************************************//void wr_com(unsigned char com) //写指令{delayms(5);RS=0;EN=0;P0=com;delayms(5);EN=1;delayms(5);EN=0;}void wr_dat(unsigned char dat) //写数据{delayms(5);RS=1;EN=0;P0=dat;delayms(5);EN=1;delayms(5);EN=0;}void lcd_init() //1602初始化设置//{delayms(25);wr_com(0x38); //设置16*2显示,5*7点阵,8位数据接口wr_com(0x01); //显示清0,数据指针清0wr_com(0x06); //写一个字符后地址加一wr_com(0x0c); //设置开显示,不显示光标getRecord();}void displayWelcome() //显示欢迎界面wr_com(0x80+0x03);delayms(5);for(i=0; i<9; i++){wr_dat(str1[i]);delayus(5);}wr_com(0xc0+0x01);delayms(5);for(i=0; i<13; i++){wr_dat(str9[i]);delayus(5);}for(i=0; i<10; i++) //开关显示完成闪烁{if(j==0){wr_com(0x08); //关显示delayms(100);}else{wr_com(0x0c); //开显示delayms(100);}j=~j;}Play_Song(0);delayms(100);void displayPrepare() //显示选项{wr_com(0x01); //清屏delayms(5);wr_com(0x80);delayms(5);for(i=0; i<15; i++){wr_dat(str2[i]);delayus(5);}wr_com(0x80+0x40);delayms(5);for(i=0; i<6; i++){wr_dat(str3[i]);delayus(5);}for(i=0; i<9; i++){switch(i%3){case 0:hole1=0;P3=0x00;delayms(100);case 1:hole1=0;P3=0x55;delayms(100);case 2:hole1=1;P3=0xaa;delayms(100);}}hole1=0;P3=0x00;void displaytime() //游戏过程中刷新显示时间、分数{wr_com(0x80+0x05); //显示倒计时delayus(5);wr_dat(0x30+time/10);delayus(5);wr_dat(0x30+time%10);delayus(5);wr_com(0x80+0x0e); //显示分数delayus(5);wr_dat(0x30+score/10);delayus(5);wr_dat(0x30+score%10);delayus(5);wr_com(0xc0+0x0e); //显示关卡delayus(5);wr_dat(0x30+(level+1));delayus(5);}void recordName() //记录姓名{wr_com(0x01);delayus(5);wr_com(0x80);delayus(5);for(i=0; i<10; i++) //Your Name:{wr_dat(str18[i]);delayus(5);}i='A';wr_dat(i);delayus(5);wr_com(0x10); //光标左移delayus(5);wr_com(0x0f); //光标闪烁delayus(5);while(1) //输入第一个字母{wr_com(0x80+0x0a);delayus(5);wr_dat(i);delayus(5);if(button1==0){delayms(10);if(button1==0){while(!button1);i++;if(i>'Z')i='A';}}if(button2==0)//确认,开始输入第二个字母{tempname[0]=i;break;}}i='A'; //输入第二个字母wr_dat(i);delayus(5);while(1){wr_com(0x80+0x0b);delayus(5);wr_dat(i);delayus(5);if(button1==0){delayms(10);if(button1==0){while(!button1);i++;if(i>'Z')i='A';}}if(button2==0)//确认,输入完毕{tempname[1]=i;break;}}wr_com(0x0c); //关闭光标delayus(5);displayChoose();}void displayover() //显示一轮游戏结束画面{TR1=0; //关闭定时器1wr_com(0x01);delayms(5);wr_com(0x80);delayms(5);for(i=0; i<10; i++) //Game Over{wr_dat(str10[i]);delayus(5);}wr_com(0xc0);delayus(5);if(score>=(10*(1+level))) //不同level分数要求不同,win了{if(level==3) //通关了{level=0;wr_com(0x80);delayus(5);for(i=0; i<15; i++){wr_dat(str14[i]);delayus(5);}wr_com(0xc0);delayus(5);for(i=0; i<8; i++){wr_dat(str11[i]);delayus(5);}while(1){if(button2==0){delayms(10);if(button2==0){while(!button2);recordName();}}}}else //升级了{for(i=0; i<12; i++) //You Win!{wr_dat(str11[i]);delayus(5);}while(1){if(button2==0){delayms(10);if(button2==0){while(!button2);level++;displayGame();}}}}}else //You Lose!{for(i=0; i<9; i++){wr_dat(str12[i]);delayus(5);}}while(1) //失败了{if(button2==0){delayms(10);if(button2==0){while(!button2);if(score!=0) //0分不记录recordName();displayChoose();}}}}void scankey() //扫描按键,判断是否得分{if((hole1==0) && (P3==0x00))//打中地鼠{delayms(5);if((hole1==0) && (P3==0x00)){while(((hole1==0) && (P3==0x00)));flag1=1; //标志得分不进行scankeyflag2=1; //标识得分buzzerscore++;playBuzzer();hole1=0;P3=0x00;}}}unsigned char random() //随机数{temp++;result=rand()%9+1;return result;}void displayhole() //hole地鼠显示{holenum=random();if(holenum==0)holenum++;wr_com(0xc0+0x06);delayus(5);wr_dat(0x30+holenum);delayus(5);switch(holenum){case 0: break;case 1: //1号洞亮hole1=1;P3=hole[1];break;case 2: //2号洞亮hole1=0;P3=hole[2];break;case 3: //3号洞亮hole1=0;P3=hole[3];break;case 4: //4号洞亮hole1=0;P3=hole[4];break;case 5: //5号洞亮hole1=0;P3=hole[5];break;case 6: //6号洞亮hole1=0;P3=hole[6];break;case 7: //7号洞亮hole1=0;P3=hole[7];break;case 8: //8号洞亮hole1=0;P3=hole[8];break;case 9: //9号洞亮hole1=0;P3=hole[9];break;}}void pause() //暂停/恢复游戏{if(button2==0) //暂停键{delayms(5); //去抖动if(button2==0){while(!button2);TR1=~TR1;flag5=~flag5;return;}}}void Gameinit() //游戏开始时数据初始化{flag1=0;//scankey标识flag2=0;//蜂鸣器标志位flag3=0;//出洞结束标识flag4=0;//timeover标识time=30;if(level==0) //重新开始闯关,则清零得分score=0;wr_com(0x01); //清屏delayus(5);wr_com(0x80);delayus(5);for(i=0; i<15; i++) //固定内容显示{wr_dat(str8[i]);delayus(5);}wr_com(0xc0);delayus(5);for(i=0; i<14; i++){wr_dat(str15[i]);delayus(5);}}void Game() //游戏真正进行{Gameinit();displaytime(); //显示时间、分数、洞、关卡TR1=1; //开启定时器1while(1){displayhole(); //地鼠出洞while(!flag3)//地鼠出洞时间level:3s; level2:2s; level3:1s{if(flag5==0){if(flag1==0)scankey();displaytime();}pause(); //暂停键判断};if(flag2==0)//没有打中地鼠{playBuzzer();}if(flag4==1)//时间到,结束game{displayover();}flag1=0;//scankey标识flag2=0;//蜂鸣器标志位flag3=0;//出洞结束标识flag4=0;//timeover标识}}void displayGame() //开始游戏{wr_com(0x01); //清屏delayms(5);wr_com(0x80+0x04);delayms(5);for(i=0; i<6; i++) //显示Ready{wr_dat(str5[i]);delayus(5);}wr_com(0xc0+0x06);delayms(5);for(i=5; i>0; i--) //显示倒数5秒{wr_dat(0x30+i);for(j=0; j<10; j++)delayms(100);wr_com(0xc0+0x06);delayms(5);}wr_com(0xc0+0x06);delayms(5);for(i=0; i<3; i++) //显示GO{wr_dat(str6[i]);delayus(5);}delayms(200);Game(); //开始游戏!}void displayScore() //显示得分记录{getRecord();//从24C02中获取数据wr_com(0x01);delayms(5);wr_com(0x80);delayms(5);for(i=0; i<12; i++) //显示当前得分{wr_dat(str7[i]);delayus(5);}wr_dat(0x30+score/10);delayms(5);wr_dat(0x30+score%10);delayms(5);wr_com(0xc0);delayus(5);for(i=0; i<5; i++) //第二行显示top1{wr_dat(str13[i]);delayus(5);}wr_com(0xc0+0x06); //top1 delayus(5);wr_dat(0x30+topscore[0]/10); delayus(5);wr_dat(0x30+topscore[0]%10); delayus(5);wr_com(0xc0+0x09);delayus(5);wr_dat(name[0][0]);delayus(5);wr_dat(name[0][1]);delayus(5);while(1) //进入第二页键{if(button2==0){delayms(10); //去抖动if(button2==0){while(!button2);displayScoreNext();break;}}}}void displayScoreNext() //显示分数第二页{wr_com(0x01);delayms(5);wr_com(0x80);delayus(5);for(i=0; i<5; i++) //第一行显示top2{wr_dat(str16[i]);delayus(5);}wr_com(0x80+0x06);delayus(5);wr_dat(0x30+topscore[3]/10);delayus(5);wr_dat(0x30+topscore[3]%10);delayus(5);wr_com(0x80+0x09);delayus(5);wr_dat(name[1][0]);delayus(5);wr_dat(name[1][1]);delayus(5);wr_com(0xc0);delayus(5);for(i=0; i<5; i++) //第二行显示top3{wr_dat(str17[i]);delayus(5);}wr_com(0xc0+0x06);delayus(5);wr_dat(0x30+topscore[6]/10);delayus(5);wr_dat(0x30+topscore[6]%10);delayus(5);wr_com(0xc0+0x09);delayus(5);wr_dat(name[2][0]);delayus(5);wr_dat(name[2][1]);delayus(5);while(1) //返回键{if(button2==0){delayms(10); //去抖动if(button2==0){while(!button2);break;}}}}void displayExit() //显示退出界面{wr_com(0x01); //清屏delayms(5);wr_com(0x80+0x01);delayms(5);for(i=0; i<8; i++){wr_dat(str4[i]);delayus(5);}wr_com(0xc0+0x01);delayms(5);for(i=0; i<13; i++){wr_dat(str9[i]);delayus(5);}while(1){Play_Song(1);delayms(200);}}void displayChoose() //显示选择界面{if(score!=0)//0分不记录{Judge();//判断并重新排序Record();//记录到24C02中}displayPrepare();wr_com(0x80);delayms(5);wr_com(0x0f); //光标闪烁delayms(5);i=0;while(1){if(button1==0) //选择模式键{delayms(10); //去抖动if(button1==0){while(!button1); //松开按钮i++;if(i==3)i=0;switch(i){case 0:wr_com(0x80);delayms(5);break; //移动光标到相应位置case 1:wr_com(0x80+0x08);delayms(5);break;case 2:wr_com(0x80+0x40);delayms(5);break;}}}if(button2==0) //确认键{delayms(10); //去抖动if(button2==0){while(!button2); //松开wr_com(0x0c); //关闭光标delayus(5);switch(i){case 0:displayGame(); break;case 1:displayScore(); break;case 2:displayExit(); break;}return;}}}}void main(){lcd_init(); //lm016Time_init(); //interruptinit(); //E2PROMdisplayWelcome();while(1){displayChoose();}}。