STC89C52实现电子魔方,带一键还原

STC89C52实现电子魔方,带一键还原,第1张

STC89C52实现电子魔方,带一键还原

参考资料:

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;i1;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;
	}
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5713776.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存