|
本帖最后由 LscmunaixMG 于 2017-7-20 21:51 编辑
(图文无关)
- /*
- 数字推盘游戏4x4串口版 可在STC15F104E中运行
- By:LscmunaixMG 2017-07-14
- */
- #include "reg51.h"
- #include "intrins.h"
- sbit rxd=P3^0; //数据接收口
- sbit txd=P3^1; //数据发送口
- sfr AUXR = 0x8E; //定义AUXR寄存器
- unsigned char ped[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
- unsigned char code xyd[64] = { //拼图板移动方向与0交换坐标数据,请勿修改否则数字会无法正常移动。
- 0x04, 0x10, 0x01, 0x10, 0x05, 0x10, 0x02, 0x00, 0x06, 0x10, 0x03, 0x01, 0x07, 0x10, 0x10, 0x02,
- 0x08, 0x00, 0x05, 0x10, 0x09, 0x01, 0x06, 0x04, 0x0A, 0x02, 0x07, 0x05, 0x0B, 0x03, 0x10, 0x06,
- 0x0C, 0x04, 0x09, 0x10, 0x0D, 0x05, 0x0A, 0x08, 0x0E, 0x06, 0x0B, 0x09, 0x0F, 0x07, 0x10, 0x0A,
- 0x10, 0x08, 0x0D, 0x10, 0x10, 0x09, 0x0E, 0x0C, 0x10, 0x0A, 0x0F, 0x0D, 0x10, 0x0B, 0x10, 0x0E
- };
- sfr INT_CLKO = 0x8F; //定义下降沿中断寄存器
- void delay_uart(){ //延时时间1除以波特率秒
- unsigned char a,b;
- for(b=3;b>0;b--)
- for(a=94;a>0;a--);
- }
- void txd_data(unsigned char i){ //发送数据
- unsigned char j=1;//控制移位
- unsigned char k=8;//控制循环次数
- delay_uart();//延时时间
- txd=0; //发送起始位,低电平
- while(k--){ //下面循环8次
- delay_uart();//延时时间
- txd=(i&j)/j; //发送数据
- j<<=1; //左移1位,发送下1位数据
- }
- delay_uart();//延时时间
- txd=1; //发送停止位
- }
- unsigned char rxd_data(){ //接收数据
- unsigned char j=1;//控制移位
- unsigned char k=8;//控制循环次数
- unsigned char d=0;//存放数据
- while(rxd == 1); //等待起始位低电平
- while(k--){//下面循环8次
- delay_uart(); //延时时间
- d|=(rxd*j); //存入数据
- j<<=1; //左移1位,接收下1位数据
- }
- delay_uart();//延时时间
- if(rxd == 1){ //停止位为高电平
- return d; //返回数据
- } else {
- return 0; //无效数据 返回0
- }
- }
- void send_text(unsigned char *text){ //发送字符串
- for(;*text!=0;text++){ //遇到停止符0结束发送
- txd_data(*text); //发送数据
- }
- }
- void send_enter(){ //发送换行
- txd_data(0x0D);
- txd_data(0x0A);
- }
- void send_puzzle(){ //发送拼图数据
- unsigned char a=0;
- txd_data(0x0C); //清屏
- send_text("┏━┳━┳━┳━┓");send_enter(); //发送顶部表格框架
- for(a=0;a<16;a++){
- send_text("┃");
- if(ped[a] == 0){ //读取到的数字为0则发送2个空格
- txd_data(0x20);
- txd_data(0x20);
- } else { //不为0则发送数字
- txd_data((ped[a]/10)|0x30); //发送数字十位
- txd_data((ped[a]%10)|0x30); //发送数字个位
- }
-
- if(a==3 || a==7 || a==11){ //读取到第3 7 11个数字
- send_text("┃"); //发送分隔符
- send_enter();
- send_text("┣━╋━╋━╋━┫"); //发送中间表格框架
- send_enter();
- }
- }
- send_text("┃");
- send_enter();
- send_text("┗━┻━┻━┻━┛"); //发送底部表格框架
- }
- unsigned char g0xy(){ //从拼图数据中获取0的位置并且返回
- unsigned char add=0; //计数
- for(add=0;add<=15;add++){
- if(ped[add] == 0){ //读取到0
- break; //跳出循环
- }
- }
- return add; //返回0的位置
- }
- void epp(unsigned char a,unsigned char b){ //通过坐标找到数字然后进行交换
- unsigned char ad=0; //坐标地址a数据
- unsigned char bd=0; //坐标地址b数据
- if(a>15 || b>15){ //地址a或b大于15则退出避免出现错误
- return;
- }
-
- ad=ped[a]; //读取a的数据
- bd=ped[b]; //读取b的数据
- ped[a]=bd; //地址a放入地址b的数据
- ped[b]=ad; //地址b放入地址a的数据
-
-
- }
- void init_uart(){ //初始化串口
- AUXR |= 0x80; //设置AUXR寄存器
- INT_CLKO |= 0x40; //开串口中断 (允许串口接收数据)
- EA = 1; //启用I/O口外部中断功能
- }
- //--------------------------------
- void main(){ //入口函数
- unsigned char a=0;
- init_uart(); //初始化串口
- send_puzzle();
- while(1);
- }
- void exint4() interrupt 16{ //P3.0下降沿中断 (串口接收到数据)
- unsigned char dat=0; //数据存放变量
- unsigned char m=0; //拼图数字移动方向
- unsigned char xy0=0; //0的位置
- unsigned char y=0; //要对该坐标的数字与0进行交换
- unsigned char a=0;
- INT_CLKO &= 0xBF; //关闭中断,避免重复触发中断程序。
- dat=rxd_data(); //串口接收数据。
- if(dat == 0x57 || dat == 0x77) m=1; //W键按下 (上)
- if(dat == 0x41 || dat == 0x61) m=3; //A键按下 (左)
- if(dat == 0x53 || dat == 0x73) m=2; //S键按下 (下)
- if(dat == 0x44 || dat == 0x64) m=4; //D键按下 (右)
- if(m >= 1 && m <= 4){ //进行了一次移动操作
- xy0=g0xy(); //获取0的位置(在数码管中不会显示0)
- y=xyd[xy0*4+m-1]; //要和0的坐标交换的数字坐标
- if(y != 16){ //数字可以被移动
- epp(xy0,y); //被移动坐标的数字与0交换位置即可完成移动
- send_puzzle();
- } else { //数字不能被移动
-
- }
- }
- INT_CLKO |= 0x40; //开启中断,允许下次接收数据。
- }
复制代码
|
|