【51项目】51单片机自制小霸王游戏机

视频演示效果:

纳新作品——小霸王游戏机

目录:

目录

视频演示效果:

目录:

前言:

一、连接方式:

1.1 控制引脚

1.2. 显示模块

1.3. 定时器

1.4. 游戏逻辑与硬件结合

1.5. 中断处理

二、源码分析:

2.1. 全局变量与常量定义

2.2. 游戏初始化函数

2.3. 游戏状态与逻辑

2.4. 辅助功能

2.5. 显示与输入

2.6. 中断处理

2.7. 主函数

2.8. 源码整合:

完整工程源码获取方式:


前言:

51单片机自制小霸王游戏机不仅是一个充满乐趣的DIY项目,而且蕴含了深刻的教育和技术意义。通过这一过程,可以加深对嵌入式系统原理的理解,锻炼实践操作能力,同时也是一种对经典电子游戏文化的致敬和传承

首先,这一项目使得制作者能够深入理解51单片机的内部结构和工作原理。51单片机作为一种基础的微控制器,其编程和硬件接口设计对于电子工程的学习者来说是基础且关键的。在自制游戏机的实践中,制作者需要对51单片机的I/O端口、定时器、中断系统等有深入的了解和运用,这有助于提升对微控制器应用的熟练度。

其次,自制小霸王游戏机的过程是对电子电路设计能力的考验和提升。从电路板的布局设计到元件的选择,再到焊接和调试,每一步都需要精细的操作和严谨的思考。这不仅能够锻炼动手能力,还能培养解决实际问题的能力。

此外,该项目具有浓厚的文化意义。小霸王游戏机是许多80后甚至70后的童年记忆,通过自制游戏机,可以体验复古游戏带来的乐趣,同时也是对那个时代电子游戏文化的一种纪念和传承。

这一项目能够激发创新思维和独立解决问题的能力。在制作过程中,可能会遇到各种预料之外的挑战,比如如何优化电路设计以减小体积,如何编写更高效的代码来提升游戏性能,如何使游戏机界面更友好等。这些问题的解决,都需要制作者发挥创新思维,寻找最佳解决方案。

最后,自制小霸王游戏机也是一种良好的技术交流方式。制作者可以将自己的设计分享给他人,通过社区交流获取反馈和建议,从而不断提升自己的技术水平,同时也促进了技术爱好者和同行之间的交流与合作。

一、连接方式:

1.1 控制引脚

  • P2口:用于控制方向和确认操作。

    • 0x04: 表示向上移动。
    • 0x10: 表示向下移动。
    • 0x01: 表示向左移动。
    • 0x40: 表示向右移动。
    • 0x80: 表示确认操作。
  • P3口:用于控制蜂鸣器。

    • P3^7 (loud): 控制蜂鸣器的开关状态。
  • P0口:用于检测键盘输入,具体检测到哪个键由P0的值决定。

    • P0=0xf7: 检测第一列键盘输入。
    • P0=0xfb: 检测第二列键盘输入。
    • P0=0xfd: 检测第三列键盘输入。
    • P0=0xfe: 检测第四列键盘输入。

1.2. 显示模块

相关接口

  • LCD接口:用于显示游戏信息和状态。
    • 涉及到LCD的初始化、位置设置、数据写入等操作。
    • wr_i_lcd 和 wr_d_lcd 函数用于写入指令和数据到LCD。

该代码主要涉及对 LCD 的控制,LCD 通常通过多个引脚与微控制器连接。在本代码中,使用了一些特定的控制信号:

  • RS (Register Select):选择寄存器信号,用于选择指令寄存器或数据寄存器。rs=0表示指令寄存器,rs=1表示数据寄存器。

  • RW (Read/Write):读写控制信号。rw=0表示写操作,rw=1表示读操作。

  • E (Enable):使能信号。LCD 在 E 由高变低的瞬间捕获数据。

  • busy_lcd():检查 LCD 的忙碌状态,确保在其准备好之前不会发送新的指令或数据。

 数据线

  • lcddata:用于发送指令或数据到 LCD 的数据线。在特定指令下,将数据或命令传递给 LCD。

 电路接口功能

  • 延时函数 (delaynms):用于产生精确的时间延迟,以满足 LCD 的指令和数据处理的时间要求。通过软件延时的方式确保 LCD 在指令或数据写入后有充足的时间来完成操作。

  • 初始化函数 (init_lcd):对 LCD 进行初始化设置,包括配置 LCD 的指令集、显示控制和清屏等操作。

  • 图像处理函数 (img_disp, lcd_set_dot, clear_pic):这些函数用于在 LCD 上绘制图像或图形,通过操控特定的寄存器和位来改变显示内容。

硬件连接

  • 接口引脚:通常 LCD 与微控制器之间会有多个 GPIO 口连接,上述信号(RS, RW, E, lcddata)都需要连接到微控制器的相应引脚。

  • 电源与接地:LCD 显示屏需要连接合适的电源和接地,以确保稳定工作。

工作原理

  • 指令与数据传输:通过上述信号的组合,微控制器可以发送不同的命令和数据到 LCD,实现各种显示效果。

  • 忙碌检测:在执行新的指令或写入数据之前,通过 busy_lcd() 检测 LCD 的忙碌状态,以防止由于过快的指令发送导致的数据丢失或指令失效。

1.3. 定时器

  • 定时器设置
    • 使用定时器(如T1)来产生随机数,用于游戏逻辑中的随机生成(如食物位置的随机生成)。
    • TH1 和 TL1 分别用于设置定时器高位和低位。

1.4. 游戏逻辑与硬件结合

  • 游戏状态:通过变量flag来控制不同的游戏状态,如贪吃蛇、飞机大战等。
  • 随机数生成:利用定时器的计数值来随机生成游戏中的元素位置。

1.5. 中断处理

  • 中断服务程序:负责处理按键输入。
    • 对应的中断例程负责检测按键输入,并根据输入修改游戏状态或控制动作(如改变方向、选择菜单选项等)。

电路接口主要包括按键检测、LCD显示、蜂鸣器控制等部分。通过这些硬件接口,代码实现了一个简单的游戏控制系统。每个硬件接口的功能都通过相应的端口和位定义清晰地映射到特定的操作上,如移动、选择、确认等。

二、源码分析:

2.1. 全局变量与常量定义

代码开头定义了一些全局变量和常量,用于控制游戏的状态和行为。

  • 字符串常量:用于显示在 LCD 上的不同游戏名称和提示信息,如 namegame1loser 等。
  • 全局变量:如 ppxlengthflagslect 等,这些变量用于控制菜单选择、游戏状态、长度计数等。
  • 硬件接口loud 是一个特殊位(sbit),用于控制蜂鸣器的开关。
#include "includes.h"
#include "intrins.h"
#include "stdlib.h"/*fx=0 ÓÒ fx=1 ×ófx=2 ÉÏfx=3 ÏÂ*/
/*P2 ÉÏ 0x04 ÏÂ 0x10 ×ó 0x01 ÓÒ 0x40 È·ÈÏ 0x80 */ 
uchar code name[]={"С°ÔÍõÓÎÏ·»ú"};
uchar code game1[]={"Ì°³ÔÉß"};
uchar code game2[]={"´òµØÊó"};
uchar code game3[]={"·É»ú´óÕ½"};
uchar code game4[]={"ͼƬ"};
uchar code loser[]={"ÄãÊäÁË"};
uchar code lxy1[]={"¼ÌÐø"};
uchar code lxy2[]={"·µ»Ø"};
uchar code cj[]={"³¤¶È: "};
uchar code fjs[]={"·É»ú: "};
char code  mouse[]={"ÀÏÊó: "};
uchar p=1,px=1;
uchar length=9;	
uchar flag=0,slect=0,choose=0;
uchar ran1,ran2,food=0;
uchar planex[3]={28,30,0};
uchar zidan_x[10]={0},zidan_y[10]={0};
uchar boom_x[10]={0},boom_y[10]={0};
char dishu=0;
sbit loud=P3^7;					
struct xx
{char x[22];char y[22];char head;char tail;char dir;
}snake;

 

2.2. 游戏初始化函数

  • snake_init():初始化贪吃蛇游戏的状态,在 LCD 上绘制初始蛇的形状,并设置蛇的坐标、头尾指针和方向。
void snake_init(void)
{lcd_set_dot(1,1,0);lcd_set_dot(2,1,0);lcd_set_dot(3,1,0);lcd_set_dot(4,1,0);lcd_set_dot(5,1,0);lcd_set_dot(6,1,0);snake.x[0]=1;snake.y[0]=1;snake.x[1]=2;snake.y[1]=1;snake.x[2]=3;snake.y[2]=1;snake.x[3]=4;snake.y[3]=1;snake.x[4]=5;snake.y[4]=1;snake.x[5]=6;snake.y[5]=1;snake.head=5;snake.tail=0;snake.dir=0;	
}

2.3. 游戏状态与逻辑

  • die():处理游戏失败的情况,显示失败信息并等待用户选择继续或返回。
  • cata():菜单选择功能,显示可选游戏列表,并根据用户输入更新选择。
  • game_snake():贪吃蛇游戏的核心逻辑,包括蛇的移动、食物生成、碰撞检测等。
  • game_plane():飞机大战游戏的逻辑,处理子弹和敌机的碰撞、飞机的移动等。
  • game_mouse():打地鼠游戏逻辑,随机生成地鼠位置,并检测玩家是否成功击中。
void die(void)
{uchar i;loud=0;flag=5;clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);i=0;lcd_pos(0,2);while(loser[i]!='\0'){wr_d_lcd(loser[i]);i++;}i=0;lcd_pos(2,0); while(lxy1[i]!='\0'){wr_d_lcd(lxy1[i]);i++;	}i=0;lcd_pos(2,5); while(lxy2[i]!='\0'){wr_d_lcd(lxy2[i]);i++;	}lcd_pos(3,0); wr_d_lcd('o');delay(1000);loud=1;while(flag==5);	
}
uchar cata(void)
{uchar i;i=0;slect=0;lcd_pos(0,0);wr_d_lcd('o');lcd_pos(0,1);while(game1[i]!='\0'){wr_d_lcd(game1[i]);i++;}lcd_pos(1,1);i=0;while(game3[i]!='\0'){wr_d_lcd(game2[i]);i++;}lcd_pos(2,1);i=0;while(game3[i]!='\0'){wr_d_lcd(game3[i]);i++;}lcd_pos(3,1);i=0;while(game4[i]!='\0'){wr_d_lcd(game4[i]);i++;}while(flag==0);	
}
void game_snake(void)
{uchar i,k,j;k=0;food=0;length=6;lcd_pos(3,0);i=0;while(cj[i]!='\0'){wr_d_lcd(cj[i]);i++;	}wr_d_lcd(length+48);while(1){if(food==0){while(1)//·ÀÖ¹²úÉúµÄʳÎï³öÏÖÔÚÉß×Ô¼ºÉíÉÏ{ran1=TH1%59+1;ran2=TL1%30+1;food=1;i=snake.tail;while(i!=snake.head){if(snake.x[i]==ran1&&snake.y[i]==ran2){break;}i++;if(i==22) i=0;if(i==snake.head){if(snake.x[i]==ran1&&snake.y[i]==ran2){i=snake.head-1;break;}}	}if(i==snake.head) break;	}lcd_set_dot(ran1,ran2,0);}i=snake.tail;while(i!=snake.head)//ÉßÒ§µ½×Ô¼º{if(snake.x[i]==snake.x[snake.head]&&snake.y[i]==snake.y[snake.head]){die();	break;	}i++;if(i==22) i=0;}if(i!=snake.head) break;if(snake.x[snake.head] >= 60 || snake.y[snake.head] >= 30 ||snake.x[snake.head] == 0 ||snake.y[snake.head] == 0) //ÉßÅöǽ{die();	break;	}snake.head++;if(snake.head==22){snake.head=0;if(snake.dir==0)	 //ÓÒ{snake.x[snake.head]=snake.x[21]+1;snake.y[snake.head]=snake.y[21];	}else if(snake.dir==1)  //×ó{snake.x[snake.head]=snake.x[21]-1;snake.y[snake.head]=snake.y[21];	}else if(snake.dir==2) //ÏÂ{		snake.x[snake.head]=snake.x[21];snake.y[snake.head]=snake.y[21]+1;}else if(snake.dir==3) //ÉÏ{snake.x[snake.head]=snake.x[21];snake.y[snake.head]=snake.y[21]-1;	}	}else{if(snake.dir==0){snake.x[snake.head]=snake.x[snake.head-1]+1;snake.y[snake.head]=snake.y[snake.head-1];	}else if(snake.dir==1){snake.x[snake.head]=snake.x[snake.head-1]-1;snake.y[snake.head]=snake.y[snake.head-1];	}else if(snake.dir==2){snake.x[snake.head]=snake.x[snake.head-1];snake.y[snake.head]=snake.y[snake.head-1]+1;}else if(snake.dir==3){snake.x[snake.head]=snake.x[snake.head-1];snake.y[snake.head]=snake.y[snake.head-1]-1;}}lcd_set_dot(snake.x[snake.head],snake.y[snake.head],0);if(snake.x[snake.head]!=ran1 || snake.y[snake.head]!=ran2)//Éßû³Ôµ½Ê³Îï{lcd_set_dot(snake.x[snake.tail],snake.y[snake.tail],1);snake.tail++;if(snake.tail==22) snake.tail=0;}else  //Éß³Ôµ½Ê³Îï{if(k<90) k+=10;loud=0;length++;wr_i_lcd(0x30);//	wr_i_lcd(0x01);lcd_pos(3,3);wr_d_lcd(length/10+48);wr_d_lcd(length%10+48);food=0;}for(i=0;i<100;i++)for(j=0;j<100-k;j++) time_1ms(1000);loud=1;	}	
}

2.4. 辅助功能

  • plane_init():初始化飞机的位置和状态。
  • back_ground():绘制游戏背景,比如边界和初始分数。
  • picture():显示图片的功能,通过选择不同的图片页来更新显示内容。
  • mouse_back():初始化打地鼠游戏的背景。
void plane_init(void)
{uchar i;lcd_set_dot(29,29,0);lcd_set_dot(28,30,0);lcd_set_dot(30,30,0);lcd_set_dot(29,30,0);for(i=0;i<10;i++){zidan_x[i]=0;zidan_y[i]=0;boom_x[i]=0;boom_y[i]=0;	}planex[0]=28;	planex[1]=30;
}void back_ground(void)
{uchar i;clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);for(i=0;i<=60;i++){ lcd_set_dot(i,0,0);lcd_set_dot(i,31,0);	}for(i=0;i<=32;i++){lcd_set_dot(0,i,0);lcd_set_dot(60,i,0);	}if(flag==3){lcd_pos(3,0);i=0;while(fjs[i]!='\0'){wr_d_lcd(fjs[i]);i++;}wr_d_lcd(length+48);}		
}
void game_plane(void)
{uchar i,t=0,j=0;while(1){i=0;while(i<10){j=0;while(j<10){if(((zidan_x[i])==boom_x[j]) && ((zidan_y[i]-1==boom_y[j]) || (zidan_y[i]==boom_y[j])) && (zidan_x[i]!=0) && (zidan_y[i] != 0)){lcd_set_dot(zidan_x[i],zidan_y[i],1);lcd_set_dot(boom_x[j],boom_y[j],1);zidan_y[i]=0;zidan_x[i]=0;boom_x[j]=0;boom_y[j]=0;wr_i_lcd(0x30);length++;lcd_pos(3,3);if(length<10) wr_d_lcd(length+48);else{wr_d_lcd(length/10+48);wr_d_lcd(length%10+48);}} j++;}i++;}i=0;while(i<10){j=0;while(j<10){if(((zidan_x[i])==boom_x[j]) && (zidan_y[i]-1==boom_y[j]) && (zidan_x[i]!=0) && (zidan_y[i] != 0)){lcd_set_dot(zidan_x[i],zidan_y[i],1);lcd_set_dot(boom_x[j],boom_y[j],1);zidan_y[i]=0;zidan_x[i]=0;boom_x[j]=0;boom_y[j]=0;} j++;}if((boom_x[i] ==planex[0]&& boom_y[i] ==29) || (boom_x[i] ==planex[1]&& boom_y[i] ==29) || ((boom_x[i] ==(planex[1]+planex[0])/2) && boom_y[i] ==29) ){die();break;	}i++;}if(i!=10) break;i=0;t++;ran2=TL1%59;while(i<10){if(zidan_x[i]!=0){if(zidan_y[i]==1){lcd_set_dot(zidan_x[i],zidan_y[i],1);zidan_y[i]=0;zidan_x[i]=0;}else{ lcd_set_dot(zidan_x[i],zidan_y[i],1); busy_lcd();zidan_y[i]--;lcd_set_dot(zidan_x[i],zidan_y[i],0);}	}				   i++;}i=0;while(boom_x[i]!=0) i++;if(t==4){t=0;boom_x[i]=ran2+1;boom_y[i]=1;}i=0;while(i<10){if(boom_x[i]!=0){if(boom_y[i]==30){lcd_set_dot(boom_x[i],boom_y[i],1);boom_y[i]=0;boom_x[i]=0;		}else{ lcd_set_dot(boom_x[i],boom_y[i],1); busy_lcd();boom_y[i]++;lcd_set_dot(boom_x[i],boom_y[i],0); }}i++;}			for(i=0;i<200;i++)for(j=0;j<50;j++){ //	if(i==70) loud=1;time_1ms(1000);} 	}	
}
void picture(void)
{img_disp(tab1);while(1){if(p!=px){if(px==4){flag=0;break;}clear_pic();p=px;if(p==1) img_disp(tab1);//	else if(p==2) img_disp(tab1); else if(p==2) img_disp(tab3); }	   }
}
void mouse_back(void)
{char i,j;clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);	for(i=0;i<4;i++)for(j=0;j<4;j++){lcd_pos(i,j);wr_d_lcd('o');	}i=0;lcd_pos(1,4);while(mouse[i]!='\0'){wr_d_lcd(mouse[i]);i++;		}wr_d_lcd(length+48);
}

 

2.5. 显示与输入

  • lcd_pos():设置 LCD 的显示位置,用于更新屏幕上的字符位置。
  • lcd_set_dot():在特定坐标设置点,用于绘制图形或游戏元素。
  • clear_pic():清除屏幕内容,为下一次显示做好准备。
void game_mouse(void)
{uchar i,j,k;k=0;length=0;while(1){ran1=TH1%4;ran2=TL1%4;lcd_pos(ran1,ran2);wr_d_lcd(0x02);dishu=1;loud=0;for(i=0;i<200;i++)for(j=0;j<200-k;j++){ if(i==70) loud=1;time_1ms(1000);}if(k<150) k+=10;if(dishu==1){die();	break;}lcd_pos(1,7); length++;if(length<10) wr_d_lcd(length+48);else{wr_d_lcd(length/10+48); wr_d_lcd(length%10+48);	}lcd_pos(ran1,ran2);wr_d_lcd('o');}
}

 

2.6. 中断处理

  • T0_():中断服务程序,用于处理按键输入,根据按键的不同改变游戏状态或控制游戏行为。包括方向键和确认键的处理。
void T0_() interrupt 3
{/*P2 ÉÏ 0x04 ÏÂ 0x10 ×ó 0x01 ÓÒ 0x40 È·ÈÏ 0x80 */uchar temp,i,j;if(flag==1||flag==2){TH1=(65536-30000)/256;TL1=(65536-30000)%256;}else{TH1=(65536-200)/256;TL1=(65536-200)%256;	}P2=0x00;temp=P2;if(temp!=0x00){time_1ms(20);if(temp!=0x00){	switch(temp){case 0x04:{loud=0;if(flag==0){lcd_pos(slect,0);wr_d_lcd(' ');if(slect==0) slect==3;else slect--;lcd_pos(slect,0);wr_d_lcd('o');while(P2!=0x00);time_1ms(50);	} else if(flag==1)if(snake.dir!=2) snake.dir=3;loud=1;}break;case 0x10:{loud=0;if(flag==0){lcd_pos(slect,0);wr_d_lcd(' ');if(slect==3) slect==0;else slect++;lcd_pos(slect,0);wr_d_lcd('o');while(P2!=0x00);time_1ms(20);}else if(flag==1)if(snake.dir!=3) snake.dir=2;loud=1;}break; case 0x01:{loud=0;if(flag==5){if(choose != 0){lcd_pos(3,0);wr_d_lcd('o');lcd_pos(3,6);wr_d_lcd(' ');choose=0;while(P2!=0x00);time_1ms(20);	}	} else if(flag==1){if(snake.dir!=0) snake.dir=1;}else if(flag==3){if(planex[0]>1) {planex[0]--;planex[1]--;lcd_set_dot(planex[0],30,0); busy_lcd();if((planex[0]-1)!=0) lcd_set_dot(planex[0]-1,30,1); busy_lcd();lcd_set_dot(planex[1],30,0);  busy_lcd();if((planex[1]+1)!=113) lcd_set_dot(planex[1]+1,30,1); busy_lcd();lcd_set_dot((planex[0]+planex[1])/2,29,0); busy_lcd();lcd_set_dot((planex[0]+planex[1])/2+1,29,1); busy_lcd();while(P2!=0x00){i=0;while(i<10){j=0;while(j<10){if(((zidan_x[i])==boom_x[j]) && (zidan_y[i]-1==boom_y[j]) && (zidan_x[i]!=0) && (zidan_y[i] != 0)){lcd_set_dot(zidan_x[i],zidan_y[i],1);lcd_set_dot(boom_x[j],boom_y[j],1);zidan_y[i]=0;zidan_x[i]=0;boom_x[j]=0;boom_y[j]=0;wr_i_lcd(0x30);length++;lcd_pos(3,3);if(length<10) wr_d_lcd(length+48);else{wr_d_lcd(length/10+48);wr_d_lcd(length%10+48);}} j++;}i++;}	}time_1ms(20);} }else if(flag==4){if(px>1) px--;else if(px==1) px=2;while(P2!=0x00);time_1ms(20);}loud=1;		}break; case 0x40:{loud=0;if(flag==5){if(choose != 1){lcd_pos(3,6);wr_d_lcd('o');lcd_pos(3,0);wr_d_lcd(' ');choose=1;while(P2!=0x00);time_1ms(20);	}	} else if(flag==1){if(snake.dir!=1) snake.dir=0;}else if(flag==3){if(planex[1]<59){planex[1]++;planex[0]++;lcd_set_dot(planex[0],30,0); busy_lcd();if((planex[0]-1)!=0) lcd_set_dot(planex[0]-1,30,1); busy_lcd();lcd_set_dot(planex[1],30,0);  busy_lcd();if((planex[1]+1)!=60) lcd_set_dot(planex[1]+1,30,1); busy_lcd();lcd_set_dot((planex[0]+planex[1])/2,29,0); busy_lcd();lcd_set_dot((planex[0]+planex[1])/2-1,29,1); busy_lcd();while(P2!=0x00){i=0;while(i<10){j=0;while(j<10){if(((zidan_x[i])==boom_x[j]) && (zidan_y[i]-1==boom_y[j]) && (zidan_x[i]!=0) && (zidan_y[i] != 0)){lcd_set_dot(zidan_x[i],zidan_y[i],1);lcd_set_dot(boom_x[j],boom_y[j],1);zidan_y[i]=0;zidan_x[i]=0;boom_x[j]=0;boom_y[j]=0;wr_i_lcd(0x30);length++;lcd_pos(3,3);if(length<10) wr_d_lcd(length+48);else{wr_d_lcd(length/10+48);wr_d_lcd(length%10+48);}} j++;}i++;}}time_1ms(20);} }else if(flag==4){if(px<2) px++;else if(px==2) px=1;while(P2!=0x00);time_1ms(20);}loud=1;		}break; case 0x80: {loud=0;if(flag==0){if(slect==0) flag=1;else if(slect==1) flag=2;else if(slect==2) flag=3;else if(slect==3) flag=4;while(P2!=0x00);time_1ms(20);}else if(flag==5){if(choose==0){flag=slect+1;}else if(choose==1) flag=0;choose=0;while(P2!=0x00);time_1ms(20);}else if(flag==3){i=0;while(zidan_x[i]!=0) i++;zidan_x[i]=planex[0]+1;zidan_y[i]=28;while(P2!=0x00);time_1ms(100);	}		else if(flag==4){px=4;while(P2!=0x00);time_1ms(100);}loud=1;	}break; }}	   }/*0x77	   0xb7	   0xd7	   0xe70x7b	   0xbb	   0xdb	   0xeb0x7d	   0xbd	   0xdd	   0xed0x7e     0xbe    0xde    0xee */P0=0xf7;temp=P0;if(temp!=0xf7){time_1ms(20);if(temp!=0xf7){switch(temp){case 0x77:{if(ran1==0&&ran2==0) dishu=0;	}break;case 0xb7:{if(ran1==0&&ran2==1) dishu=0;	}break;case 0xd7:{if(ran1==0&&ran2==2) dishu=0;}break;case 0xe7:{if(ran1==0&&ran2==3) dishu=0;	}break;}//	   while(P0!=0xf7);time_1ms(20);}}P0=0xfb;temp=P0;if(temp!=0xfb){time_1ms(20);if(temp!=0xfb){switch(temp){case 0x7b:{if(ran1==1&&ran2==0) dishu=0;		}break;case 0xbb:{if(ran1==1&&ran2==1) dishu=0;	}break;case 0xdb:{if(ran1==1&&ran2==2) dishu=0;}break;case 0xeb:{if(ran1==1&&ran2==3) dishu=0;	}break;}//	while(P0!=0xfb);time_1ms(20);}}P0=0xfd;temp=P0;if(temp!=0xfd){time_1ms(20);if(temp!=0xfd){switch(temp){case 0x7d:{if(ran1==2&&ran2==0) dishu=0;	}break;case 0xbd:{if(ran1==2&&ran2==1) dishu=0;			}break;case 0xdd:{if(ran1==2&&ran2==2) dishu=0;}break;case 0xed:{if(ran1==2&&ran2==3) dishu=0;		}break;}//	   while(P0!=0xfd);time_1ms(20);}}P0=0xfe;temp=P0;if(temp!=0xfe){time_1ms(20);if(temp!=0xfe){switch(temp){case 0x7e:{	if(ran1==3&&ran2==0) dishu=0;	}break;case 0xbe:{if(ran1==3&&ran2==1) dishu=0;	}break;case 0xde:{if(ran1==3&&ran2==2) dishu=0;  	}break;case 0xee:{if(ran1==3&&ran2==3) dishu=0;	}break;}//	 while(P0!=0xfe);time_1ms(20);}}	
}

 

2.7. 主函数

  • main():程序的入口,初始化 LCD,显示起始画面,进入主循环。根据不同的 flag 值进入相应的游戏模块或功能模块。
void main()
{char i=0,j;loud=1;init_lcd();     //³õʼ»¯img_disp(tab1);    //ÏÔʾͼÏñdelaynms(1000);wr_i_lcd(0x30);wr_i_lcd(0x01);lcd_pos(1,1);while(name[i]!='\0') {wr_d_lcd(name[i]);i++;if(i%2!=0)loud=0;delay(20000);}clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);TMOD=0x10;TH1=(65536-8000)/256;TL1=(65536-8000)%256;EA=1;		 ET1=1;TR1=1;while(1){clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);cata();if(flag==1){while(flag==1){food=0;back_ground();snake_init();game_snake();}	}if(flag==2){			while(flag==2){/*Ò»ÅÅ16¸öµØÊó00 01 02 0310 11 12 1320 21 22 2330 31 32 33*/length=0;mouse_back();game_mouse();}		}if(flag==3){while(flag==3){length=0;back_ground();plane_init();game_plane();}	}if(flag==4){px=1;p=1;clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);picture();		}}}

2.8. 源码整合:

#include "includes.h"
#include "intrins.h"
#include "stdlib.h"// 方向代码:0 右,1 左,2 上,3 下
// P2 端口:上 0x04,下 0x10,左 0x01,右 0x40,确认 0x80uchar code name[] = {"小龟游戏机"};
uchar code game1[] = {"贪吃蛇"};
uchar code game2[] = {"打地鼠"};
uchar code game3[] = {"飞机大战"};
uchar code game4[] = {"图片"};
uchar code loser[] = {"你输了"};
uchar code lxy1[] = {"继续"};
uchar code lxy2[] = {"返回"};
uchar code cj[] = {"长度: "};
uchar code fjs[] = {"飞机: "};
char code mouse[] = {"老鼠: "};// 全局变量定义
uchar p = 1, px = 1;
uchar length = 9;	
uchar flag = 0, slect = 0, choose = 0;
uchar ran1, ran2, food = 0;
uchar planex[3] = {28, 30, 0};
uchar zidan_x[10] = {0}, zidan_y[10] = {0};
uchar boom_x[10] = {0}, boom_y[10] = {0};
char dishu = 0;sbit loud = P3^7; // 定义蜂鸣器的开关// 贪吃蛇的结构体
struct xx {char x[22];char y[22];char head;char tail;char dir;
} snake;// 贪吃蛇初始化函数
void snake_init(void) {lcd_set_dot(1, 1, 0);lcd_set_dot(2, 1, 0);lcd_set_dot(3, 1, 0);lcd_set_dot(4, 1, 0);lcd_set_dot(5, 1, 0);lcd_set_dot(6, 1, 0);snake.x[0] = 1; snake.y[0] = 1;snake.x[1] = 2; snake.y[1] = 1;snake.x[2] = 3; snake.y[2] = 1;snake.x[3] = 4; snake.y[3] = 1;snake.x[4] = 5; snake.y[4] = 1;snake.x[5] = 6; snake.y[5] = 1;snake.head = 5;snake.tail = 0;snake.dir = 0;	
}// 游戏失败处理函数
void die(void) {uchar i;loud = 0; // 关闭蜂鸣器flag = 5; // 设置标志为5,表示游戏结束clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);i = 0;lcd_pos(0, 2);while (loser[i] != '\0') {wr_d_lcd(loser[i]);i++;}i = 0;lcd_pos(2, 0); while (lxy1[i] != '\0') {wr_d_lcd(lxy1[i]);i++;	}i = 0;lcd_pos(2, 5); while (lxy2[i] != '\0') {wr_d_lcd(lxy2[i]);i++;	}lcd_pos(3, 0); wr_d_lcd('o');delay(1000);loud = 1; // 打开蜂鸣器while (flag == 5);	
}// 游戏菜单选择
uchar cata(void) {uchar i;i = 0;slect = 0;lcd_pos(0, 0);wr_d_lcd('o');lcd_pos(0, 1);while (game1[i] != '\0') {wr_d_lcd(game1[i]);i++;}lcd_pos(1, 1);i = 0;while (game3[i] != '\0') {wr_d_lcd(game2[i]);i++;}lcd_pos(2, 1);i = 0;while (game3[i] != '\0') {wr_d_lcd(game3[i]);i++;}lcd_pos(3, 1);i = 0;while (game4[i] != '\0') {wr_d_lcd(game4[i]);i++;}while (flag == 0);	
}// 贪吃蛇游戏逻辑
void game_snake(void) {uchar i, k, j;k = 0;food = 0;length = 6;lcd_pos(3, 0);i = 0;while (cj[i] != '\0') {wr_d_lcd(cj[i]);i++;	}wr_d_lcd(length + 48);while (1) {if (food == 0) {while (1) { // 确保生成的食物不在蛇身上ran1 = TH1 % 59 + 1;ran2 = TL1 % 30 + 1;food = 1;i = snake.tail;while (i != snake.head) {if (snake.x[i] == ran1 && snake.y[i] == ran2) {break;}i++;if (i == 22) i = 0;if (i == snake.head) {if (snake.x[i] == ran1 && snake.y[i] == ran2) {i = snake.head - 1;break;}}	}if (i == snake.head) break;	}lcd_set_dot(ran1, ran2, 0);}i = snake.tail;while (i != snake.head) { // 蛇碰到自己if (snake.x[i] == snake.x[snake.head] && snake.y[i] == snake.y[snake.head]) {die();	break;	}i++;if (i == 22) i = 0;}if (i != snake.head) break;if (snake.x[snake.head] >= 60 || snake.y[snake.head] >= 30 || snake.x[snake.head] == 0 || snake.y[snake.head] == 0) { // 蛇撞墙die();	break;	}snake.head++;if (snake.head == 22) {snake.head = 0;if (snake.dir == 0) { // 右snake.x[snake.head] = snake.x[21] + 1;snake.y[snake.head] = snake.y[21];	} else if (snake.dir == 1) { // 左snake.x[snake.head] = snake.x[21] - 1;snake.y[snake.head] = snake.y[21];	} else if (snake.dir == 2) { // 下snake.x[snake.head] = snake.x[21];snake.y[snake.head] = snake.y[21] + 1;} else if (snake.dir == 3) { // 上snake.x[snake.head] = snake.x[21];snake.y[snake.head] = snake.y[21] - 1;	}	} else {if (snake.dir == 0) {snake.x[snake.head] = snake.x[snake.head - 1] + 1;snake.y[snake.head] = snake.y[snake.head - 1];	} else if (snake.dir == 1) {snake.x[snake.head] = snake.x[snake.head - 1] - 1;snake.y[snake.head] = snake.y[snake.head - 1];	} else if (snake.dir == 2) {snake.x[snake.head] = snake.x[snake.head - 1];snake.y[snake.head] = snake.y[snake.head - 1] + 1;} else if (snake.dir == 3) {snake.x[snake.head] = snake.x[snake.head - 1];snake.y[snake.head] = snake.y[snake.head - 1] - 1;}}lcd_set_dot(snake.x[snake.head], snake.y[snake.head], 0);if (snake.x[snake.head] != ran1 || snake.y[snake.head] != ran2) { // 蛇没有吃到食物lcd_set_dot(snake.x[snake.tail], snake.y[snake.tail], 1);snake.tail++;if (snake.tail == 22) snake.tail = 0;} else {  // 蛇吃到食物if (k < 90) k += 10;loud = 0;length++;wr_i_lcd(0x30);// wr_i_lcd(0x01);lcd_pos(3, 3);wr_d_lcd(length / 10 + 48);wr_d_lcd(length % 10 + 48);food = 0;}for (i = 0; i < 100; i++)for (j = 0; j < 100 - k; j++) time_1ms(1000);loud = 1;	}	
}// 飞机初始化函数
void plane_init(void) {uchar i;lcd_set_dot(29, 29, 0);lcd_set_dot(28, 30, 0);lcd_set_dot(30, 30, 0);lcd_set_dot(29, 30, 0);for (i = 0; i < 10; i++) {zidan_x[i] = 0;zidan_y[i] = 0;boom_x[i] = 0;boom_y[i] = 0;	}planex[0] = 28;	planex[1] = 30;
}// 游戏背景绘制
void back_ground(void) {uchar i;clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);for (i = 0; i <= 60; i++) { lcd_set_dot(i, 0, 0);lcd_set_dot(i, 31, 0);	}for (i = 0; i <= 32; i++) {lcd_set_dot(0, i, 0);lcd_set_dot(60, i, 0);	}if (flag == 3) {lcd_pos(3, 0);i = 0;while (fjs[i] != '\0') {wr_d_lcd(fjs[i]);i++;}wr_d_lcd(length + 48);}		
}// 飞机大战游戏逻辑
void game_plane(void) {uchar i, t = 0, j = 0;while (1) {i = 0;while (i < 10) {j = 0;while (j < 10) {if (((zidan_x[i]) == boom_x[j]) && ((zidan_y[i] - 1 == boom_y[j]) || (zidan_y[i] == boom_y[j])) && (zidan_x[i] != 0) && (zidan_y[i] != 0)) {lcd_set_dot(zidan_x[i], zidan_y[i], 1);lcd_set_dot(boom_x[j], boom_y[j], 1);zidan_y[i] = 0;zidan_x[i] = 0;boom_x[j] = 0;boom_y[j] = 0;wr_i_lcd(0x30);length++;lcd_pos(3, 3);if (length < 10) wr_d_lcd(length + 48);else {wr_d_lcd(length / 10 + 48);wr_d_lcd(length % 10 + 48);}} j++;}i++;}i = 0;while (i < 10) {j = 0;while (j < 10) {if (((zidan_x[i]) == boom_x[j]) && (zidan_y[i] - 1 == boom_y[j]) && (zidan_x[i] != 0) && (zidan_y[i] != 0)) {lcd_set_dot(zidan_x[i], zidan_y[i], 1);lcd_set_dot(boom_x[j], boom_y[j], 1);zidan_y[i] = 0;zidan_x[i] = 0;boom_x[j] = 0;boom_y[j] = 0;} j++;}if ((boom_x[i] == planex[0] && boom_y[i] == 29) || (boom_x[i] == planex[1] && boom_y[i] == 29) || ((boom_x[i] == (planex[1] + planex[0]) / 2) && boom_y[i] == 29)) {die();break;	}i++;}if (i != 10) break;i = 0;t++;ran2 = TL1 % 59;while (i < 10) {if (zidan_x[i] != 0) {if (zidan_y[i] == 1) {lcd_set_dot(zidan_x[i], zidan_y[i], 1);zidan_y[i] = 0;zidan_x[i] = 0;} else { lcd_set_dot(zidan_x[i], zidan_y[i], 1); busy_lcd();zidan_y[i]--;lcd_set_dot(zidan_x[i], zidan_y[i], 0);}	}				   i++;}i = 0;while (boom_x[i] != 0) i++;if (t == 4) {t = 0;boom_x[i] = ran2 + 1;boom_y[i] = 1;}i = 0;while (i < 10) {if (boom_x[i] != 0) {if (boom_y[i] == 30) {lcd_set_dot(boom_x[i], boom_y[i], 1);boom_y[i] = 0;boom_x[i] = 0;		} else { lcd_set_dot(boom_x[i], boom_y[i], 1); busy_lcd();boom_y[i]++;lcd_set_dot(boom_x[i], boom_y[i], 0); }}i++;}			for (i = 0; i < 200; i++)for (j = 0; j < 50; j++) { // if (i == 70) loud = 1;time_1ms(1000);} 	}	
}// 图片显示函数
void picture(void) {img_disp(tab1);while (1) {if (p != px) {if (px == 4) {flag = 0;break;}clear_pic();p = px;if (p == 1) img_disp(tab1);// else if (p == 2) img_disp(tab1); else if (p == 2) img_disp(tab3); }	   }
}// 打地鼠背景初始化
void mouse_back(void) {char i, j;clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);	for (i = 0; i < 4; i++)for (j = 0; j < 4; j++) {lcd_pos(i, j);wr_d_lcd('o');	}i = 0;lcd_pos(1, 4);while (mouse[i] != '\0') {wr_d_lcd(mouse[i]);i++;		}wr_d_lcd(length + 48);
}// 打地鼠游戏逻辑
void game_mouse(void) {uchar i, j, k;k = 0;length = 0;while (1) {ran1 = TH1 % 4;ran2 = TL1 % 4;lcd_pos(ran1, ran2);wr_d_lcd(0x02);dishu = 1;loud = 0;for (i = 0; i < 200; i++)for (j = 0; j < 200 - k; j++) { if (i == 70) loud = 1;time_1ms(1000);}if (k < 150) k += 10;if (dishu == 1) {die();	break;}lcd_pos(1, 7); length++;if (length < 10) wr_d_lcd(length + 48);else {wr_d_lcd(length / 10 + 48); wr_d_lcd(length % 10 + 48);	}lcd_pos(ran1, ran2);wr_d_lcd('o');}
}// 主函数入口
void main() {char i = 0, j;loud = 1;init_lcd();     // 初始化LCDimg_disp(tab1); // 显示图片delaynms(1000);wr_i_lcd(0x30);wr_i_lcd(0x01);lcd_pos(1, 1);while (name[i] != '\0') {wr_d_lcd(name[i]);i++;if (i % 2 != 0) loud = 0;delay(20000);}clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);TMOD = 0x10;TH1 = (65536 - 8000) / 256;TL1 = (65536 - 8000) % 256;EA = 1;		 ET1 = 1;TR1 = 1;while (1) {clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);cata();if (flag == 1) {while (flag == 1) {food = 0;back_ground();snake_init();game_snake();}	}if (flag == 2) {			while (flag == 2) {/* 一个4x4的打地鼠格子00 01 02 0310 11 12 1320 21 22 2330 31 32 33 */length = 0;mouse_back();game_mouse();}		}if (flag == 3) {while (flag == 3) {length = 0;back_ground();plane_init();game_plane();}	}if (flag == 4) {px = 1;p = 1;clear_pic();wr_i_lcd(0x30);wr_i_lcd(0x01);picture();		}}
}// 中断处理函数
void T0_() interrupt 3 {/* P2 上 0x04 下 0x10 左 0x01 右 0x40 确认 0x80 */uchar temp, i, j;if (flag == 1 || flag == 2) {TH1 = (65536 - 30000) / 256;TL1 = (65536 - 30000) % 256;} else {TH1 = (65536 - 200) / 256;TL1 = (65536 - 200) % 256;	}P2 = 0x00; // 初始化P2为0temp = P2;if (temp != 0x00) {time_1ms(20);if (temp != 0x00) {	switch (temp) {case 0x04: { // 上键loud = 0;if (flag == 0) { // 菜单导航lcd_pos(slect, 0);wr_d_lcd(' ');if (slect == 0) slect = 3;else slect--;lcd_pos(slect, 0);wr_d_lcd('o');while (P2 != 0x00);time_1ms(50);	} else if (flag == 1) { // 贪吃蛇游戏中if (snake.dir != 2) snake.dir = 3;}loud = 1;} break;case 0x10: { // 下键loud = 0;if (flag == 0) { // 菜单导航lcd_pos(slect, 0);wr_d_lcd(' ');if (slect == 3) slect = 0;else slect++;lcd_pos(slect, 0);wr_d_lcd('o');while (P2 != 0x00);time_1ms(20);} else if (flag == 1) { // 贪吃蛇游戏中if (snake.dir != 3) snake.dir = 2;}loud = 1;} break; case 0x01: { // 左键loud = 0;if (flag == 5) { // 游戏失败后if (choose != 0) {lcd_pos(3, 0);wr_d_lcd('o');lcd_pos(3, 6);wr_d_lcd(' ');choose = 0;while (P2 != 0x00);time_1ms(20);	}	} else if (flag == 1) { // 贪吃蛇游戏中if (snake.dir != 0) snake.dir = 1;} else if (flag == 3) { // 飞机大战游戏中if (planex[0] > 1) {planex[0]--;planex[1]--;lcd_set_dot(planex[0], 30, 0); busy_lcd();if ((planex[0] - 1) != 0) lcd_set_dot(planex[0] - 1, 30, 1); busy_lcd();lcd_set_dot(planex[1], 30, 0);  busy_lcd();if ((planex[1] + 1) != 113) lcd_set_dot(planex[1] + 1, 30, 1); busy_lcd();lcd_set_dot((planex[0] + planex[1]) / 2, 29, 0); busy_lcd();lcd_set_dot((planex[0] + planex[1]) / 2 + 1, 29, 1); busy_lcd();while (P2 != 0x00) {i = 0;while (i < 10) {j = 0;while (j < 10) {if (((zidan_x[i]) == boom_x[j]) && (zidan_y[i] - 1 == boom_y[j]) && (zidan_x[i] != 0) && (zidan_y[i] != 0)) {lcd_set_dot(zidan_x[i], zidan_y[i], 1);lcd_set_dot(boom_x[j], boom_y[j], 1);zidan_y[i] = 0;zidan_x[i] = 0;boom_x[j] = 0;boom_y[j] = 0;wr_i_lcd(0x30);length++;lcd_pos(3, 3);if (length < 10) wr_d_lcd(length + 48);else {wr_d_lcd(length / 10 + 48);wr_d_lcd(length % 10 + 48);}} j++;}i++;}	}time_1ms(20);} } else if (flag == 4) { // 图片显示中if (px > 1) px--;else if (px == 1) px = 2;while (P2 != 0x00);time_1ms(20);}loud = 1;		} break; case 0x40: { // 右键loud = 0;if (flag == 5) { // 游戏失败后if (choose != 1) {lcd_pos(3, 6);wr_d_lcd('o');lcd_pos(3, 0);wr_d_lcd(' ');choose = 1;while (P2 != 0x00);time_1ms(20);	}	} else if (flag == 1) { // 贪吃蛇游戏中if (snake.dir != 1) snake.dir = 0;} else if (flag == 3) { // 飞机大战游戏中if (planex[1] < 59) {planex[1]++;planex[0]++;lcd_set_dot(planex[0], 30, 0); busy_lcd();if ((planex[0] - 1) != 0) lcd_set_dot(planex[0] - 1, 30, 1); busy_lcd();lcd_set_dot(planex[1], 30, 0);  busy_lcd();if ((planex[1] + 1) != 60) lcd_set_dot(planex[1] + 1, 30, 1); busy_lcd();lcd_set_dot((planex[0] + planex[1]) / 2, 29, 0); busy_lcd();lcd_set_dot((planex[0] + planex[1]) / 2 - 1, 29, 1); busy_lcd();while (P2 != 0x00) {i = 0;while (i < 10) {j = 0;while (j < 10) {if (((zidan_x[i]) == boom_x[j]) && (zidan_y[i] - 1 == boom_y[j]) && (zidan_x[i] != 0) && (zidan_y[i] != 0)) {lcd_set_dot(zidan_x[i], zidan_y[i], 1);lcd_set_dot(boom_x[j], boom_y[j], 1);zidan_y[i] = 0;zidan_x[i] = 0;boom_x[j] = 0;boom_y[j] = 0;wr_i_lcd(0x30);length++;lcd_pos(3, 3);if (length < 10) wr_d_lcd(length + 48);else {wr_d_lcd(length / 10 + 48);wr_d_lcd(length % 10 + 48);}} j++;}i++;}}time_1ms(20);} } else if (flag == 4) { // 图片显示中if (px < 2) px++;else if (px == 2) px = 1;while (P2 != 0x00);time_1ms(20);}loud = 1;		} break; case 0x80: { // 确认键loud = 0;if (flag == 0) { // 在菜单中选择游戏if (slect == 0) flag = 1;else if (slect == 1) flag = 2;else if (slect == 2) flag = 3;else if (slect == 3) flag = 4;while (P2 != 0x00);time_1ms(20);} else if (flag == 5) { // 游戏失败后选择继续或返回if (choose == 0) {flag = slect + 1;} else if (choose == 1) flag = 0;choose = 0;while (P2 != 0x00);time_1ms(20);} else if (flag == 3) { // 飞机大战游戏中i = 0;while (zidan_x[i] != 0) i++;zidan_x[i] = planex[0] + 1;zidan_y[i] = 28;while (P2 != 0x00);time_1ms(100);	} else if (flag == 4) { // 图片显示中px = 4;while (P2 != 0x00);time_1ms(100);}loud = 1;	} break; }}	   }// 检测P0口的输入,判断打地鼠游戏中的鼠标位置P0 = 0xf7;temp = P0;if (temp != 0xf7) {time_1ms(20);if (temp != 0xf7) {switch (temp) {case 0x77: {if (ran1 == 0 && ran2 == 0) dishu = 0;	} break;case 0xb7: {if (ran1 == 0 && ran2 == 1) dishu = 0;	} break;case 0xd7: {if (ran1 == 0 && ran2 == 2) dishu = 0;} break;case 0xe7: {if (ran1 == 0 && ran2 == 3) dishu = 0;	} break;}time_1ms(20);}}P0 = 0xfb;temp = P0;if (temp != 0xfb) {time_1ms(20);if (temp != 0xfb) {switch (temp) {case 0x7b: {if (ran1 == 1 && ran2 == 0) dishu = 0;		} break;case 0xbb: {if (ran1 == 1 && ran2 == 1) dishu = 0;	} break;case 0xdb: {if (ran1 == 1 && ran2 == 2) dishu = 0;} break;case 0xeb: {if (ran1 == 1 && ran2 == 3) dishu = 0;	} break;}time_1ms(20);}}P0 = 0xfd;temp = P0;if (temp != 0xfd) {time_1ms(20);if (temp != 0xfd) {switch (temp) {case 0x7d: {if (ran1 == 2 && ran2 == 0) dishu = 0;	} break;case 0xbd: {if (ran1 == 2 && ran2 == 1) dishu = 0;			} break;case 0xdd: {if (ran1 == 2 && ran2 == 2) dishu = 0;} break;case 0xed: {if (ran1 == 2 && ran2 == 3) dishu = 0;		} break;}time_1ms(20);}}P0 = 0xfe;temp = P0;if (temp != 0xfe) {time_1ms(20);if (temp != 0xfe) {switch (temp) {case 0x7e: {	if (ran1 == 3 && ran2 == 0) dishu = 0;	} break;case 0xbe: {if (ran1 == 3 && ran2 == 1) dishu = 0;	} break;case 0xde: {if (ran1 == 3 && ran2 == 2) dishu = 0;  	} break;case 0xee: {if (ran1 == 3 && ran2 == 3) dishu = 0;	} break;}time_1ms(20);}}	
}

完整工程源码获取方式:毕设&amp;课设&amp;项目&amp;实训-51单片机自制小霸王游戏机资源-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/501088.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024/12/29 黄冈师范学院计算机学院网络工程《路由期末复习作业一》

一、选择题 1.某公司为其一些远程小站点预留了网段 172.29.100.0/26&#xff0c;每一个站点有10个IP设备接到网络&#xff0c;下面那个VLSM掩码能够为该需求提供最小数量的主机数目 &#xff08; &#xff09; A./27 B./28 C./29 D./30 -首先审题我们需要搞清楚站点与网…

【OpenCV】使用Python和OpenCV实现火焰检测

1、 项目源码和结构&#xff08;转&#xff09; https://github.com/mushfiq1998/fire-detection-python-opencv 2、 运行环境 # 安装playsound&#xff1a;用于播放报警声音 pip install playsound # 安装opencv-python&#xff1a;cv2用于图像和视频处理&#xff0c;特别是…

Vue2: table加载树形数据的踩坑记录

table中需要加载树形数据,如图: 官网给了两个例子,且每个例子中的tree-props都是这么写的: :tree-props="{children: children, hasChildren: hasChildren}" 给我一种错觉,以为数据结构中要同时指定children和hasChildren字段,然而,在非懒加载模式下,数据结…

深度学习模型预测值集中在某一个值

深度学习模型&#xff0c;训练过程中&#xff0c;经常遇到预测的结果集中在某个值&#xff0c;而且在学习的过程中会变&#xff0c;样例如下。 主要有如下解决方案 1、更换relu ->tanh 或者其他激活函数 2、更改随机种子&#xff0c;估计是没有初始化好&#xff0c;或者调…

图书项目:整合SSM

步骤&#xff1a; pom文件&#xff1a;导包&#xff0c;写入静态资源导出配置&#xff0c;连接数据库 建包&#xff1a;controller dao/mapper pojo service 配置文件&#xff1a;mybatis-config.xml applicationContext.xml&#xff08;Spring的配置文件&#xff09; datab…

javacript中function (res) {}与箭头函数表达式(res) =>{}的区别

javacript中function (res) {}与(res) &#xff1e;{}的区别 function (res) {} 代码演示 let shape {name:长方形,say:function(){console.log(我是this.name)setTimeout(function(){console.log(3秒后输出我是: this.name); //this.name为undefined}, 3000)} }shape.sa…

Docker安装(Docker Engine安装)

一、Docker Engine和Desktop区别 Docker Engine 核心组件&#xff1a;Docker Engine是Docker的核心运行时引擎&#xff0c;负责构建、运行和管理容器。它包括守护进程&#xff08;dockerd&#xff09;、API和命令行工具客户端&#xff08;docker&#xff09;。适用环境&#…

【卡通风格的的登录界面】

卡通风格的的登录、注册界面模板&#xff0c;使用uni-app编写&#xff0c;直接复制粘贴即可。 废话不多说&#xff0c;代码如下&#xff1a; login.vue文件 <template><view class"content"><view class"login-form"><view class&quo…

【AI】最近有款毛茸茸AI生成图片圈粉了,博主也尝试使用风格转换生成可爱的小兔子,一起来探索下是如何实现的

应用名称&#xff1a;一键变身毛茸茸小兔子 体验地址&#xff1a;点击跳转体验 模型名称&#xff1a;Kolors&#xff0c;点击跳转 背景 Gitee AI最近发起了一个社群挑战赛。 如果最近你也没什么好点子&#xff0c;想练习又无从下手&#xff0c;怎么办呢&#xff1f; 没关系&a…

重学 Android 自定义 View 系列(十):带指针的渐变环形进度条

前言 该篇文章根据前面 重学 Android 自定义 View 系列(六)&#xff1a;环形进度条 拓展而来。 最终效果如下&#xff1a; 1. 扩展功能 支持进度顺时针或逆时针显示在进度条末尾添加自定义指针图片使用线性渐变为进度条添加颜色效果 2. 关键技术点解析 2.1 进度方向控制的…

Oracle 23ai 图形界面安装

新年的第一篇博客&#xff0c;展示下Oracle 23ai的图形化安装。 主要给大家看下界面&#xff0c;安装的过程与19c没什么不同。 安装前 安装Oracle Database Preinstallation RPM&#xff1a; sudo dnf install oracle-database-preinstall-23aioracle用户有了&#xff1a; …

跳转至系统设置下某个子模块 - 鸿蒙 Harmony

有时候遇到一些需要预授权系统权限才可访问的功能,可以通过如下方式先跳转至系统设置下的某个子页面进行配置,具体如下 code 所示参考: 具体跳转到设置的子设置页面如下也有注释,可供参考使用 /*** 访问系统设置: 子目录* */ static accessSystemSettingSubDirectory(uriKey?:…

el-table 实现纵向多级表头

为了实现上图效果&#xff0c;最开始打算用el-row、el-col去实现&#xff0c;但发现把表头和数据分成两大列时&#xff0c;数据太多时会导致所在格高度变高。但由于每一格数据肯定不一样&#xff0c;为保持高度样式一致&#xff0c;就需要我们手动去获取最高格的高度之后再设置…

2024年度总结答疑

大家好&#xff0c;我是大师兄。在2024年的最后一天&#xff0c;让我们一起来复盘总结&#xff0c;回顾我们在学习和工作中的能力提升、经验教训以及如何在未来做得更好。 过去一年&#xff0c;我们努力提升了学习和工作能力&#xff0c;学习了新的技术和知识&#xff0c;积极参…

flutter组件————Row和Column

Row和Column 在Flutter中&#xff0c;Row 和 Column 是两个非常常用的布局组件&#xff0c;它们用于按照水平或垂直方向排列子组件。 Row Row 组件是一个将子组件沿水平方向&#xff08;从左到右&#xff09;排列的控件。它通常用于创建一行中的多个小部件&#xff0c;比如文…

苹果解锁工具iToolab UnlockGo 中文安装版(附教程+补丁) 2024年6月ios17.4.1可用(记得点赞)解压密码请看文章!!! 评论区获取最新链接

UnlockGo 允许您非常轻松地绕过 iPhone 的密码并获得对设备的完全访问权限。它在以下场景中很有用。 在几分钟内删除 iPhone/iPad 上的各种锁定。 解锁 4 位/6 位密码、Touch ID 和 Face ID 删除没有密码的 iCloud 免费锁 无需密码即可从 iPhone/iPad/iPod 中删除 Apple ID…

[最佳方法] 如何将视频从 Android 发送到 iPhone

概括 将大视频从 Android 发送到 iPhone 或将批量视频从 iPhone 传输到 Android 并不是一件容易的事情。也许您已经尝试了很多关于如何将视频从 Android 发送到 iPhone 15/14 的方法&#xff0c;但都没有效果。但现在&#xff0c;通过本文中的这 6 种强大方法&#xff0c;您可…

driftingblues2

修改网卡配置信息 首先kali终端运行以下命令查看靶机ip 这里我们发现并没有查到靶机的ip&#xff0c;这时我们重启靶机 打开靶机&#xff0c;按下e键&#xff0c;进入到如下界面 将ro替换为rw signie init/bin/bash 替换完毕后&#xff0c;按下Ctrl键X键&#xff0c;进入如下…

数据挖掘——聚类

数据挖掘——聚类 聚类K-meansKNN VS K-meansK-Nearest Neighbors (KNN)K-means K中心算法PAM算法 K-modes算法——解决数据敏感的问题KMeans算法 ——解决初始点选择问题K-中心点层次方法AGNES算法——最小距离单链接全链接平均链接 聚类评估K均值和K中心点的优缺点层次化聚类…

Nginx - 整合lua 实现对POST请求的参数拦截校验(不使用Openresty)

文章目录 概述步骤 1: 安装 Nginx 和 Lua 模块步骤 2: 创建 Lua 脚本用于参数校验步骤 3: 配置 Nginx 使用 Lua 脚本写法二&#xff1a; 状态码写法三 &#xff1a; 返回自定义JSON复杂的正则校验 步骤 4: 测试和验证ngx.HTTP_* 枚举值 概述 一个不使用 OpenResty 的 Nginx 集…