设为首页收藏本站淘宝杂货铺

从F到0 - From F to 0

 找回密码
 注册已关闭
搜索
查看: 1951|回复: 3
收起左侧

数字推盘游戏4x4串口版 可在STC15F104E中运行

[复制链接]
发表于 2017-7-14 07:03:59 | 显示全部楼层 |阅读模式
本帖最后由 LscmunaixMG 于 2017-7-20 21:51 编辑

u=3698854252,2014413796&fm=58.jpg

(图文无关)


  1. /*
  2. 数字推盘游戏4x4串口版 可在STC15F104E中运行
  3. By:LscmunaixMG 2017-07-14
  4. */

  5. #include "reg51.h"
  6. #include "intrins.h"
  7. sbit rxd=P3^0; //数据接收口
  8. sbit txd=P3^1; //数据发送口
  9. sfr AUXR   = 0x8E; //定义AUXR寄存器
  10. unsigned char ped[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};

  11. unsigned char code xyd[64] = { //拼图板移动方向与0交换坐标数据,请勿修改否则数字会无法正常移动。
  12.         0x04, 0x10, 0x01, 0x10, 0x05, 0x10, 0x02, 0x00, 0x06, 0x10, 0x03, 0x01, 0x07, 0x10, 0x10, 0x02,
  13.         0x08, 0x00, 0x05, 0x10, 0x09, 0x01, 0x06, 0x04, 0x0A, 0x02, 0x07, 0x05, 0x0B, 0x03, 0x10, 0x06,
  14.         0x0C, 0x04, 0x09, 0x10, 0x0D, 0x05, 0x0A, 0x08, 0x0E, 0x06, 0x0B, 0x09, 0x0F, 0x07, 0x10, 0x0A,
  15.         0x10, 0x08, 0x0D, 0x10, 0x10, 0x09, 0x0E, 0x0C, 0x10, 0x0A, 0x0F, 0x0D, 0x10, 0x0B, 0x10, 0x0E
  16. };


  17. sfr INT_CLKO = 0x8F; //定义下降沿中断寄存器


  18. void delay_uart(){ //延时时间1除以波特率秒
  19.     unsigned char a,b;
  20.     for(b=3;b>0;b--)
  21.         for(a=94;a>0;a--);
  22. }




  23.         void txd_data(unsigned char i){  //发送数据
  24.         unsigned char j=1;//控制移位
  25.         unsigned char k=8;//控制循环次数
  26.                 delay_uart();//延时时间
  27.                 txd=0; //发送起始位,低电平
  28.                 while(k--){ //下面循环8次
  29.                 delay_uart();//延时时间
  30.                 txd=(i&j)/j; //发送数据
  31.                 j<<=1; //左移1位,发送下1位数据
  32.                 }
  33.                 delay_uart();//延时时间
  34.                 txd=1;  //发送停止位
  35.         }

  36.         unsigned char rxd_data(){ //接收数据
  37.         unsigned char j=1;//控制移位
  38.         unsigned char k=8;//控制循环次数
  39.         unsigned char d=0;//存放数据
  40.                 while(rxd == 1); //等待起始位低电平
  41.                 while(k--){//下面循环8次
  42.                 delay_uart(); //延时时间
  43.                 d|=(rxd*j); //存入数据
  44.                 j<<=1;  //左移1位,接收下1位数据
  45.                 }
  46.                 delay_uart();//延时时间
  47.                 if(rxd == 1){ //停止位为高电平
  48.                 return d; //返回数据
  49.                 } else {
  50.                 return 0; //无效数据 返回0
  51.                 }
  52.         }

  53. void send_text(unsigned char *text){ //发送字符串
  54.         for(;*text!=0;text++){  //遇到停止符0结束发送
  55.                 txd_data(*text); //发送数据
  56.         }
  57. }
  58. void send_enter(){ //发送换行
  59.                 txd_data(0x0D);
  60.                 txd_data(0x0A);
  61.         }

  62. void send_puzzle(){        //发送拼图数据
  63. unsigned char a=0;

  64.         txd_data(0x0C); //清屏
  65.         send_text("┏━┳━┳━┳━┓");send_enter(); //发送顶部表格框架
  66.                 for(a=0;a<16;a++){
  67.                 send_text("┃");
  68.                 if(ped[a] == 0){ //读取到的数字为0则发送2个空格
  69.                         txd_data(0x20);
  70.                         txd_data(0x20);
  71.                 } else { //不为0则发送数字
  72.                         txd_data((ped[a]/10)|0x30);  //发送数字十位
  73.                         txd_data((ped[a]%10)|0x30);  //发送数字个位
  74.                 }
  75.                
  76.                                 if(a==3 || a==7 || a==11){ //读取到第3 7 11个数字
  77.                                 send_text("┃"); //发送分隔符
  78.                                 send_enter();
  79.                                 send_text("┣━╋━╋━╋━┫"); //发送中间表格框架
  80.                                 send_enter();
  81.                                 }
  82.                 }
  83.         send_text("┃");
  84.         send_enter();
  85.         send_text("┗━┻━┻━┻━┛"); //发送底部表格框架


  86. }

  87. unsigned char g0xy(){ //从拼图数据中获取0的位置并且返回
  88.         unsigned char add=0; //计数
  89.                 for(add=0;add<=15;add++){
  90.                         if(ped[add] == 0){ //读取到0
  91.                         break; //跳出循环
  92.                         }
  93.                 }
  94.         return add; //返回0的位置


  95. }


  96. void epp(unsigned char a,unsigned char b){ //通过坐标找到数字然后进行交换
  97.         unsigned char ad=0; //坐标地址a数据
  98.         unsigned char bd=0; //坐标地址b数据
  99.                 if(a>15 || b>15){  //地址a或b大于15则退出避免出现错误
  100.                         return;
  101.                 }
  102.                
  103.                 ad=ped[a]; //读取a的数据
  104.                 bd=ped[b]; //读取b的数据
  105.                 ped[a]=bd; //地址a放入地址b的数据
  106.                 ped[b]=ad; //地址b放入地址a的数据
  107.         
  108.                
  109. }

  110.         void init_uart(){ //初始化串口
  111.                     AUXR |= 0x80;                      //设置AUXR寄存器
  112.                     INT_CLKO |= 0x40;           //开串口中断 (允许串口接收数据)
  113.                      EA = 1;                      //启用I/O口外部中断功能

  114.         }
  115.         //--------------------------------
  116.         void main(){ //入口函数
  117.                 unsigned char a=0;
  118.                 init_uart(); //初始化串口
  119.                 send_puzzle();
  120.                 while(1);

  121. }

  122. void exint4() interrupt 16{ //P3.0下降沿中断 (串口接收到数据)
  123.         unsigned char dat=0;  //数据存放变量
  124.         unsigned char m=0; //拼图数字移动方向
  125.         unsigned char xy0=0; //0的位置
  126.         unsigned char y=0; //要对该坐标的数字与0进行交换
  127.         unsigned char a=0;
  128.          INT_CLKO &= 0xBF;  //关闭中断,避免重复触发中断程序。
  129.         dat=rxd_data();    //串口接收数据。
  130.                         if(dat == 0x57 || dat == 0x77) m=1; //W键按下 (上)
  131.                         if(dat == 0x41 || dat == 0x61) m=3; //A键按下 (左)
  132.                         if(dat == 0x53 || dat == 0x73) m=2; //S键按下 (下)
  133.                         if(dat == 0x44 || dat == 0x64) m=4; //D键按下 (右)

  134.                                 if(m >= 1 && m <= 4){ //进行了一次移动操作

  135.                                         xy0=g0xy(); //获取0的位置(在数码管中不会显示0)
  136.                                               y=xyd[xy0*4+m-1]; //要和0的坐标交换的数字坐标
  137.                                         if(y != 16){ //数字可以被移动
  138.                                         epp(xy0,y); //被移动坐标的数字与0交换位置即可完成移动
  139.                                         send_puzzle();

  140.                                                 } else { //数字不能被移动
  141.                                        
  142.                                         }
  143.                                 }



  144.           INT_CLKO |= 0x40; //开启中断,允许下次接收数据。        
  145. }

复制代码

发表于 2017-8-13 21:32:01 | 显示全部楼层
1个月么人要沙发,我先收了。
发表于 2017-9-17 13:54:50 来自手机 | 显示全部楼层
间隔了1个多月板凳的来了。
发表于 2019-4-13 00:15:14 | 显示全部楼层
两年没人要地板
您需要登录后才可以回帖 登录 | 注册已关闭

本版积分规则

QQ|手机版|Archiver|从F到0 ( 蒙ICP备17002595号-1 )
蒙公网安备15010402000325号

腾讯云安全认证

GMT+8, 2024-3-29 10:29 , Processed in 0.552032 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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