参考资料:
74hc138中文资料详细(74hc138引脚图及功能表_封装真值表及应用电路图) - 全文 - 电子发烧友网
三阶魔方还原图文教程-番茄魔方
电器原理图: 代码:#include "STC8952.h" #include//#include //#include //#include<74HC595.c> #define ulong unsigned long P0M1 = 0x01; P0M0 = 0x01; //P0开漏,其它准双 sbit testBit2 = P3^4; sbit testBit1 = P3^5; sbit modeBit1 = P3^6; sbit modeBit2 = P3^7; sbit stateR = P1^6; sbit stateB = P1^7; sbit key1 = P3^2; sbit key2 = P3^3; unsigned char cube[6][4] ={ {0xff, 0x00, 0x00,0x04}, {0x00, 0xff, 0x00,0x02}, {0x00, 0x00, 0xff,0x01}, {0xff, 0xff, 0x00,0x06}, {0xff, 0x00, 0xff,0x05}, {0x00, 0xff, 0xff,0x03}}; unsigned char tempCube[6][4] ={ {0x00, 0x00, 0x00,0x00}, {0x00, 0x00, 0x00,0x00}, {0x00, 0x00, 0x00,0x00}, {0x00, 0x00, 0x00,0x00}, {0x00, 0x00, 0x00,0x00}, {0x00, 0x00, 0x00,0x00}}; unsigned char getCharBit(char cr,unsigned char index){ return (cr&(0x80>>index))>0; } unsigned char getSurfacePieceRGB(unsigned char surfaceNumber,unsigned char index){ if(index==8)return cube[surfaceNumber][3]; return (0|getCharBit(cube[surfaceNumber][0],index)<<1|getCharBit(cube[surfaceNumber][1],index))<<1|getCharBit(cube[surfaceNumber][2],index); } unsigned char getTempSurfacePieceRGB(unsigned char surfaceNumber,unsigned char index){ if(index==8)return tempCube[surfaceNumber][3]; return (0|getCharBit(tempCube[surfaceNumber][0],index)<<1|getCharBit(tempCube[surfaceNumber][1],index))<<1|getCharBit(tempCube[surfaceNumber][2],index); } void setCharBit(unsigned char *cr,unsigned char index,unsigned char d){ //unsigned char j = 7-index; //if(index<0||index>7){ return;} if(d>0){ *cr=*cr|(0x80>>index); }else{ *cr=*cr&(~(0x80>>index)); } } void setSurfacePieceRGB(unsigned char surfaceNumber,unsigned char index,unsigned char rgb){ if(index==8){ cube[surfaceNumber][3] = 7&rgb; }else{ setCharBit(&cube[surfaceNumber][0],index,rgb&4); setCharBit(&cube[surfaceNumber][1],index,rgb&2); setCharBit(&cube[surfaceNumber][2],index,rgb&1); } } void setTempSurfacePieceRGB(unsigned char surfaceNumber,unsigned char index,unsigned char rgb){ if(index==8){ tempCube[surfaceNumber][3] = 7&rgb; }else{ setCharBit(&tempCube[surfaceNumber][0],index,rgb&4); setCharBit(&tempCube[surfaceNumber][1],index,rgb&2); setCharBit(&tempCube[surfaceNumber][2],index,rgb&1); } } // 设置第surfaceNumber个面的RGB值(0~9)*/ void setTempSurfaceRGBLuminance(unsigned char surfaceNumber,char rgbType,unsigned char rgb){ unsigned char d=0,i; for(i=0;i 1;i--){ setSurfacePieceRGB(tempCube[i/4][i%4],tempCube[i/4+3][i%4],getSurfacePieceRGB(tempCube[(i-1)/4][(i-1)%4],tempCube[(i-1)/4+3][(i-1)%4])); } setSurfacePieceRGB(tempCube[0][1],tempCube[3][1],temp); } } //某一个面旋转移动一位,移动两位为 90度。 typeRL=1 为顺时针,其它为逆时针 void surfaceLeftOrRightStep(unsigned char surfaceNumber,unsigned char typeRL){ unsigned char temp; unsigned char i; unsigned char cr; for(i = 0;i<3;i++){ cr = cube[surfaceNumber][i]; if(typeRL==1){ temp = cr&1; cr = cr>>1; cr = cr|(temp<<7); }else{ temp = cr&0x80; cr = cr<<1; cr = cr|(temp>>7); } cube[surfaceNumber][i] = cr; } } //延迟函数// void delayMinimum(ulong n){ ulong i; for(i=0;i >(i<<1); temp2 = (data2&temp)>>(i<<1); if(temp1!=temp2){//确认了是第几个编码器旋转,下面判断正反转 //temp1一个周期有四个阶段:00,10,11,01,00..... //需要判断出temp2是往那个周期方向变化的 if((temp1==0&&temp2==2)||(temp1==2&&temp2==3)||(temp1==3&&temp2==1)||(temp1==1&&temp2==0))//穷举正转情况 return 0x0100|i; else if((temp1==0&&temp2==1)||(temp1==1&&temp2==3)||(temp1==3&&temp2==2)||(temp1==2&&temp2==0))//穷举反转情况 return 0xff00|i; } } return 0x0000; } unsigned short detectInputCoderVersion(unsigned char type){ //i=1时,时间为1s unsigned short result = 1; unsigned short d1=(input8<<4)|(input4&0x0f);//记录当前所有编码状态 unsigned short d2; unsigned short count = 0xf; //延迟,如果不变说明当前稳定,开始检测,否则输出0 if(type)delay_ms(20); d2=(input8<<4)|(input4&0x0f); if(d1!=d2&&type)return 0x00; while(type==0||(modeBit1==1&&modeBit2==1&&key1==1&&key2==1)){//判断是否退出魔方模式 d2=(input8<<4)|(input4&0x0f); if(d1!=d2){//等待发生变化 //delayMinimum(5);//短暂延迟等待接触稳定后再读取编码 d2=(input8<<4)|(input4&0x0f); return detectInputCoderVersionSub(d1,d2); } if(type==0)break; } return 0x0000; } ///输出数据到LED / //移位寄存器 sbit DI = P1^4; //串行数据输入 sbit OE = P1^3; //输出使能 OE (低电平有效) sbit RCK = P1^2; //并行输出存储器锁存时钟线(上升沿触发) sbit SCK = P1^1; //数据输入时钟(上升沿触发) sbit CSCK = P1^0; //主复位(低电平有效) sbit LQH = P1^5; //串行输出位 //将寄存器芯片数据刷新输出到并行输出端 void rushICOut(){ RCK = 0; RCK = 1; RCK = 0; } //输入信号触发,触发一次读取一位数据输入寄存器 void triggerInputClock(){SCK = 0;SCK = 1;} //开启寄存器输出 void opernICOut(){OE = 0;} //关闭寄存器输出 void closeICOut(){OE = 1;} //清除数据 void clearICData(){ DI = 0; CSCK = 0; triggerInputClock(); CSCK = 1; rushICOut(); } //写入1位数据 void registerWriteonePinData (unsigned char pinData){ DI = pinData; triggerInputClock(); } ///输出数据到LED 1/ //接线方法:每个面4个寄存器,前三个分别按如下顺序接0~7号块的RGB引脚:(0-R,1-G,2-B) // QA-0 QB-1 QC-2 QD-3 QE-4 QF-5 QG-6 QH-7 //第4个寄存器接8号块的RGB:QA QB QC QD QE QF-8R QG-8G QH-8B //信号从3号寄存器输入,3-2-1-0 //unsigned char serialOutputChar; unsigned char registerWriteoneBitData(unsigned char oneBitData,unsigned char order){//写入8位数据,order为每位写入顺序,根据不同接线方法选择不同顺序 //char位定义从左至右为正序,编号为: 01234567 //位移寄存器输出引脚从A到H位定义为正序,信号从H后输出,编号为: QA QB QC QD QE QF QG QH - SOH char j; if(order==0){//正序顺时针编号顺序写入,写入数据结果 QA-0 QB-1 QC-2 QD-3 QE-4 QF-5 QG-6 QH-7,LED接线编号顺序如下: //0 1 2 //7 9 3 //6 5 4 for(j=7;j>=0;j--){ registerWriteonePinData(getCharBit(oneBitData,j)); } }else if(order==1){//逆序序顺时针编号顺序写入,写入数据结果 QA-7 QB-6 QC-5 QD-4 QE-3 QF-2 QG-1 QH-0,LED接线编号顺序如下: //0 1 2 //7 9 3 //6 5 4 for(j=0;j<8;j++){ registerWriteonePinData(getCharBit(oneBitData,j)); } }else if(order==2){//正序逆时针编号顺序写入,写入数据结果 QA-0 QB-1 QC-2 QD-3 QE-4 QF-5 QG-6 QH-7,LED接线编号顺序如下: //0 7 6 //1 9 5 //2 3 4 for(j=1;j<8;j++){ registerWriteonePinData(getCharBit(oneBitData,j)); } registerWriteonePinData(getCharBit(oneBitData,0)); }else if(order==3){//逆序逆时针编号顺序写入,写入数据结果 QA-7 QB-6 QC-5 QD-4 QE-3 QF-2 QG-1 QH-0,LED接线编号顺序如下: //0 7 6 //1 9 5 //2 3 4 for(j=6;j>=0;j--){ registerWriteonePinData(getCharBit(oneBitData,j)); } registerWriteonePinData(getCharBit(oneBitData,7)); } // return serialOutputChar; return 0; } void registerWriteSurface1(unsigned char cubeNumber,unsigned char surfaceNumber){//写入一个面的数据 unsigned char colorAndOrder0[2] = {0,0};//默认0号寄存器显示R,标准正序 unsigned char colorAndOrder1[2] = {1,0};//默认1号寄存器显示G,标准正序 unsigned char colorAndOrder2[2] = {2,0};//默认2号寄存器显示B,标准正序 unsigned char colorAndOrder3[2] = {3,0};//默认3号寄存器显示第9块RGB,标准正序 //定制PCB板驱动模式 colorAndOrder0[0] = 0; colorAndOrder1[0] = 1; colorAndOrder2[0] = 2; colorAndOrder3[0] = 3; colorAndOrder0[1] = 2; colorAndOrder1[1] = 2; colorAndOrder2[1] = 2; colorAndOrder3[1] = 0; if(cubeNumber==0){ //每个面4个移位寄存器 registerWriteoneBitData(cube[surfaceNumber][colorAndOrder0[0]],colorAndOrder0[1]); registerWriteoneBitData(cube[surfaceNumber][colorAndOrder1[0]],colorAndOrder1[1]); registerWriteoneBitData(cube[surfaceNumber][colorAndOrder2[0]],colorAndOrder2[1]); registerWriteoneBitData(cube[surfaceNumber][colorAndOrder3[0]],colorAndOrder3[1]); }else if(cubeNumber==1){ //每个面4个移位寄存器 registerWriteoneBitData(tempCube[surfaceNumber][colorAndOrder0[0]],colorAndOrder0[1]); registerWriteoneBitData(tempCube[surfaceNumber][colorAndOrder1[0]],colorAndOrder1[1]); registerWriteoneBitData(tempCube[surfaceNumber][colorAndOrder2[0]],colorAndOrder2[1]); registerWriteoneBitData(tempCube[surfaceNumber][colorAndOrder3[0]],colorAndOrder3[1]); }else{ return; } } ///输出数据到LED 2/ //接线方法:每个面4个寄存器,信号从3号寄存器输入,按序接入每一块的RGB,顺序如下 //0QH-0R 0QG-0G 0QF-0B 0QE-1R 0QD-1G 0QC-1B 0QB-2R 0QA-2G //1QH-2B 1QG-3R 1QF-3G 1QE-3B 1QD-4R 1QC-4G 1QB-4B 1QA-5R //2QH-5G 2QG-5B 2QF-6R 2QE-6G 2QD-6B 2QC-7R 2QB-7G 2QA-7B //3QH-8R 3QG-8G 3QF-8B 3QE- 3QD- 3QC- 3QB- 3QA- void registerWriteCube(unsigned char cubeNumber){//cubeNumber:0为cube,1为tempCube registerWriteSurface1(cubeNumber,5); registerWriteSurface1(cubeNumber,2); registerWriteSurface1(cubeNumber,3); registerWriteSurface1(cubeNumber,4); registerWriteSurface1(cubeNumber,1); registerWriteSurface1(cubeNumber,0); rushICOut(); } 初始化LED展示效果1 void initWriteCube1sub(char i,char j,unsigned char sd){ setTempSurfacePieceRGB(i,j,getSurfacePieceRGB(i,j)); registerWriteCube(1); delay_ms(sd); } 初始化LED展示效果2 void initWriteCube2(){ char i,j; unsigned char sd=10; i = 0; for(j=8;j>=0;j--){ initWriteCube1sub(i,j,sd); } for(i=4;i>0;i--){ for(j=2;j<5;j++){ initWriteCube1sub(i,j,sd); } } for(i=4;i>0;i--){ j=1; initWriteCube1sub(i,j,sd); j=8; initWriteCube1sub(i,j,sd); j=5; initWriteCube1sub(i,j,sd); } for(i=4;i>0;i--){ j=0; initWriteCube1sub(i,j,sd); j=7; initWriteCube1sub(i,j,sd); j=6; initWriteCube1sub(i,j,sd); } i = 5; for(j=0;j<9;j++){ initWriteCube1sub(i,j,sd); } } 面旋转函数 //调用此方法直接操作某一面旋转90度 typeRL=1 为顺时针,其它为逆时针 unsigned char delay = 80; void leftOrRightCubeSurfaceC52(unsigned char surfaceNumber, unsigned char typeRL) { aroundLeftOrRightStep(surfaceNumber, typeRL); registerWriteCube(0);// 刷新显示 delay_ms(delay);// 延迟 surfaceLeftOrRightStep(surfaceNumber, typeRL); registerWriteCube(0);// 刷新显示 delay_ms(delay);// 延迟 aroundLeftOrRightStep(surfaceNumber, typeRL); registerWriteCube(0);// 刷新显示 delay_ms(delay);// 延迟 surfaceLeftOrRightStep(surfaceNumber, typeRL); registerWriteCube(0);// 刷新显示 delay_ms(delay);// 延迟 aroundLeftOrRightStep(surfaceNumber, typeRL); registerWriteCube(0);// 刷新显示 //Send_Cube(cube); } /定时器初始化、定时中断开关函数// void timerInit0(){ AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //定时器T0运行在模式0 ,13位计数器 // GATE0=0; C/T0#=0; M1=0; M0=0; //软件模拟测试不论怎么调整都是9ms左右触发一次 //TL0 = 0xFF; //设置定时初始值//1微秒@11.0592MHz //TH0 = 0xFF; //设置定时初始值//1微秒@11.0592MHz //TL0 = 0x66; //设置定时初始值//500微秒@11.0592MHz //TH0 = 0xEA; //设置定时初始值//500微秒@11.0592MHz TL0 = 0x00; //设置定时初始值//5毫秒@11.0592MHz TH0 = 0x28; //设置定时初始值//5毫秒@11.0592MHz TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 } /层先法自动还原// //获取此块相邻面的坐标(0x[面编号][块编号]) //输入为角块时,返回以输入角块面为左上角,取此角块面上方相邻角块面的坐标 unsigned char getAdjacentBlock(unsigned char surfaceNumber,unsigned char index){ unsigned char surfaceNumberR=0,indexR=0,offset=0; if(index%2==0){ index=index+1; offset = 1; } switch (surfaceNumber) { case 0: indexR=3; surfaceNumberR = ((index+3)/2)/5+((index+3)/2)%5;//节省代码空间24位 break; case 1: if(index<4){//节省代码空间15位 surfaceNumberR = (index+1)%4; indexR=index+4; }else{ surfaceNumberR = 4+index/6; indexR=1+index%5; } break; case 2: indexR=1; switch (index) { case 1:surfaceNumberR=3;indexR=5;break; case 3:surfaceNumberR=0;break; case 5:surfaceNumberR=1;break; case 7:surfaceNumberR=5;break; } break; case 3: switch (index) { case 1:surfaceNumberR=4;indexR=5;break; case 3:surfaceNumberR=0;indexR=3;break; case 5:surfaceNumberR=2;indexR=1;break; case 7:surfaceNumberR=5;indexR=7;break; } break; case 4: indexR=5; switch (index) { case 1:surfaceNumberR=1;break; case 3:surfaceNumberR=0;break; case 5:surfaceNumberR=3;indexR=1;break; case 7:surfaceNumberR=5;break; }break; case 5: indexR=7; surfaceNumberR = ((13-index)%5+4)/2+(((13-index)%5+4)%2)*2-1;//节省代码空间12位 break; } return (surfaceNumberR<<4)|((indexR+offset)%8); } //查找某个棱块或角块的位置,返回RGB0所位于的面编号和块编号,返回8代表未找到 //RGB2大于7查找棱块,否则查找角块 unsigned char findVertexOrEdge(unsigned char RGB0,unsigned char RGB1,unsigned char RGB2){ //遍历所有块依次查找 unsigned char surfaceNumberR,indexR,si,si1; for(surfaceNumberR=0;surfaceNumberR<6;surfaceNumberR++){//遍历六个面 for(indexR=(RGB2>7);indexR<8;indexR+=2){//遍历角或棱 if(getSurfacePieceRGB(surfaceNumberR,indexR)==RGB0){//判断本面颜色 si = getAdjacentBlock(surfaceNumberR,indexR);//获取相邻面 if(getSurfacePieceRGB(si>>4&0x0f,si&0x0f)==RGB1){//判断相邻面颜色 if(indexR%2){//棱块 return (surfaceNumberR<<4)|indexR; }else{//角块 si1 = getAdjacentBlock(si>>4&0x0f,si&0x0f);//获取上相邻面颜色 if(getSurfacePieceRGB(si1>>4&0x0f,si1&0x0f)==RGB2) return (surfaceNumberR<<4)|indexR; } } } } } return 8; } //以number号棱块为上顶,获取其所在面某个方位的棱块面编号 L:左侧 R:右侧 U:正下方 //orientation输入错误时返回值等于输入值 //如下所示,若以7为顶,L=5 R=1 U=3 // 6 7 0 // 5 8 1 // 4 3 2 //以number号角块为左上顶,获取其所在面某个方位的角块面编号 R:右侧 U:正下方 O:右下侧、对角 //orientation输入错误时返回值等于输入值 //如下所示,若以6为顶,R=0 U=4 O=2 // 6 7 0 // 5 8 1 // 4 3 2 unsigned char getVertexOrEdgeNumber(unsigned char number,unsigned char orientation){ if(number%2){//棱 switch(orientation){ case 'L':number-=2;break; case 'R':number+=2;break; case 'U':number+=4;break; default:break; } }else{//角 switch(orientation){ case 'O':number+=4;break; case 'R':number+=2;break; case 'U':number-=2;break; default:break; } } return (number+8)%8; } //判断目标棱块面和当前棱块面相对位置:以某个面某棱块为顶,按照固定顺序依次查找,输出值后0~23,查找编号位置示意说明如下: //所述的左右下方向定义方法与getVertexOrEdgeNumber描述的LRU定义方法一致:如1-0R意为1位于0位所在面的右侧 //6位与7位相邻简写为:6|7 // 0-目标位位于当前位 1|0 2-0R 3|2 4-2R 5|4 6-4R 7|6 8-7L 9|8 10-9U 11|10 12-11U 13|12 14-13U 15|14 16-15R 17|16 18-17R 19|18 20-18R 21|20 22-20R 23|22 // // 9 S2 10 // 1 // 8 0 11 //16 S1 7|6 S0 2|3 S3 --- S5 // 15 4 12 // 5 // 14 S4 13 //找不到时返回24 unsigned char getEdgeRelativePosition(unsigned char surfaceNumber0,unsigned char index0,unsigned char surfaceNumber1,unsigned char index1){ unsigned char R = 0,i,siTemp; if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R; for(i=0;i<3;i++){ R++; siTemp = getAdjacentBlock(surfaceNumber0,index0); if(((siTemp>>4&0x0f)==surfaceNumber1)&&((siTemp&0x0f)==index1))return R;//判断相邻 R++; index0 = getVertexOrEdgeNumber(index0,'R'); if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R;//判断右侧 } R++; siTemp = getAdjacentBlock(surfaceNumber0,index0); surfaceNumber0 = siTemp>>4&0x0f; index0 = siTemp&0x0f; if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R;//判断相邻 R++; index0 = getVertexOrEdgeNumber(index0,'L'); if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R;//判断左侧 for(i=0;i<3;i++){ R++; siTemp = getAdjacentBlock(surfaceNumber0,index0); surfaceNumber0 = siTemp>>4&0x0f; index0 = siTemp&0x0f; if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R;//判断相邻 R++; index0 = getVertexOrEdgeNumber(index0,'U'); if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R;//判断下侧 } R++; siTemp = getAdjacentBlock(surfaceNumber0,index0); surfaceNumber0 = siTemp>>4&0x0f; index0 = siTemp&0x0f; if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R;//判断相邻 R++; index0 = getVertexOrEdgeNumber(index0,'R'); if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R;//判断右侧 R++; siTemp = getAdjacentBlock(surfaceNumber0,index0); surfaceNumber0 = siTemp>>4&0x0f; index0 = siTemp&0x0f; if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R;//判断相邻 for(i=0;i<3;i++){ R++; index0 = getVertexOrEdgeNumber(index0,'R'); if((surfaceNumber0==surfaceNumber1)&&(index0==index1))return R;//判断右侧 R++; siTemp = getAdjacentBlock(surfaceNumber0,index0); if(((siTemp>>4&0x0f)==surfaceNumber1)&&((siTemp&0x0f)==index1))return R;//判断相邻 } return 24; } //取对立面编号 unsigned char getOppositeNumber(unsigned char surfaceNumber){ unsigned char temp; // 取1号块相邻块a surfaceNumber = getAdjacentBlock(surfaceNumber,1); //取a块下方块b temp = getVertexOrEdgeNumber(surfaceNumber&0x0f,'U'); //输出b相邻块c所在面 return getAdjacentBlock(surfaceNumber>>4&0xf,temp)>>4&0xf; } //还原底面单个棱块(需要多次调用,调用一次只干一部分,然后需要更新目标块位置后再调用,直到输出为0) char restoreoneBottomEdge(unsigned char surfaceNumber0,unsigned char index0,unsigned char surfaceNumber1,unsigned char index1){ unsigned char temp,surfaceNumberTemp,typeRL; //获取目标棱块和当前棱块相对位置 temp = getEdgeRelativePosition(surfaceNumber0,index0,surfaceNumber1,index1); //位置正确 if(temp==0)return 0; //棱块处于本层 - 直接转到中层 if(temp>0&&temp<8){ if(surfaceNumber0==surfaceNumber1){//在本面,判断下相邻面,进行旋转 leftOrRightCubeSurfaceC52(getAdjacentBlock(surfaceNumber1,index1)>>4&0x0f,0); }else{ //在本层不在本面,可以直接转动目标所在面 leftOrRightCubeSurfaceC52(surfaceNumber1,0); } return 1; } //棱块处于底层 - 先对准位置再转到中层 if(temp>15&&temp<24){ if(temp==22||temp==23){//位置对 - 转动本块的相邻面 surfaceNumberTemp = getAdjacentBlock(surfaceNumber0,index0)>>4&0x0f; leftOrRightCubeSurfaceC52(surfaceNumberTemp,0); }else{ //获取顶面编号(对立面) surfaceNumberTemp = getOppositeNumber(surfaceNumber0); if(temp==20||temp==21){//右 顺时针 正转顶面 leftOrRightCubeSurfaceC52(surfaceNumberTemp,1); }else{//左或正后方 逆时针 反转顶面 leftOrRightCubeSurfaceC52(surfaceNumberTemp,0); } } return 1; } //棱块处于中层 //判断正反转 typeRL = temp%2; //获取转动面 surfaceNumberTemp = getAdjacentBlock(surfaceNumber1,index1)>>4&0x0f; //根据情况转动底面,对齐位置进行还原 if(temp==8||temp==11){//位置对,直接还原棱角 leftOrRightCubeSurfaceC52(surfaceNumberTemp,typeRL); return 0; } if(temp==10||temp==13){//右,正转一步对齐,还原棱角,再反转归位 leftOrRightCubeSurfaceC52(surfaceNumber0,1); leftOrRightCubeSurfaceC52(surfaceNumberTemp,typeRL); leftOrRightCubeSurfaceC52(surfaceNumber0,0); return 0; } if(temp==14||temp==9){//左,反转一步对齐,还原棱角,再正转归位 leftOrRightCubeSurfaceC52(surfaceNumber0,0); leftOrRightCubeSurfaceC52(surfaceNumberTemp,typeRL); leftOrRightCubeSurfaceC52(surfaceNumber0,1); return 0; } if(temp==15||temp==12){//后,正转两步对齐,还原棱角,再正转两部归位 leftOrRightCubeSurfaceC52(surfaceNumber0,1); leftOrRightCubeSurfaceC52(surfaceNumber0,1); leftOrRightCubeSurfaceC52(surfaceNumberTemp,typeRL); leftOrRightCubeSurfaceC52(surfaceNumber0,1); leftOrRightCubeSurfaceC52(surfaceNumber0,1); return 0; } return 0; } //还原底面棱块 输入底面编号 void restoreBottomEdge(unsigned char surfaceNumber){ //遍历所有棱块依次还原 unsigned char index,surfaceNumberR,indexR; unsigned char bottomRGB,tempRGB,temp; //获取底面中心块颜色 bottomRGB = getSurfacePieceRGB(surfaceNumber,8); for(index=1;index<8;index+=2){ //获取此棱块相邻面中心块颜色 tempRGB = getSurfacePieceRGB(getAdjacentBlock(surfaceNumber,index)>>4&0x0f,8); // 查找目标棱块位置 temp = findVertexOrEdge(bottomRGB,tempRGB,8); surfaceNumberR = temp>>4&0x0f; indexR = temp&0x0f; //还原底面单个棱块 while(restoreoneBottomEdge(surfaceNumber,index,surfaceNumberR,indexR)){ // 查找目标棱块位置 temp = findVertexOrEdge(bottomRGB,tempRGB,8); surfaceNumberR = temp>>4&0x0f; indexR = temp&0x0f; } } } //判断目标角块和当前角块的相对位置 unsigned char getVertexRelativePositionSub(unsigned char surfaceNumber0,unsigned char index0,unsigned char surfaceNumber1,unsigned char index1){ unsigned char R=0,i=0,siTemp=0,surfaceNumberTemp=0,indexTemp=0; //正面四个角 indexTemp = index0; surfaceNumberTemp = surfaceNumber0; for(i=0;i<4;i++){ if((surfaceNumberTemp==surfaceNumber1)&&(indexTemp==index1))return R;//本块 R++; //上相邻块 siTemp = getAdjacentBlock(surfaceNumberTemp,indexTemp); surfaceNumberTemp = siTemp>>4&0x0f; indexTemp = siTemp&0x0f; if((surfaceNumberTemp==surfaceNumber1)&&(indexTemp==index1))return R; R++; //左相邻块 siTemp = getAdjacentBlock(surfaceNumberTemp,indexTemp); surfaceNumberTemp = siTemp>>4&0x0f; indexTemp = siTemp&0x0f; if((surfaceNumberTemp==surfaceNumber1)&&(indexTemp==index1))return R; R++; index0 = getVertexOrEdgeNumber(index0,'R'); indexTemp = index0; surfaceNumberTemp = surfaceNumber0; } return 12; } unsigned char getVertexRelativePosition(unsigned char surfaceNumber0,unsigned char index0,unsigned char surfaceNumber1,unsigned char index1){ unsigned char temp0; //正面四个角判断 temp0 = getVertexRelativePositionSub(surfaceNumber0,index0,surfaceNumber1,index1); if(temp0==12){ //背面四个角判断 //取镜像对角编号,如0,0镜像对角为5,0,如0,2镜像对角为5,6 temp0 = getAdjacentBlock(surfaceNumber0,index0);//取上相邻临面 index0 = getVertexOrEdgeNumber(temp0&0x0f,'R'); //取右侧角 temp0 = getAdjacentBlock(temp0>>4&0x0f,index0);//取右侧角上相邻临面 index0 = getVertexOrEdgeNumber(temp0&0x0f,'U');//取右侧角上相邻临面下角 temp0 = getVertexRelativePositionSub(temp0>>4&0x0f,index0,surfaceNumber1,index1); return temp0+12; }else{ return temp0; } } //还原底面单个角块(需要多次调用,调用一次只干一部分,然后需要更新目标块位置后再调用,直到输出为0) char restoreoneBottomVertex(unsigned char surfaceNumber0,unsigned char index0,unsigned char surfaceNumber1,unsigned char index1){ unsigned char temp,surfaceNumberTemp,temp2,temp3,typeRL; //获取目标角块和当前角块相对位置 temp = getVertexRelativePosition(surfaceNumber0,index0,surfaceNumber1,index1); //位置正确 if(temp==0)return 0; surfaceNumberTemp = getOppositeNumber(surfaceNumber0);//对立面 //角块处于本层 - 将目标角块面转到第三层(顶层/对立层) if(temp>0&&temp<12){ if(surfaceNumber0==surfaceNumber1){//在本面,正转目标块的上相邻面,反转顶面(对立面),反转目标块的上相邻面 temp3 = getAdjacentBlock(surfaceNumber1,index1); temp2 = temp3>>4&0x0f;//目标块的上相邻面 leftOrRightCubeSurfaceC52(temp2,1); leftOrRightCubeSurfaceC52(surfaceNumberTemp,0); leftOrRightCubeSurfaceC52(temp2,0); }else{ //在本层不在本面,正/反转目标所在面,正/反转顶面(对立面),反/正转目标所在面, typeRL = temp%3%2; leftOrRightCubeSurfaceC52(surfaceNumber1,typeRL); leftOrRightCubeSurfaceC52(surfaceNumberTemp,typeRL); leftOrRightCubeSurfaceC52(surfaceNumber1,(typeRL+1)%2); } return 1; } //角块处于底层 if(temp>11&&temp<24){ temp3 = getAdjacentBlock(surfaceNumber0,index0); temp2 = temp3>>4&0x0f;//本块的上相邻面 //角块面在顶面上 - 将目标角块面转到第三层(顶层/对立层) if(temp%3==0){ if(temp==21){ //将目标角块面转到第三层 :正转本块上相邻面,正转顶面(对立面),反转本块上相邻面 leftOrRightCubeSurfaceC52(temp2,1); leftOrRightCubeSurfaceC52(surfaceNumberTemp,1); leftOrRightCubeSurfaceC52(temp2,0); } if(temp==12)leftOrRightCubeSurfaceC52(surfaceNumberTemp,0);//往21号位转动 else leftOrRightCubeSurfaceC52(surfaceNumberTemp,1);//往21号位转动 return 1; }else{//目标角块面在第三层 if(temp==14){//位于14位 - 还原:本块左相邻面反转,顶面正转,本块左相邻面正转 temp2 = getAdjacentBlock(temp2,temp3&0x0f)>>4&0x0f;//本块左相邻面 leftOrRightCubeSurfaceC52(temp2,0); leftOrRightCubeSurfaceC52(surfaceNumberTemp,1); leftOrRightCubeSurfaceC52(temp2,1); return 1; }else if(temp==19){//位于19位 - 还原:本块上相邻面正转,顶面反转,本块上相邻面反转 leftOrRightCubeSurfaceC52(temp2,1); leftOrRightCubeSurfaceC52(surfaceNumberTemp,0); leftOrRightCubeSurfaceC52(temp2,0); return 1; }else{ //13、16、22 转到19位 //17、20、23 转到14位 if(temp==22||temp==17){ leftOrRightCubeSurfaceC52(surfaceNumberTemp,0); }else{ leftOrRightCubeSurfaceC52(surfaceNumberTemp,1); } return 1; } } } return 0; } //还原底面角块 输入底面编号 void restoreBottomVertex(unsigned char surfaceNumber){ //遍历所有角块依次还原 unsigned char index,surfaceNumberR,indexR; unsigned char bottomRGB,tempRGB1,tempRGB2,temp; //获取底面中心块颜色 bottomRGB = getSurfacePieceRGB(surfaceNumber,8); for(index=0;index<8;index+=2){ //获取此角块相邻面中心块颜色 temp = getAdjacentBlock(surfaceNumber,index); tempRGB1 = getSurfacePieceRGB(temp>>4&0x0f,8); tempRGB2 = getSurfacePieceRGB(getAdjacentBlock(temp>>4&0x0f,temp&0x0f)>>4&0x0f,8); // 查找目标棱块位置 temp = findVertexOrEdge(bottomRGB,tempRGB1,tempRGB2); surfaceNumberR = temp>>4&0x0f; indexR = temp&0x0f; //还原底面单个棱块 while(restoreoneBottomVertex(surfaceNumber,index,surfaceNumberR,indexR)){ // 查找目标棱块位置 temp = findVertexOrEdge(bottomRGB,tempRGB1,tempRGB2); surfaceNumberR = temp>>4&0x0f; indexR = temp&0x0f; } } } //输入当前面,左面或右面(参数是左输入左面编号,反之输入右面编号),顶面,左右参数(左0,右1),执行还原第二层做棱块或右棱块的旋转 *** 作。在这之前需要将目标块放在对的位置上。 void restoreoneSecondEdgeSub(unsigned char surfaceNumber,unsigned char LRSurfaceNumber,unsigned char upwardSurfaceNumber,unsigned char LR){ unsigned char RL = (LR+1)%2; leftOrRightCubeSurfaceC52(LRSurfaceNumber,LR); leftOrRightCubeSurfaceC52(upwardSurfaceNumber,RL); leftOrRightCubeSurfaceC52(LRSurfaceNumber,RL); leftOrRightCubeSurfaceC52(upwardSurfaceNumber,RL); leftOrRightCubeSurfaceC52(surfaceNumber,RL); leftOrRightCubeSurfaceC52(upwardSurfaceNumber,LR); leftOrRightCubeSurfaceC52(surfaceNumber,LR); } //还原单个第二层棱块(需要多次调用,调用一次只干一部分,然后需要更新目标块位置后再调用,直到输出为0) unsigned char restoreoneSecondEdge(unsigned char surfaceNumber0,unsigned char index0,unsigned char surfaceNumber1,unsigned char index1){ //2,3 10,11 13,12 20,21 三层,顶面 目标块面在2 10 20要移至13位 目标块面在3 11 12 移至21位 在13位执行本块面移动函数(还原二层左棱块) 在21位执行本块面相邻临块面移动函数(还原二层右棱块) //4,5 右棱块 19,18 后棱块 22,23 对角棱块 (左,右) 需要先把目标目标块移出来 在4,19,22,执行目标块还原二层右棱块函数,在5,18,23目标块还原二层左棱块函数 tempCube[0][0] = getEdgeRelativePosition(surfaceNumber0,index0,surfaceNumber1,index1); //获取目标棱块和当前棱块相对位置 if(tempCube[0][0]==0)return 0; //获取顶面编号 tempCube[0][1] = getAdjacentBlock(surfaceNumber0,getVertexOrEdgeNumber(index0,'R'))>>4&0x0f; if(tempCube[0][0]==2||tempCube[0][0]==3||tempCube[0][0]==10||tempCube[0][0]==11||tempCube[0][0]==12||tempCube[0][0]==20){//在顶面上,移动到固定位置 if(tempCube[0][0]==2||tempCube[0][0]==12){//反转 leftOrRightCubeSurfaceC52(tempCube[0][1],0); }else{//正转 leftOrRightCubeSurfaceC52(tempCube[0][1],1); } }else{ tempCube[0][2] = getAdjacentBlock(surfaceNumber0,index0)>>4&0x0f;//本面相邻面 if(tempCube[0][0]==1||tempCube[0][0]==13){//在13位执行本块面还原二层左棱块函数 restoreoneSecondEdgeSub(surfaceNumber0,tempCube[0][2],tempCube[0][1],0); }else if (tempCube[0][0]==21){//在21位执行本块面相邻临块面还原二层右棱块函数 restoreoneSecondEdgeSub(tempCube[0][2],surfaceNumber0,tempCube[0][1],1); } else{ tempCube[0][2] = getAdjacentBlock(surfaceNumber1,index1)>>4&0x0f;//目标面相邻面 if(tempCube[0][0]==4||tempCube[0][0]==19||tempCube[0][0]==22){//4,19,22,执行目标块还原二层右棱块函数 restoreoneSecondEdgeSub(surfaceNumber1,tempCube[0][2],tempCube[0][1],1); }else if(tempCube[0][0]==5||tempCube[0][0]==18||tempCube[0][0]==23){//5,18,23目标块还原二层左棱块函数 restoreoneSecondEdgeSub(surfaceNumber1,tempCube[0][2],tempCube[0][1],0); }else{ return 0; //不再考虑情况范围内,处理不了,输出0退出 } } } return 1; } //还原第二层棱块 输入底面编号 void restoreSecondEdge(unsigned char surfaceNumber){ //遍历所有第二层棱块依次还原 unsigned char index,surfaceNumber0,index0,surfaceNumberR,indexR; unsigned char tempRGB1,tempRGB2,temp; for(index=1;index<8;index+=2){ //index = 5; //获取此棱块相邻块面坐标 temp = getAdjacentBlock(surfaceNumber,index); surfaceNumber0 = temp>>4&0x0f; //获取此棱块相邻面中心块颜色 tempRGB1 = getSurfacePieceRGB(surfaceNumber0,8); //获取此棱块相邻块面右侧棱块面坐标 index0 = getVertexOrEdgeNumber(temp&0x0f,'R'); //获取surfaceNumber0,index0相邻面中心块颜色 tempRGB2 = getSurfacePieceRGB(getAdjacentBlock(surfaceNumber0,index0)>>4&0x0f,8); // 查找目标棱块位置 temp = findVertexOrEdge(tempRGB1,tempRGB2,8); surfaceNumberR = temp>>4&0x0f; indexR = temp&0x0f; //还原底面单个棱块 while(restoreoneSecondEdge(surfaceNumber0,index0,surfaceNumberR,indexR)){ // 查找目标棱块位置 temp = findVertexOrEdge(tempRGB1,tempRGB2,8); surfaceNumberR = temp>>4&0x0f; indexR = temp&0x0f; } } } //还原顶面十字 输入底面编号 void restoreTopCrossShapedSub(unsigned char frontSurfaceNumber,unsigned char rightSurfaceNumber,unsigned char topSurfaceNumber){ leftOrRightCubeSurfaceC52(frontSurfaceNumber,1); leftOrRightCubeSurfaceC52(topSurfaceNumber,1); leftOrRightCubeSurfaceC52(rightSurfaceNumber,1); leftOrRightCubeSurfaceC52(topSurfaceNumber,0); leftOrRightCubeSurfaceC52(rightSurfaceNumber,0); leftOrRightCubeSurfaceC52(frontSurfaceNumber,0); } unsigned char restoreTopCrossShaped(unsigned char surfaceNumber){ unsigned char count=30; while(count--){ tempCube[0][2] = getOppositeNumber(surfaceNumber);//获取顶面编号 tempCube[0][3] = getSurfacePieceRGB(tempCube[0][2],8);//获取顶面颜色 //获取顶面四个相邻面编号 for(tempCube[0][1]=1;tempCube[0][1]<8;tempCube[0][1]+=2){ tempCube[5][(tempCube[0][1]-1)/2] = getAdjacentBlock(tempCube[0][2],tempCube[0][1])>>4&0x0f; } //获取四个棱块面颜色是否为目标色 for(tempCube[0][1]=1;tempCube[0][1]<8;tempCube[0][1]+=2){ tempCube[0][0] = ((tempCube[0][0]<<1)|(getSurfacePieceRGB(tempCube[0][2],tempCube[0][1])==tempCube[0][3]))&0x0f; } //SendoneByte(tempCube[0][0]); switch(tempCube[0][0]){ case 0://完全不对情况 restoreTopCrossShapedSub(tempCube[5][0],tempCube[5][3],tempCube[0][2]);break; case 3:case 6://角情况1 2 restoreTopCrossShapedSub(tempCube[5][2-tempCube[0][0]/3],tempCube[5][(5-tempCube[0][0]/3)%4],tempCube[0][2]);break; case 12:case 9://角情况3 4 restoreTopCrossShapedSub(tempCube[5][tempCube[0][0]/6+1],tempCube[5][tempCube[0][0]/6],tempCube[0][2]);break; case 5://线情况1 restoreTopCrossShapedSub(tempCube[5][2],tempCube[5][1],tempCube[0][2]);break; //case 13://线情况2 restoreTopCrossShapedSub(tempCube[5][tempCube[0][0]%12+1],tempCube[5][tempCube[0][0]%12],tempCube[0][2]);break; case 10://线情况3456 //test = tempCube[5][tempCube[0][0]%10]; restoreTopCrossShapedSub(tempCube[5][1],tempCube[5][0],tempCube[0][2]);break; default:return 0;//完成情况或意外情况 } //while(key2);//按一下继续 } return 1; } //还原顶面 void restoreTopSurfaceSub(unsigned char tempSurfaceNumber,unsigned char topSurfaceNumber,unsigned char typeLr){ leftOrRightCubeSurfaceC52(tempSurfaceNumber,typeLr); leftOrRightCubeSurfaceC52(topSurfaceNumber,typeLr); leftOrRightCubeSurfaceC52(tempSurfaceNumber,(typeLr+1)%2); leftOrRightCubeSurfaceC52(topSurfaceNumber,typeLr); leftOrRightCubeSurfaceC52(tempSurfaceNumber,typeLr); leftOrRightCubeSurfaceC52(topSurfaceNumber,typeLr); leftOrRightCubeSurfaceC52(topSurfaceNumber,typeLr); leftOrRightCubeSurfaceC52(tempSurfaceNumber,(typeLr+1)%2); } unsigned char restoreTopSurface(unsigned char surfaceNumber){ unsigned char count=30; unsigned char topSurfaceNumber = getOppositeNumber(surfaceNumber);//获取顶面编号 while(count--){ tempCube[0][3] = getSurfacePieceRGB(topSurfaceNumber,8);//获取顶面颜色 //获取顶面四个相邻面编号 for(tempCube[0][1]=1;tempCube[0][1]<8;tempCube[0][1]+=2){ tempCube[5][(tempCube[0][1]-1)/2] = getAdjacentBlock(topSurfaceNumber,tempCube[0][1])>>4&0x0f; } //获取4个角块的8个相邻面颜色是否为目标色 //获取本面4个角块面是否为目标色 for(tempCube[0][1]=0;tempCube[0][1]<8;tempCube[0][1]+=2){ tempCube[1][0]=((tempCube[1][0]<<1)|(getSurfacePieceRGB(topSurfaceNumber,tempCube[0][1])==tempCube[0][3]))&0x0f; surfaceNumber=getAdjacentBlock(topSurfaceNumber,tempCube[0][1]); tempCube[0][0] = tempCube[0][0]<<2|(getSurfacePieceRGB(surfaceNumber>>4,surfaceNumber&0xf)==tempCube[0][3]); surfaceNumber=getAdjacentBlock(surfaceNumber>>4,surfaceNumber&0xf); tempCube[0][0] = tempCube[0][0]|(getSurfacePieceRGB(surfaceNumber>>4,surfaceNumber&0xf)==tempCube[0][3])<<1; } //SendoneByte(tempCube[0][0]); switch(tempCube[0][0]){ case 0: if(tempCube[1][0]==0xf) return 0;//完成 else return 1; //拼错了 case 138://情况1 case 105:case 102:case 24:case 144:case 18://情况3 4 5 6 7 restoreTopSurfaceSub(tempCube[5][2],topSurfaceNumber,0);break; case 81://情况2 restoreTopSurfaceSub(tempCube[5][0],topSurfaceNumber,1);break; default:leftOrRightCubeSurfaceC52(topSurfaceNumber,1);break; } } return 1; } //还原顶面角块 void restoreTopVertexSub(unsigned char rightSurfaceNumber,unsigned char downSurfaceNumber,unsigned char upSurfaceNumber){ leftOrRightCubeSurfaceC52(rightSurfaceNumber,0); leftOrRightCubeSurfaceC52(rightSurfaceNumber,0); leftOrRightCubeSurfaceC52(downSurfaceNumber,1); leftOrRightCubeSurfaceC52(downSurfaceNumber,1); leftOrRightCubeSurfaceC52(rightSurfaceNumber,0); leftOrRightCubeSurfaceC52(upSurfaceNumber,0); leftOrRightCubeSurfaceC52(rightSurfaceNumber,1); leftOrRightCubeSurfaceC52(downSurfaceNumber,0); leftOrRightCubeSurfaceC52(downSurfaceNumber,0); leftOrRightCubeSurfaceC52(rightSurfaceNumber,0); leftOrRightCubeSurfaceC52(upSurfaceNumber,1); leftOrRightCubeSurfaceC52(rightSurfaceNumber,0); } unsigned char restoreTopVertex(unsigned char surfaceNumber){ unsigned char count=30; unsigned char topSurfaceNumber = getOppositeNumber(surfaceNumber);//获取顶面编号 while(count--){ //while(key1); tempCube[0][3] = getSurfacePieceRGB(topSurfaceNumber,8);//获取顶面颜色 tempCube[0][2] = 0; tempCube[1][1] = 0; tempCube[1][2] = 0; //获取4个角块的8个相邻面颜色状况 for(tempCube[0][1]=0;tempCube[0][1]<8;tempCube[0][1]+=2){ surfaceNumber=getAdjacentBlock(topSurfaceNumber,tempCube[0][1]);//获取角块上相邻角块面坐标 tempCube[5][tempCube[0][1]/2] = surfaceNumber>>4; //获取顶面四个相邻面编号 tempCube[0][0] = getSurfacePieceRGB(surfaceNumber>>4,surfaceNumber&0xf); //获取角块上相邻角块面颜色 tempCube[1][0] = getSurfacePieceRGB(surfaceNumber>>4,getVertexOrEdgeNumber(surfaceNumber&0xf,'U'));//获取角块上相邻角块下方角块面颜色 tempCube[2][0] = getSurfacePieceRGB(surfaceNumber>>4,8);//获取上相邻颜色 if(tempCube[0][0]==tempCube[1][0]){ if(tempCube[0][0]==tempCube[2][0]){//两个颜色对 tempCube[3][tempCube[0][1]/2] = 2; tempCube[0][2]++; }else{ //两个颜色一致但位置不对 tempCube[3][tempCube[0][1]/2] = 3; tempCube[1][1]++; } }else{ if(tempCube[0][0]==tempCube[2][0]){//第一个颜色对 tempCube[3][tempCube[0][1]/2] = 1; tempCube[1][2]++; }else{//其它情况 tempCube[3][tempCube[0][1]/2] = 0; } } } if(tempCube[0][2]==4)return 0;//完成 if(tempCube[0][2]>0){//有两个颜色都对的面 for(tempCube[0][1]=0;tempCube[0][1]<4;tempCube[0][1]++){//找到面编号,执行公式 if(tempCube[3][tempCube[0][1]]==2)break; } }else if(tempCube[1][1]>0||tempCube[1][2]==0){//有 两个颜色一致但位置不对的面 或 位置全不对 leftOrRightCubeSurfaceC52(topSurfaceNumber,0);continue; }else{//没有两个颜色对的面,随便找一个有一个颜色对的位置执行公式 for(tempCube[0][1]=0;tempCube[0][1]<4;tempCube[0][1]++){ if(tempCube[3][tempCube[0][1]]==1)break; } } restoreTopVertexSub(tempCube[5][tempCube[0][1]],tempCube[5][(tempCube[0][1]+1)%4],tempCube[5][(tempCube[0][1]+3)%4]); } return 1; } //还原顶面棱块 unsigned char restoreTopEdge(unsigned char surfaceNumber){ unsigned char count=30; while(count--){ tempCube[0][2] = getOppositeNumber(surfaceNumber);//获取顶面编号 tempCube[0][3] = getSurfacePieceRGB(tempCube[0][2],8);//获取顶面颜色 //获取顶面四个相邻面编号 for(tempCube[0][1]=1;tempCube[0][1]<8;tempCube[0][1]+=2){ tempCube[5][(tempCube[0][1]-1)/2] = getAdjacentBlock(tempCube[0][2],tempCube[0][1])>>4&0x0f; } tempCube[1][1] = 0; tempCube[1][2] = 0; //获取4个棱块的4个相邻面位置状况 tempCube[0][0] = getSurfacePieceRGB(tempCube[0][2],8);//顶面颜色 for(tempCube[0][1]=1;tempCube[0][1]<8;tempCube[0][1]+=2){ tempCube[1][0] = getSurfacePieceRGB(tempCube[5][(tempCube[0][1]-1)/2],8); //相邻面颜色 tempCube[3][(tempCube[0][1]-1)/2] = findVertexOrEdge(tempCube[0][0],tempCube[1][0],8);//位置信息 //相对位置 tempCube[3][(tempCube[0][1]-1)/2] = getEdgeRelativePosition(tempCube[0][2],tempCube[0][1],tempCube[3][(tempCube[0][1]-1)/2]>>4,tempCube[3][(tempCube[0][1]-1)/2]&0xf); if(tempCube[3][(tempCube[0][1]-1)/2]==0) tempCube[1][2]++;//位置对的数量 } if(tempCube[1][2]==4)return 0;//完成 if(tempCube[3][0]>7||tempCube[3][1]>7||tempCube[3][2]>7||tempCube[3][3]>7)return 1;//拼错了 if(tempCube[1][2]==1){//有1个棱块对 for(tempCube[0][1]=0;tempCube[0][1]<4;tempCube[0][1]++){//找到哪个对 if(tempCube[3][tempCube[0][1]]==0){ //判断此块下方块位置情况 if(tempCube[3][getVertexOrEdgeNumber(tempCube[0][1]*2+1,'U')/2]==6){//情况1 stateR = 1; restoreTopSurfaceSub(tempCube[5][(tempCube[0][1]+1)%4],tempCube[0][2],1); //leftOrRightCubeSurfaceC52(tempCube[0][2],1); //restoreTopSurfaceSub(tempCube[5][(tempCube[0][1]+3)%4],tempCube[0][2],0); restoreTopSurface(surfaceNumber); stateR = 0; }else{//情况2 stateB = 1; restoreTopSurfaceSub(tempCube[5][(tempCube[0][1]+3)%4],tempCube[0][2],0); //leftOrRightCubeSurfaceC52(tempCube[0][2],0); //restoreTopSurfaceSub(tempCube[5][(tempCube[0][1]+1)%4],tempCube[0][2],1); restoreTopSurface(surfaceNumber); stateB = 0; } } } }else { if(tempCube[3][0]==tempCube[3][1]&&tempCube[3][0]==tempCube[3][2]&&tempCube[3][0]==tempCube[3][3]){//转顶面归位 leftOrRightCubeSurfaceC52(tempCube[0][2],tempCube[3][0]!=2); //restoreTopVertex(surfaceNumber); }else {//全不对 情况3 //delay=40; if(tempCube[3][0]==6) restoreTopSurfaceSub(tempCube[5][0],tempCube[0][2],0); else //if(tempCube[3][1]==6) restoreTopSurfaceSub(tempCube[5][1],tempCube[0][2],0); restoreTopVertex(surfaceNumber); //while(key2); } } } return 1; } //层先法还原,输入以哪个面为底面开始还原魔方 void restore(unsigned char surfaceNumber){ stateR = 0; stateB = 0; restoreBottomEdge(surfaceNumber); restoreBottomVertex(surfaceNumber); restoreSecondEdge(surfaceNumber); if(restoreTopCrossShaped(surfaceNumber)==0){ if(restoreTopSurface(surfaceNumber)==0){ if(restoreTopVertex(surfaceNumber)==0){ restoreTopEdge(surfaceNumber); }else stateR = 1; }else stateB = 1; }else { stateR = 1; stateB = 1; } } /打乱魔方// void disorganizeCube(){ unsigned char surfaceNumber; unsigned char i; srand((unsigned)TL0); for(i=0;i<6;i++){ surfaceNumber = rand()%6; leftOrRightCubeSurfaceC52(surfaceNumber,0); } for(i=0;i<6;i++){ surfaceNumber = rand()%6; leftOrRightCubeSurfaceC52(surfaceNumber,1); } } unsigned short min(unsigned short a,unsigned short b){if(a>b)return b;else return a;} /主函数/// void main() //主函数 { unsigned char scale = 25,dw=100,tt=0;//1~10,控制LED亮度 unsigned short inputData,tempValue; //unsigned char modeNumber; unsigned char newCube,i,j,n; //char i,j; timerInit0(); // UartInit(); //引脚状态初始化 P1=0x3f; delay=20; //delay=0; begin: clearICData(); closeICOut();//关闭LED输出 if(modeBit1==1&&modeBit2==1){//-----------------------------11模式:魔方 按键打乱或还原魔方,编码器旋转面 newCube = 1; input8=0xff; input4=0xff; //TurnonTimerInterrupt();//开启定时器中断,调节亮度(不要用,频闪严重,伤眼) opernICOut();//开启LED输出(开启亮度调节时无需开启输出) initWriteCube2();//初始化展示效果 //registerWriteCube(1);//显示魔方 while(modeBit1==1&&modeBit2==1){ //inputData = detectInputSwitchVersion(); inputData = detectInputCoderVersion(1); if(inputData!=0){ leftOrRightCubeSurfaceC52(inputData&0xff,inputData>>8); newCube = 0; } if(key1==0&&newCube)disorganizeCube(); if(key2==0)restore(5); } //TurnOffTimerInterrupt();//退出魔方模式时定时器中断 goto begin; } if(modeBit1==1&&modeBit2==0){//-----------------------------10模式:照明:编码器微调亮度,按键调节亮度档位,按住按键旋转编码器调颜色 //stateB=1; opernICOut();//开启LED输出 //TurnonTimerInterrupt(); for(i=0;i<9;i++){ for(j=0;j<6;j++){ setTempSurfacePieceRGB(j,i,7); } } tempValue = 0; newCube = 1;//代表是否有刷新任务,有任务每次再进去处理,无任务跳过,提高频闪频率 i=0; j=255; //registerWriteCube(1);while(1); while(modeBit1==1&&modeBit2==0){ //tt用来保存当前时间在一秒中的比例位置 tt++; //每1微秒增加1 if(tt==dw){ //10微妙的时钟周期 tt=0; //使tt=0,开始新的PWM周期 opernICOut(); //使LED灯亮 }else if(scale0&&tempValue<0x200))&&getTempSurfacePieceRGB(0,0)==0){//熄灯状态碰任意操作开灯,方便黑灯瞎火时操作 setTempSurfacePieceRGB(0,0,7); j=1; newCube=1; continue; } if(tempValue>0){ if(tempValue==0x3fd){ if(key1==0&&key2==1) scale=min(scale+dw/6,dw);//加6分之一档,此公式保证最大值不会大于dw else if(key1==1&&key2==0) scale=scale-min(scale,dw/6);//减6分之一档,此公式保证最小值不会小于0 else{//熄灯 setTempSurfacePieceRGB(0,0,0); j=1; newCube=1; } } } if(inputData!=0){ if(tempValue==0x3fe){//调色 newCube=1; j=getTempSurfacePieceRGB(0,0); if(inputData>>8==1) setTempSurfacePieceRGB(0,0,min((j+1),7)); else setTempSurfacePieceRGB(0,0,j-min((j-1),1)); j=1; }else if((inputData>>8==1)&&scale >8!=1)&&scale>0)//亮度- scale--; } } //TurnOffTimerInterrupt(); goto begin; } if(modeBit1==0&&modeBit2==1){//-----------------------------01模式:728色变换 按键切换模式 //tempValue = 200; opernICOut();//开启LED输出 setTempAllSurfaceRGBLuminance('B',9); //registerWriteCube(1); newCube=5; tempValue = 728; i=0;n=0; while(modeBit1==0&&modeBit2==1){ if(newCube>0&&newCube<5){ inputData=60*newCube; setTempAllSurfaceRGBLuminance('R',tempValue/81); setTempAllSurfaceRGBLuminance('G',(tempValue%81)/9); setTempAllSurfaceRGBLuminance('B',tempValue%9); registerWriteCube(1); if(tempValue==0){ tempValue=729; } tempValue--; } if(newCube>4&&newCube<9){ inputData=100*(newCube-4); if(i++==10){ i=1; n=(n+1)%3; } if(n==0){//B-R setTempAllSurfaceRGBLuminance('B',10-i); setTempAllSurfaceRGBLuminance('R',i-1); registerWriteCube(1); } if(n==1){//R-G setTempAllSurfaceRGBLuminance('R',10-i); setTempAllSurfaceRGBLuminance('G',i-1); registerWriteCube(1); } if(n==2){//G-B setTempAllSurfaceRGBLuminance('G',10-i); setTempAllSurfaceRGBLuminance('B',i-1); registerWriteCube(1); } } if(key1==0){ newCube=(newCube+1)%8+1; while(key1==0); } if(key2==0){ newCube=(newCube+6)%8+1; while(key2==0); } delay_ms(inputData); } goto begin; } if(modeBit1==0&&modeBit2==0){//-----------------------------00模式:关闭输出,用开发板电源输出口充电时开发板必须处于开机状态,可使用此模式。 while(modeBit1==0&&modeBit2==0); goto begin; } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)