找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2965|回复: 7
打印 上一主题 下一主题
收起左侧

基于51单片机实习的数码管俄罗斯方块游戏的制作

[复制链接]
跳转到指定楼层
楼主
ID:390172 发表于 2018-11-3 21:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. //该游戏采用函数指针制作确保的数据的安全性
  2. #include "sys.h"
  3. #include "key.h"
  4. sbit key0 = P1^0;  //上移按键
  5. sbit key1 = P1^1;  //下移按键
  6. sbit key2 = P1^2;  //顺时针旋转按键
  7. sbit key3 = P1^3;  //逆时针·旋转按键
  8. sbit led1 = P1^4;  //测试的小灯
  9. /*         按键检测函数        */
  10. void KeyScan()
  11. {
  12.   if(key0 == 0)
  13.   {
  14.   Control.delay_ms(5); //消抖延时
  15.   if(key0 == 0)
  16.   {
  17.   switch(num3)
  18.   {
  19.   case 1:break;
  20.   case 2:break;
  21.   case 3:num3 = Control.Find_position(0xbf); break;
  22.   case 4:break;
  23.   case 5:break;
  24.   case 6:num3 = Control.Find_position(0xfe); break;
  25.   case 7:break;
  26.   case 8:break;
  27.   case 9:break;
  28.   case 10:num3 = Control.Find_position(0x9c);break;
  29.   case 12:num3 = Control.Find_position(0xdc);break;
  30.   }
  31.   while(!key0);     //等待按键释放
  32.   }
  33.   }
  34.   /*以上是第一个按键按下的函数即是上移的函数*/
  35.   else if(key1 == 0 )
  36.   {
  37.    Control.delay_ms(5); //消抖延时
  38.    if(key1 == 0)
  39.    {
  40.    switch(num3)
  41.    {
  42.     case 0:num3 = Control.Find_position(0xbf);break;
  43. case 1:break;
  44. case 2:break;
  45. case 4:break;
  46. case 5:break;
  47. case 6:num3 = Control.Find_position(0xf7);break;
  48. case 7:break;
  49. case 8:num3 = Control.Find_position(0xa3);break;
  50. case 9:num3 = Control.Find_position(0xe3);break;
  51.    }
  52.    while(!key1);       //等待按键释放
  53.    }
  54.   }
  55.   /*以上是第二个按键按下的函数即是下移的函数*/
  56.   else if(key2 == 0)
  57.   {
  58.     Control.delay_ms(5);//消抖延时
  59. if(key2 == 0)
  60. {
  61. switch(num3)
  62. {
  63. case 0: num3=Control.Find_position(0xfd);break;
  64. case 1: num3=Control.Find_position(0xfb);break;
  65. case 2: num3=Control.Find_position(0xf7);break;
  66. case 3: num3=Control.Find_position(0xef);break;
  67. case 4: num3=Control.Find_position(0xdf);break;
  68. case 5: num3=Control.Find_position(0xbf);break;
  69. case 6: num3=Control.Find_position(0xfe);break;
  70. case 7: num3=Control.Find_position(0xcf);break;
  71. case 11:num3=Control.Find_position(0xf9);break;
  72. }
  73. while(!key2);      //等待按键释放
  74. }
  75.   }
  76.   /*以上是第三个按键按下的函数即是顺时针的函数*/
  77.   else if(key3 == 0 )
  78.   {
  79.     Control.delay_ms(5); //消抖延时
  80. if(key3 == 0 )
  81. {
  82. switch(num3)
  83. {
  84. case 0: num3=Control.Find_position(0xdf);break;
  85. case 5: num3=Control.Find_position(0xef);break;
  86. case 4: num3=Control.Find_position(0xf7);break;
  87. case 3: num3=Control.Find_position(0xfb);break;
  88. case 2: num3=Control.Find_position(0xfd);break;
  89. case 1: num3=Control.Find_position(0xbf);break;
  90. case 6: num3=Control.Find_position(0xfe);break;
  91. case 7: num3=Control.Find_position(0xcf);break;
  92. case 11:num3=Control.Find_position(0xf9);break;
  93. }
  94. while(!key3);   //等待按键释放
  95. }
  96.   }
  97.   /*以上是第四个按键按下的函数即是逆时针的函数*/
  98. }

  99. #include "Game.h"
  100. #include "main.h"
  101. #include "sys.h"
  102. Enable flag = False;
  103. uint num0,num1,num2;

  104. void T0_timer() interrupt 1
  105. {
  106.   TH0 =(65536-45872)/256;
  107.   TL0 =(65536-45872)%256;
  108.   num0++;

  109.   if(num0==20)
  110.   {
  111.   num1++;
  112.   num0=0;
  113.   }
  114.   if(num1==10)
  115.   {
  116.    num1=0;
  117.   num2++;
  118.   }
  119.   if(num2==10)
  120.   {
  121.   num2=0;
  122.   }

  123.   Control.Nixie_Display(num1);
  124.   Control.Nixie_Display(num2);
  125.   Control.CS_Enable(True);
  126.   
  127. }
  128. void Sys_init()
  129. {
  130.   
  131.     TMOD = 0X01;
  132. TH0 = (65536-45872)/256;
  133. TL0 = (65536-45872)%256;
  134. EA = 1;
  135. ET0 = 1;
  136. TR0 = 1;
  137. num2=0;
  138.     num0 = 0;
  139. num1 = 0;
  140. }
  141. void Game_Init()
  142. {
  143.     //Sys_init();
  144. Control.Init_LCD();
  145. Control.LCD_PutString(1,1,"俄罗斯方块");
  146. Control.LCD_PutString(0,2,"当前得分");
  147. Control.LCD_PutString(0,3,"电气信息工程学院");
  148. Control.LCD_PutString(0,4,"2018年10月31");
  149. while(1)
  150.     {
  151.   //Left_shift();
  152.   
  153. Control.Write_Cmd(0x90+5);
  154. Control.Write_Data('0'+score/10);
  155. Control.Write_Data('0'+score%10);
  156. //Control.Left_shift() ;
  157. Control.Regulation_Game(2);
  158.   
  159.   
  160. //  Disable(0,8);
  161. }

  162. #include "sys.h"
  163. #include "main.h"
  164. #include "game.h"
  165. #include "st7290.h"
  166. #include "key.h"
  167. int score=0;
  168. uint num3=0;
  169. uchar code Nixie[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0x80,0X90,0xff};     //显示的数
  170. uchar code vide_Game[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0xf9,0x9c,0xdc,0xa3,0xcf,0xe3,0xff};     //方块

  171. void beep_enabel(Enable enable,uint index)
  172. {
  173.    uint x=0;
  174.    for(;x<index;x++)
  175.    {
  176.    Control.delay_ms(100);
  177.    beep = enable == True? 1 : 0;
  178.    }
  179. }
  180. uint Find_position(char parameter)  //查找位置函数
  181. {
  182.    uint index=0,i;
  183.    uint length = sizeof(vide_Game);
  184.    for(i=0;i<length;i++)
  185.    {
  186.      if(parameter==vide_Game[i])
  187.   {
  188.     index=i;
  189.     break;
  190.   }
  191.    }
  192.      return index;
  193. }

  194. void delay_ms(uint flag)  //延时函数
  195. {
  196.    uint i,j;
  197.    for(i = 0; i < flag; i++)
  198.    for(j = 110; j > 0; j--);
  199. }

  200. void CS_Enable(Enable enable)    //CS使能或失能函数
  201. {
  202.   if(enable == True)
  203.   {
  204.    P2 = 0XFF;
  205.   }
  206.   else
  207.   if(enable == False)
  208.   {
  209.    P2 = 0XDF;
  210.   }
  211. }

  212. void Nixie_Display(uint index)        //数码管显示函数
  213. {
  214. char temp,i = 0;
  215. clk = 0;
  216. Control.CS_Enable(False);
  217. temp = Nixie[index];
  218. for(;i<8;i++)
  219. {
  220.   din = temp&0x80;
  221.   clk = 1;
  222.   clk = 1;
  223.   clk = 0;
  224.   clk = 0;
  225.   temp <<=1;
  226. }
  227. }

  228. void Game_Display(uint index)        //游戏产生的种子
  229. {
  230. char temp,i = 0;
  231. clk = 0;
  232. Control.CS_Enable(False);
  233. temp = vide_Game[index];
  234. for(;i<8;i++)
  235. {
  236.   din = temp&0x80;
  237.   clk = 1;
  238.   clk = 1;
  239.   clk = 0;
  240.   clk = 0;
  241.   temp <<=1;
  242. }
  243. }
  244. void Result_Display(char index)        //用来显示最后的记分的
  245. {
  246. char temp,i = 0;
  247. clk = 0;
  248. Control.CS_Enable(False);
  249. temp = index;
  250. for(;i<8;i++)
  251. {
  252.   din = temp&0x80;
  253.   clk = 1;
  254.   clk = 1;
  255.   clk = 0;
  256.   clk = 0;
  257.   temp <<=1;
  258. }
  259. }

  260. void Disable(uchar index1,uchar index2 )   //这个函数是用来设置数码管哪几个不亮的
  261. {
  262.    for(;index1 < index2;index1++)
  263.    {
  264.        Nixie_Display(10);
  265.    }
  266. }

  267. void Regulation_Game(uint index)      //这个函数是用来执行游戏的规则的
  268. {
  269.   int i;
  270.   static uint seed=1,value=sizeof(vide_Game)-1 ,bug=5;
  271.   static char temp=0xff;
  272.   srand(seed);
  273.    num3=1+rand()%bug;       //随机种子
  274.   for(i=7;i>=0;i--)
  275.   {
  276.   Control.KeyScan();
  277.      Game_Display(num3);        //这个是移动的数
  278.   Disable(0,i);
  279.   Control.Result_Display(temp);      //这个是用来显示在第一位数码管上的值
  280.   CS_Enable(True);
  281.   delay_ms(1000);
  282.   CS_Enable(False);
  283.   delay_ms(1000);
  284.   Disable(0,8);
  285.   seed++;            //更新随机种子
  286.   }
  287.   /****************************以下为该游戏的协议****************************************/
  288.   temp = temp&vide_Game[num3];  value=num3;     //进行与操作显示最后一位数
  289.   if(temp==Nixie[8]) { score++; temp=0xff; Control.beep_enabel(True,3); Control.beep_enabel(False,1);}  //出结果后进行消去数码管上的数
  290.   if(bug==12) { bug=5; }       //限制随机种子的范围
  291.   else{ bug++; }
  292.   
  293. }
  294. void Left_shift()      //这个是左移函数
  295. {
  296.   int i;
  297.   for(i = 7;i >= 0;i--)
  298.   {
  299.    Control.Nixie_Display(i);
  300.    Control.Disable(0,i);
  301.    Control.CS_Enable(True);
  302.    Control.delay_ms(1000);
  303.    Control.CS_Enable(False);
  304.    Control.delay_ms(1000);
  305.    Control.Disable(0,8);
  306.   }
  307. }
  308. void Right_shift()                  //这个是又移函数
  309. {
  310.   int i;
  311.   for(i=0;i<8;i++)
  312.   {
  313.   Control.Nixie_Display(i);
  314.   Control.CS_Enable(True);
  315.   Control.delay_ms(1000);
  316.   Control.CS_Enable(False);
  317.   Control.delay_ms(1000);
  318.   }
  319. }


  320. CONTROL Control=
  321. {
  322. CS_Enable,
  323. Game_Init,
  324. delay_ms,
  325. Disable,
  326. Regulation_Game,
  327. Nixie_Display,
  328.     Left_shift,
  329. Right_shift,
  330. Init_LCD,
  331. LCD_PutString,
  332. Write_Data,
  333. Write_Cmd,
  334. Game_Display,
  335. KeyScan,
  336. Find_position,
  337. Result_Display,
  338. beep_enabel,
  339. };

复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2018-11-4 00:35 | 只看该作者
补全头文件 原理图或者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

板凳
ID:418731 发表于 2018-11-4 20:20 | 只看该作者
这是什么板子的??战舰v3还是阿波罗?可以直接烧进去吗?
回复

使用道具 举报

地板
ID:390172 发表于 2018-11-4 21:54 | 只看该作者
王孙浩 发表于 2018-11-4 20:20
这是什么板子的??战舰v3还是阿波罗?可以直接烧进去吗?

51单片机
回复

使用道具 举报

5#
ID:390172 发表于 2018-11-4 21:55 | 只看该作者
王孙浩 发表于 2018-11-4 20:20
这是什么板子的??战舰v3还是阿波罗?可以直接烧进去吗?

这个是自己用于单片机实习写的程序
回复

使用道具 举报

6#
ID:390172 发表于 2018-11-4 22:02 | 只看该作者
admin 发表于 2018-11-4 00:35
补全头文件 原理图或者详细说明一下电路连接即可获得100+黑币

这个板子是51单片机的板子,在资料的sys.h文件中,#include "reg52.h"
回复

使用道具 举报

7#
ID:390172 发表于 2018-11-4 22:03 | 只看该作者
王孙浩 发表于 2018-11-4 20:20
这是什么板子的??战舰v3还是阿波罗?可以直接烧进去吗?

游戏是用数码管写的
回复

使用道具 举报

8#
ID:504322 发表于 2020-5-24 19:37 | 只看该作者
写得太好了,感谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表