找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5115|回复: 9
收起左侧

16x16点阵贪吃蛇 单片机源程序 带注释

  [复制链接]
ID:633559 发表于 2020-1-21 23:21 | 显示全部楼层 |阅读模式
一年前做的小玩意了,硬件丢失了,程序还在,以前都是写在一个文件内,翻出来分成几个文件,程序注释写的很详细,希望对初入单片机的师兄有所帮助 3.png

单片机源程序如下:
  1. //=================================================================================================================================================================
  2. //软件功能:贪吃蛇
  3. //硬件描述:最小系统+4x(8x8点阵)+ (1x(HC154)+3x(74HC14D)) + 1x(HC595)
  4. //程序描述:74595.c中有串进并出程序
  5. //          delay.c中有延迟函数
  6. //          dispaly.c中有点阵显示函数
  7. //          anjian.c中有按键函数
  8. //          related.c中有初始化参数函数、游戏结束图案函数、点阵显示清除函数、糖果随机函数、蛇显示变化函数
  9. //功能概括描述:16x16点阵用于显示、5个按键有旋转按键、上、下、左、右按键
  10. //              上、下、左、右按键用于控制蛇上下左右移动
  11. //              有转折点判断(理论上蛇可以打15折)、蛇碰壁判断、蛇速度改变判断
  12. //=================================================================================================================================================================
  13. #include "reg52.h"                                                                                               //51头文件
  14. #include "intrins.h"                                                                                             //部分运算符所需头文件
  15. #include "74595.h"                                                                                               //74595程序
  16. #include "delay.h"
  17. #include "display.h"
  18. #include "anjian.h"
  19. #include "related.h"
  20. #define uchar unsigned char
  21. #define uint unsigned int
  22. //=================================================================================================================================================================
  23. //sbit Beep=P2^7;                                                                                                         //蜂鸣器
  24. uint HUANCUN[16],STX,SWX,GCUNY;                       //缓存显示数组,蛇头横坐标,蛇尾横坐标,转折点存储数组,果子位置存储
  25. uchar SSS,t,STY,SWY,GUO,CBN,GCUNX,Q,cus;                         //蛇方向变量,定时器计时变量,蛇头纵坐标,蛇尾纵坐标,转折点反向存储数组,糖果,计时变量,随机数,蛇方向前一个状态变量
  26. uchar idata ZZS[16];
  27. uint idata ZZD[16];
  28. //=================================================================================================================================================================
  29. void Init()                                                                                   //初始化
  30. {
  31.         TMOD=0x01;                                                                                                   //工作方式1
  32.         EA=1;                                                                                                               //CPU中断开启
  33.         ET0=1;                                                                                                             //定时器T0中断开启
  34.         TH0=(65536-5000)/256;                                                                 //定时5ms
  35.         TL0=(65536-5000)%256;
  36.         TR0=0;                                                                                                             //定时器关闭状态
  37.         KS=1;                                                                                                               //开始键置高电平
  38. //        Beep=0;
  39. }
  40. //=================================================================================================================================================================
  41. void main()
  42. {
  43.         Init();
  44.         while(1)
  45.         {
  46.           Q=rand()%256;                                                 //随机代码放在while(1)函数中不停运转
  47.                 if(TR0==0){                                                   //如果定时器在关闭状态
  48.                         J_S();                                                           //清除缓存
  49.                         K_S();                                                           //各种数据初始化
  50.                 }else{
  51.                    if(GUO!=1){                                         //如果没有糖果         
  52.                      SUI_JI();                                         //调用随机子程序
  53.                            t--;                                                           //蛇的速度加快
  54.                            CBN=t;                                                   //CBN用于保存改变后的t
  55.                    }
  56.                  }
  57.                 XIANSI();                                                           //循环显示函数
  58.         }
  59. }
  60. //=================================================================================================================================================================
  61. void time0() interrupt 1
  62. {
  63.         TH0=(65536-5000)/256;
  64.         TL0=(65536-5000)%256;
  65.         AN_J();                                       //调用按键子程序         
  66.         if((--CBN==0)||(cus!=SSS)){
  67.           CBN=t;                                                                               //CBN随t的变化而变化
  68.           SE_BH();                                                                             //调用蛇变子程序
  69.         }
  70. }
  71. //=================================================================================================================================================================
复制代码
  1. #include "related.h"
  2. //=================================================================================================================================================================
  3. extern uchar SSS,t,STY,SWY,GUO,GCUNX,Q;
  4. extern uint HUANCUN[16],STX,SWX,GCUNY;
  5. extern uchar idata ZZS[16];
  6. extern uint idata ZZD[16];
  7. //=================================================================================================================================================================
  8. //功能描述:开始键按下后,初始化各种参数
  9. //=================================================================================================================================================================
  10. void K_S()
  11. {
  12.         uchar i;
  13.         if(KS==0){                                                                  //如果开始键按下           
  14.           QC_HC();
  15.           SSS=2;                                                                    //蛇方向向右
  16.           t=50;                                                                      //蛇初始速度
  17.           SWY=7;                                                                    //蛇尾初始纵坐标
  18.           STY=7;                                                                    //蛇头初始纵坐标
  19.           STX=0x0040;                                                          //蛇头初始横坐标
  20.           SWX=0x0100;                                                          //蛇尾初始横坐标
  21.           HUANCUN[7]=0x01c0;                                //初始化蛇全身
  22.           ZZS[0]=SSS;                                                          //存储蛇的方向
  23.           for(i=0;i<16;i++){
  24.             ZZD[i]=0xffff;
  25.           }
  26.           GUO=0;                                                                    //无糖果
  27.           TR0=1;                                                                    //定时器开启
  28.         }
  29. }
  30. //=================================================================================================================================================================
  31. //功能描述:游戏结束后显示预设图案
  32. //=================================================================================================================================================================
  33. void J_S()                                                                                      //结束子程序
  34. {
  35.         QC_HC();
  36.   HUANCUN[2]=0x0ff0;                                                                                  //显示笑脸
  37.         HUANCUN[3]=0x1008;
  38.          HUANCUN[4]=0x2424;
  39.   HUANCUN[5]=0x2a54;
  40.         HUANCUN[6]=0x2004;
  41.         HUANCUN[7]=0x2004;
  42.         HUANCUN[8]=0x2004;
  43.         HUANCUN[9]=0x2004;
  44.   HUANCUN[10]=0x2244;
  45.         HUANCUN[11]=0x2184;
  46.         HUANCUN[12]=0x1008;
  47.   HUANCUN[13]=0x0ff0;
  48. }
  49. //=================================================================================================================================================================
  50. //功能描述:16x16点阵显示清除
  51. //=================================================================================================================================================================
  52. void QC_HC()                                                                                                  //清除缓存子程序
  53. {
  54.         uchar i;
  55.         for(i=0;i<16;i++){                                                                  //缓存清零
  56.           HUANCUN[i]=0;
  57.         }         
  58. }
  59. //=================================================================================================================================================================
  60. //功能说明:”糖果“随机函数
  61. //程序说明:Q取0~255之间的数,对应16x16点阵上的256个点
  62. //          Q/16取16x16点阵的哪一行,0x0001<<(Q%16)取16x16点阵的哪一列
  63. //          Q随机出一个数后,有可能点阵上的点是亮着的,要重新随机,直到随机到没亮着的点
  64. //          然后改变对应缓存显示数组HUANCUN[]里的数据
  65. //          16x16点阵是以左上角为原点的一个坐标(不过y轴不是负的),记录下对应点的横坐标和纵坐标
  66. //          改变“糖果”的状态变量GUO=1,就是说当前有“糖果”在
  67. //=================================================================================================================================================================
  68. void SUI_JI()
  69. {
  70.         while(HUANCUN[Q/16]&(0x0001<<(Q%16)))        //判断随机数对应的点阵上的点是否是灭的状态
  71.         {
  72.                 Q=rand()%256;                                                                                           //如果是亮的,那么再随机一次,直到随机到灭的点
  73.         }
  74.         HUANCUN[Q/16]|=(0x0001<<(Q%16));                         //让这个点亮起来
  75.         GCUNX=Q/16;                                                                                                     //记录该点的横坐标和纵坐标
  76.         GCUNY=(0x0001<<(Q%16));
  77.         GUO=1;                                                                                                                     //记录糖果状态
  78. }
  79. //=================================================================================================================================================================
  80. //功能说明:当蛇尾处在转折点处时,这个转折点数据没用了,判断蛇还有没有转折点,如果有,覆盖掉这个转折点
  81. //          根据改变后的转折点,确定蛇尾的坐标
  82. //=================================================================================================================================================================
  83. void ZZ_X()
  84. {
  85.         uchar i;
  86.         if(ZZS[1]!=0){                                                                          //如果有第二个转折点                                                                                   
  87.           for(i=0;i<15;i++){                                                        //把第一个转折点覆盖   
  88.                   ZZD[i]=ZZD[i+1];
  89.                   ZZS[i]=ZZS[i+1];                                                                  
  90.           }
  91.         }
  92.         switch(ZZS[0])                                                                                                  //判断改变后蛇的方向,而后改变蛇尾坐标
  93.         {
  94.                 case 1:
  95.                         SWY--;
  96.                   break;   
  97.           case 2:
  98.                         SWX>>=1;
  99.                   break;
  100.                 case 3:
  101.                         SWY++;
  102.                   break;
  103.                 case 4:
  104.                         SWX<<=1;
  105.                   break;               
  106.         }        
  107. }
  108. //=================================================================================================================================================================
  109. //思维说明:蛇移动是不是要判断前面有没有障碍物?这个障碍物有可能是蛇的身体,也有可能是糖果。还有,蛇会不会碰壁呢?
  110. //程序说明:根据蛇的方向(SSS)来分成4种情况,
  111. //          蛇头就是一个点,这个点被记录下横(STY)和纵坐标(STX),再加上记录下的方向(SSS),可以确定蛇头的下一个位置
  112. //          当SSS=1时,蛇向上移动,把蛇头横坐标(STX)和缓存显示数组HUANCUN[STY-1]相与,确定该位置是否被点亮,为什么是STY-1呢?点阵第一行对应HUANCUN[0]
  113. //          当该位置没被点亮时,表示蛇可以移动上去了,把蛇头的坐标改变
  114. //          否则,把该位置的坐标和糖果的坐标比较,如果是糖果位置,蛇头一样可变。其他情况游戏结束,关定时器TR0        
  115. //          其他3种情况分析同上
  116. //          蛇尾也不能忘了,一条蛇只标蛇头可不行
  117. //          如果蛇吃了糖果,那么蛇头长了一点,蛇尾不用变,蛇头坐标变后跳出函数就行了
  118. //          否则,就要让蛇尾灭掉HUANCUN[SWY]&=(~SWX);
  119. //          再则,一条蛇可会转弯的哦,那么必须要有转折点,不止一个,要判断,如果需要的话,要做改变
  120. //=================================================================================================================================================================
  121. void SE_BH()                                                                                                   //蛇变子程序
  122. {
  123.         switch(SSS)
  124.   {
  125.                 case 1:
  126.                         if(STY>0){                                         //大于0是要判断的,因为下面HUANCUN[STY-1]
  127.                     if((HUANCUN[STY-1]&STX)==0)                                                     //判断下一个蛇坐标是否是灭的
  128.                 STY--;                                                                                                     //蛇头坐标改变
  129.                 else{
  130.                                if(((STY-1)==GCUNX)&&(STX==GCUNY)){                       //否则,判断该点是否是糖果点                                   
  131.                     STY--;                                                                                           //蛇头坐标改变
  132.                                 GUO=0;                                                                                           //糖果变量清零
  133.                                            }else
  134.                                        TR0=0;                                                                                    //定时器关闭
  135.                                            return;                                                                                             //跳出
  136.                       }
  137.                         }else{
  138.                                  TR0=0;
  139.                                  return;
  140.                          }
  141.       break;
  142.                 case 2:
  143.                   if((HUANCUN[STY]&(STX>>1))==0)
  144.               STX>>=1;
  145.               else{
  146.                        if((STY==GCUNX)&&((STX>>1)==GCUNY)){
  147.                   STX>>=1;                                                                               //蛇头横坐标右移一位
  148.                         GUO=0;
  149.                       }else
  150.                          TR0=0;
  151.                       return;
  152.                                 }
  153.                         break;  
  154.     case 3:
  155.                   if((HUANCUN[STY+1]&STX)==0)
  156.               STY++;                                                                                           //蛇头纵坐标减一位
  157.               else{
  158.                 if(((STY+1)==GCUNX)&&(STX==GCUNY)){
  159.                   STY++;
  160.                         GUO=0;
  161.                              }else
  162.                                 TR0=0;
  163.                       return;
  164.                                 }
  165.                   break;                                                               
  166.     case 4:
  167.                   if((HUANCUN[STY]&(STX<<1))==0)
  168.               STX<<=1;
  169.               else{
  170.                 if((STY==GCUNX)&&((STX<<1)==GCUNY)){
  171.                   STX<<=1;
  172.                         GUO=0;
  173.                       }else  
  174.                          TR0=0;
  175.                       return;
  176.                     }
  177.                         break;
  178.   }
  179.         if((STX!=0)&&(STY>=0)&&(STY<16)){                                        //如果蛇头没超出边界
  180.           HUANCUN[STY]|=STX;                                                    //让蛇头亮起
  181.           HUANCUN[SWY]&=(~SWX);                                      //让蛇尾灭掉
  182.           switch(ZZS[0])
  183.           {
  184.                         case 1:
  185.                                 if(SWY!=ZZD[0])
  186.                                         SWY--;
  187.                             else ZZ_X();
  188.                                 break;
  189.                         case 2:
  190.                                 if(SWX!=ZZD[0])
  191.                                         SWX>>=1;
  192.                             else ZZ_X();
  193.                                 break;
  194.                         case 3:
  195.                                 if(SWY!=ZZD[0])
  196.                                         SWY++;
  197.                                          else ZZ_X();
  198.                                 break;
  199.                         case 4:
  200.                                 if(SWX!=ZZD[0])
  201.                                         SWX<<=1;
  202.                             else ZZ_X();
  203.                                 break;
  204.           }
  205.         }else{
  206.                  TR0=0;
  207. //                 return;
  208.    }        
  209. }
  210. //=================================================================================================================================================================
复制代码

  1. #include "anjian.h"

  2. extern uchar cus,STY,SSS;
  3. extern uint STX;
  4. extern uchar idata ZZS[16];
  5. extern uint idata ZZD[16];
  6. //=================================================================================================================================================================
  7. //思维说明:4个按键控制蛇的方向,当蛇往一个方向移动的时候,控制蛇在这一线上的移动方向的两个按键会失效,只有两个键有用
  8. //程序说明:SSS表示蛇方向的一个变量,有4个方向,取值范围是1~4
  9. //          当蛇的方向改变是,存储转折点的横或纵坐标放在数组ZZD[],存储转折点的方向存在ZZS[]
  10. //          蛇尾是跟着存储起来的转折点转向的,一个点的坐标用横坐标和纵坐标两个坐标表示的,这里为了节省存储空间,
  11. //          当蛇在横向上移动的时候,可以只存横坐标,为什么存横坐标?因为这个时候纵坐标不变
  12. //          当蛇在纵向上移动的时候,可以只存纵坐标
  13. //=================================================================================================================================================================
  14. void AN_J()                                                                                    //按键子程序
  15. {
  16.         static uchar a=1,b=1,c=1,d=1;                                  //定义4个方向键的状态变量
  17.         uchar i;
  18.         cus=SSS;                                                                                    //保存蛇的方向
  19.         if(SHANG!=a){                                                                          //比较按键当前状态和前一个状态是否一致
  20.           if(a==1){                                                                                  //前一个状态是否是高电平  
  21.             if((SSS!=1)&&(SSS!=3)){                                          //蛇的状态是左右的时候,才生效         
  22.                    SSS=1;
  23.                   }
  24.           }
  25.           a=SHANG;                                                                                  //锁住,直到下一次按键按下才会再进来
  26.         }
  27.         if(YOU!=b){
  28.           if(b==1){
  29.             if((SSS!=2)&&(SSS!=4)){
  30.                     SSS=2;
  31.                   }
  32.           }
  33.           b=YOU;
  34.         }
  35.         if(XIA!=c){
  36.           if(c==1){   
  37.             if((SSS!=1)&&(SSS!=3)){         
  38.                     SSS=3;
  39.                   }
  40.           }
  41.           c=XIA;
  42.         }
  43.         if(ZUO!=d){
  44.           if(d==1){
  45.             if((SSS!=2)&&(SSS!=4)){
  46.                     SSS=4;
  47.                   }
  48.           }
  49.           d=ZUO;
  50.         }
  51.         if(cus!=SSS){                                                                            //如果蛇的方向改变了
  52.           for(i=0;i<16;i++){                                                        //从第一个转折点开始判断   
  53.             if(ZZD[i]==0xffff){                              //如果转折点是0xffff,说明后面没有转折点了                  
  54.                           ZZS[i+1]=SSS;                                                          //把当前蛇的方向存储起来
  55.                           if((cus==1)||(cus==3)){                        //如果蛇前一个方向是上下               
  56.                             ZZD[i]=STY;                                                          //把转折点的纵坐标存储起来
  57.                           }else ZZD[i]=STX;                                                //否则,存横坐标
  58.                           break;                                                                            //跳出
  59.                   }
  60.           }
  61.         }
  62. }
  63. //=================================================================================================================================================================
复制代码

原理图: 无
仿真: 无
代码: 贪吃蛇.rar (58.42 KB, 下载次数: 101)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:935960 发表于 2021-6-14 18:25 | 显示全部楼层
原理图有吗?
回复

使用道具 举报

ID:554271 发表于 2021-6-22 15:28 | 显示全部楼层
请问博主有那个原理图吗?
回复

使用道具 举报

ID:981729 发表于 2021-11-17 09:18 | 显示全部楼层
请问楼主有原理图吗
回复

使用道具 举报

ID:633559 发表于 2022-1-18 21:33 | 显示全部楼层
呵,现在看来当是做的太水了,找了下工程还在

俄罗斯方块.rar

807.26 KB, 下载次数: 12, 下载积分: 黑币 -5

回复

使用道具 举报

ID:633559 发表于 2022-1-18 21:34 | 显示全部楼层

找了下,还在,上传了
回复

使用道具 举报

ID:633559 发表于 2022-1-18 21:43 | 显示全部楼层
想进步要学习 发表于 2022-1-18 21:33
呵,现在看来当是做的太水了,找了下工程还在

哎呀,想起来了,这图不对,当是8255没弄成,后面弄了个洞洞板焊了两个74LS595替换这部分电路了
回复

使用道具 举报

ID:292494 发表于 2022-2-7 21:24 来自手机 | 显示全部楼层
rand()这个函数是什么意思
回复

使用道具 举报

ID:883031 发表于 2022-2-8 10:47 | 显示全部楼层
看世界 发表于 2022-2-7 21:24
rand()这个函数是什么意思

Rand()rand函数没有参数,rand函数返回一个大于等于0小于1的随机数。
回复

使用道具 举报

ID:1106340 发表于 2023-12-29 20:40 | 显示全部楼层
有没有原理图啊铁子
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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