STC89C52实现电子魔方,带一键还原(层先法)

参考资料:

74hc138中文资料详细(74hc138引脚图及功能表_封装真值表及应用电路图) - 全文 - 电子发烧友网

三阶魔方还原图文教程-番茄魔方

电器原理图:

代码:

#include "STC8952.h" 
#include<stdlib.h>
//#include<algorithm.h>  
//#include<math.h>
//#include<74HC595.c> 

/*#include "reg52.h" 
#include <intrins.h>
#include <stdio.h>
#include <string.h>*/


#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;



/*
一个魔方面有9块,每块编号如下:
	0 1 2
	7 8 3
	6 5 4
每块的RGB三色数据对应如下:
	0到7块的R:cube[surfaceNumber][0];
	0到7块的G:cube[surfaceNumber][1];
	0到7块的B:cube[surfaceNumber][2];
	第8块的RGB三色:cube[surfaceNumber][3];


魔方各个面拼接说明(六个面编码为S0到S5,S0与S5为对面):

S0面与其衔接面编号说明:
   S2
S1 S0 S3 --- S5		
   S4

S0面与其衔接面块顺序说明(以S0为中心,六个面拆开后示意):
    		6 7 0
    		5 8 1
    		4 3 2
				
0 1 2		0 1 2		4 5 6         0 1 2
7 8 3		7 8 3		3 8 7   ---   7 8 3 
6 5 4		6 5 4		2 1 0         6 5 4

    		2 3 4
    		1 8 5
    		0 7 6
				
S5面与其衔接面编号说明:
   S2
S3 S5 S1 --- S0				
   S4

S5面与其衔接面块顺序说明(以S5为中心,六个面拆开后示意):
    		2 3 4
    		1 8 5
    		0 7 6
				
4 5 6		0 1 2		0 1 2         0 1 2
3 8 7		7 8 3		7 8 3   ---   7 8 3 
2 1 0		6 5 4		6 5 4         6 5 4

    		6 7 0
    		5 8 1
    		4 3 2

*/
/*
unsigned char cube[6][3] ={
{0b11111111, 0b00000000, 0b00000000,0b100},
{0b00000000, 0b11111111, 0b00000000,0b010},
{0b00000000, 0b00000000, 0b11111111,0b001},
{0b11111111, 0b11111111, 0b00000000,0b110},
{0b11111111, 0b00000000, 0b11111111,0b101},
{0b00000000, 0b11111111, 0b11111111,0b011}}; 
*/

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 inpSR;
void RSINTR() interrupt 4 using 2
{
	EA=0;
	if(TI) //发送中断	  
	{
		TI=0;
	}

	if(RI)	 //接收中断		  
	{	
		RI=0;//手动清寄存器
		//inpSR=SBUF;		
		//SendString(&inpSR);
		//leftOrRightCubeSurfaceC52((inpSR&0xf0)>>4,inpSR&&0x0f);
		//Send_Cube(cube);
	}
	EA=1;
}
/串口初始化///
void UartInit(void)
{
	//串口初始化 
	TMOD = 0x20;	  //定时器工作方式,选择了定时器1,工作方式2 八位初值自动重装的8位定时器。	
	SCON = 0x50;	  //工作方式1,,允许接收   
	PCON = 0x10;
	TH1 = 253;       //定时器1初值	,设置波特率为9600 晶振11.0529MHZ
	TL1 = 253;
	TR1 = 1;        //开启定时器1
	ES = 1;         //打开接收中断//允许串口中断
	EA = 1;         //允许中断(总闸)  
	TI = 0;
	RI = 0;
}


void SendOneByte(unsigned char DAT)//发送字节
{
	ES = 0;
	TI=0;
	SBUF = DAT;//赋值给SBUF启动发送
	while(TI==0);//等待发送完成
	TI=0;//清零发送完成标志位
	ES = 1;
}*/

/*
void SendString(unsigned char *c)//发送字符串
{
	while(*c != '\0')//如果p的内容不等于0
	{
		SendOneByte(*c++);//从串口发送一字节数据,并且p的地址自增1
	}	
}

void Send_Cube(unsigned char cubeDAT[6][4])
{
	char j,i; 
	//delay_ms(1);
	for(j=0;j<6;j++){ 
		for(i=0;i<4;i++){
			SendOneByte(cubeDAT[j][i]);
			//delay_ms(2);
		} 
	}
}*/




/* 获取char第N位的值 */
//高位为0,低位为7
unsigned char getCharBit(char cr,unsigned char index){  
	return (cr&(0x80>>index))>0;
}
/* 获取第surfaceNumber个面第index块的RGB值,放在后3位*/
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);
}
/* 获取第surfaceNumber个面第index块的RGB值,放在后3位*/
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);
}

/* 设置char第N位的值 */
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));
	} 
}
/* 设置第surfaceNumber个面第index块的RGB值*/
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 setSurfacePieceRGB(unsigned char (*inputCube)[4],unsigned char surfaceNumber,unsigned char index,unsigned char rgb){  
		if(index==8){
			inputCube[surfaceNumber][3] =  7&rgb;
			return;
		} 
		setCharBit(&inputCube[surfaceNumber][0],index,rgb&4);
		setCharBit(&inputCube[surfaceNumber][1],index,rgb&2);
		setCharBit(&inputCube[surfaceNumber][2],index,rgb&1); 
}*/
/*void setSurfacePieceRGB(unsigned char *inputCubeSurface,unsigned char index,unsigned char rgb){  
		if(index==8){
			inputCubeSurface[3] =  7&rgb;
			return;
		} 
		setCharBit(&inputCubeSurface[0],index,rgb&4);
		setCharBit(&inputCubeSurface[1],index,rgb&2);
		setCharBit(&inputCubeSurface[2],index,rgb&1); 
}*/

/* 设置第surfaceNumber个面第index块的RGB值(操作tempCube)*/
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;
	/*if(rgb>9)return;
	for(i=0;i<rgb&&i<8;i++){
		d=(d<<1)|0x01;
	}
	if(rgb==9)i=1;else i=0;
	switch (rgbType) {
	case 'R':
		tempCube[surfaceNumber][0] = d;
		setCharBit(&tempCube[surfaceNumber][3],5,i); 
		break;
	case 'G':
		tempCube[surfaceNumber][1] = d;
		setCharBit(&tempCube[surfaceNumber][3],6,i); 
		break;
	case 'B':
		tempCube[surfaceNumber][2] = d;
		setCharBit(&tempCube[surfaceNumber][3],7,i); 
		break;
	}*/
	for(i=0;i<rgb;i++){
		d=(d<<1)|0x01;
	}
	//if(rgb==9)i=1;else i=0;
	/*switch (rgbType) {
	case 'R':i=5;break;
	case 'G':i=6;break;
	case 'B':i=7;break;
	}*///if比switch省代码空间
	if(rgbType=='R')i=5;
	else if (rgbType=='G')i=6;
	else i=7;
	tempCube[surfaceNumber][i%5] = d;//根据rgbType设置对应的RGB值
	setCharBit(&tempCube[surfaceNumber][3],i,rgb/9); //设置8号灯RGB,慢亮度时候才亮,否则灭 
}
// 设置所有面的RGB值(1~9)
void setTempAllSurfaceRGBLuminance(char rgbType,unsigned char rgb){ 
	unsigned char i;
	for(i=0;i<6;i++){
		setTempSurfaceRGBLuminance(i,rgbType,rgb);
	}
} 

//某一个面四周相邻的4个面的12个格子旋转移动一位,移动三位为 90度。  typeRL=1 为顺时针,其它为逆时针
void aroundLeftOrRightStep(unsigned char surfaceNumber,unsigned char typeRL) { 
	unsigned char temp = 0;
	unsigned char i;    
	//20220118 新版,节省很多代码空间
	if (surfaceNumber==0){ //s0面转动 
		//  s0相邻面正序LED顺序:s1-4,s1-3,s1-2,	s2-4,s2-3,s2-2,	s3-4,s3-3,s3-2,	s4-4,s4-3,s4-2  
		tempCube[0][0]=1;tempCube[0][1]=4;tempCube[0][2]=4;tempCube[0][3]=4;tempCube[1][0]=3;tempCube[1][1]=3;tempCube[1][2]=3;tempCube[1][3]=2;tempCube[2][0]=2;tempCube[2][1]=2;tempCube[2][2]=1;tempCube[2][3]=1;
		tempCube[3][0]=4;tempCube[3][1]=2;tempCube[3][2]=3;tempCube[3][3]=4;tempCube[4][0]=2;tempCube[4][1]=3;tempCube[4][2]=4;tempCube[4][3]=2;tempCube[5][0]=3;tempCube[5][1]=4;tempCube[5][2]=2;tempCube[5][3]=3;	
	}else if (surfaceNumber==1){ //s1面转动 																									  
		//  s1相邻面正序LED顺序:s5-4,s5-3,s5-2,	s2-6,s2-5,s2-4,	s0-0,s0-7,s0-6,	s4-2,s4-1,s4-0  
		tempCube[0][0]=5;tempCube[0][1]=4;tempCube[0][2]=4;tempCube[0][3]=4;tempCube[1][0]=0;tempCube[1][1]=0;tempCube[1][2]=0;tempCube[1][3]=2;tempCube[2][0]=2;tempCube[2][1]=2;tempCube[2][2]=5;tempCube[2][3]=5;
		tempCube[3][0]=4;tempCube[3][1]=0;tempCube[3][2]=1;tempCube[3][3]=2;tempCube[4][0]=6;tempCube[4][1]=7;tempCube[4][2]=0;tempCube[4][3]=4;tempCube[5][0]=5;tempCube[5][1]=6;tempCube[5][2]=2;tempCube[5][3]=3; 																						  
	}else if (surfaceNumber==2){ 	//s0面转动 																	  
		//  s2相邻面正序LED顺序:s5-2,s5-1,s5-0,	s3-6,s3-5,s3-4,	s0-2,s0-1,s0-0,	s1-2,s1-1,s1-0  
		tempCube[0][0]=5;tempCube[0][1]=1;tempCube[0][2]=1;tempCube[0][3]=1;tempCube[1][0]=0;tempCube[1][1]=0;tempCube[1][2]=0;tempCube[1][3]=3;tempCube[2][0]=3;tempCube[2][1]=3;tempCube[2][2]=5;tempCube[2][3]=5;
		tempCube[3][0]=2;tempCube[3][1]=0;tempCube[3][2]=1;tempCube[3][3]=2;tempCube[4][0]=0;tempCube[4][1]=1;tempCube[4][2]=2;tempCube[4][3]=4;tempCube[5][0]=5;tempCube[5][1]=6;tempCube[5][2]=0;tempCube[5][3]=1;																						  
	}else if (surfaceNumber==3){ 	//s3面转动 																					  
		//  s3相邻面正序LED顺序:s5-0,s5-7,s5-6,	s4-6,s4-5,s4-4,	s0-4,s0-3,s0-2,	s2-2,s2-1,s2-0  
		tempCube[0][0]=5;tempCube[0][1]=2;tempCube[0][2]=2;tempCube[0][3]=2;tempCube[1][0]=0;tempCube[1][1]=0;tempCube[1][2]=0;tempCube[1][3]=4;tempCube[2][0]=4;tempCube[2][1]=4;tempCube[2][2]=5;tempCube[2][3]=5;
		tempCube[3][0]=0;tempCube[3][1]=0;tempCube[3][2]=1;tempCube[3][3]=2;tempCube[4][0]=2;tempCube[4][1]=3;tempCube[4][2]=4;tempCube[4][3]=4;tempCube[5][0]=5;tempCube[5][1]=6;tempCube[5][2]=6;tempCube[5][3]=7; 
	}else if (surfaceNumber==4){//s4面转动  
		//  s4相邻面正序LED顺序:s5-6,s5-5,s5-4,	s1-6,s1-5,s1-4,	s0-6,s0-5,s0-4,	 s3-2,s3-1,s3-0  
		tempCube[0][0]=5;tempCube[0][1]=3;tempCube[0][2]=3;tempCube[0][3]=3;tempCube[1][0]=0;tempCube[1][1]=0;tempCube[1][2]=0;tempCube[1][3]=1;tempCube[2][0]=1;tempCube[2][1]=1;tempCube[2][2]=5;tempCube[2][3]=5;
		tempCube[3][0]=6;tempCube[3][1]=0;tempCube[3][2]=1;tempCube[3][3]=2;tempCube[4][0]=4;tempCube[4][1]=5;tempCube[4][2]=6;tempCube[4][3]=4;tempCube[5][0]=5;tempCube[5][1]=6;tempCube[5][2]=4;tempCube[5][3]=5;
	}else{ //s5面转动 
		//  s5相邻面正序LED顺序:s4-0,s4-7,s4-6,	s3-0,s3-7,s3-6,	s2-0,s2-7,s2-6,	s1-0,s1-7,s1-6
		tempCube[0][0]=4;tempCube[0][1]=1;tempCube[0][2]=1;tempCube[0][3]=1;tempCube[1][0]=2;tempCube[1][1]=2;tempCube[1][2]=2;tempCube[1][3]=3;tempCube[2][0]=3;tempCube[2][1]=3;tempCube[2][2]=4;tempCube[2][3]=4;
		tempCube[3][0]=0;tempCube[3][1]=6;tempCube[3][2]=7;tempCube[3][3]=0;tempCube[4][0]=6;tempCube[4][1]=7;tempCube[4][2]=0;tempCube[4][3]=6;tempCube[5][0]=7;tempCube[5][1]=0;tempCube[5][2]=6;tempCube[5][3]=7;
	}
	temp = getSurfacePieceRGB(tempCube[0][0],tempCube[3][0]);  //备份 
	if(typeRL == 1){ 			// 正转(顺时针)
		for(i=0;i<11;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[2][3],tempCube[5][3],temp);																  
	}else{	//反转			
		setSurfacePieceRGB(tempCube[0][0],tempCube[3][0],getSurfacePieceRGB(tempCube[2][3],tempCube[5][3]));				  
		for(i=11;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);																 
	}
 /*
	switch (surfaceNumber) {
	case 0: //s0面转动 
		//  s0相邻面正序LED顺序:s1-4,s1-3,s1-2,   s2-4,s2-3,s2-2,   s3-4,s3-3,s3-2,   s4-4,s4-3,s4-2  
		temp = getSurfacePieceRGB(1,4);  //备份s1-4                                           
		if(typeRL == 1){ 			// 正转(顺时针)
	     setSurfacePieceRGB(1,4,getSurfacePieceRGB(4,2));                                            
	     setSurfacePieceRGB(4,2,getSurfacePieceRGB(4,3));                                            
	     setSurfacePieceRGB(4,3,getSurfacePieceRGB(4,4));                                            
	     setSurfacePieceRGB(4,4,getSurfacePieceRGB(3,2));                                            
	     setSurfacePieceRGB(3,2,getSurfacePieceRGB(3,3));                                            
	     setSurfacePieceRGB(3,3,getSurfacePieceRGB(3,4));                                            
	     setSurfacePieceRGB(3,4,getSurfacePieceRGB(2,2));                                            
	     setSurfacePieceRGB(2,2,getSurfacePieceRGB(2,3));                                            
	     setSurfacePieceRGB(2,3,getSurfacePieceRGB(2,4));                                            
	     setSurfacePieceRGB(2,4,getSurfacePieceRGB(1,2));                                            
	     setSurfacePieceRGB(1,2,getSurfacePieceRGB(1,3));                                          
	     setSurfacePieceRGB(1,3,temp);                                                       
		}else{	//反转			                                                           
	     setSurfacePieceRGB(1,4,getSurfacePieceRGB(1,3));                                            
	     setSurfacePieceRGB(1,3,getSurfacePieceRGB(1,2));                                            
	     setSurfacePieceRGB(1,2,getSurfacePieceRGB(2,4));                                            
	     setSurfacePieceRGB(2,4,getSurfacePieceRGB(2,3));                                            
	     setSurfacePieceRGB(2,3,getSurfacePieceRGB(2,2));                                            
	     setSurfacePieceRGB(2,2,getSurfacePieceRGB(3,4));                                            
	     setSurfacePieceRGB(3,4,getSurfacePieceRGB(3,3));                                            
	     setSurfacePieceRGB(3,3,getSurfacePieceRGB(3,2));                                            
	     setSurfacePieceRGB(3,2,getSurfacePieceRGB(4,4));                                            
	     setSurfacePieceRGB(4,4,getSurfacePieceRGB(4,3));                                            
	     setSurfacePieceRGB(4,3,getSurfacePieceRGB(4,2));                                            
	     setSurfacePieceRGB(4,2,temp);                                                       
		}                                                                             
		break;                                                                        
	case 1:			                                                                    
		//  s1相邻面正序LED顺序:s5-4,s5-3,s5-2,   s2-6,s2-5,s2-4,   s0-0,s0-7,s0-6,   s4-2,s4-1,s4-0  
		temp = getSurfacePieceRGB(5,4);  //备份s5-4                                           
		if(typeRL == 1){ 			// 正转(顺时针)                                        
	     setSurfacePieceRGB(5,4,getSurfacePieceRGB(4,0));                                            
	     setSurfacePieceRGB(4,0,getSurfacePieceRGB(4,1));                                            
	     setSurfacePieceRGB(4,1,getSurfacePieceRGB(4,2));                                            
	     setSurfacePieceRGB(4,2,getSurfacePieceRGB(0,6));                                            
	     setSurfacePieceRGB(0,6,getSurfacePieceRGB(0,7));                                            
	     setSurfacePieceRGB(0,7,getSurfacePieceRGB(0,0));                                            
	     setSurfacePieceRGB(0,0,getSurfacePieceRGB(2,4));                                            
	     setSurfacePieceRGB(2,4,getSurfacePieceRGB(2,5));                                            
	     setSurfacePieceRGB(2,5,getSurfacePieceRGB(2,6));                                            
	     setSurfacePieceRGB(2,6,getSurfacePieceRGB(5,2));                                            
	     setSurfacePieceRGB(5,2,getSurfacePieceRGB(5,3));                                            
	     setSurfacePieceRGB(5,3,temp);                                                       
		}else{	//反转			                                                           
	     setSurfacePieceRGB(5,4,getSurfacePieceRGB(5,3));                                            
	     setSurfacePieceRGB(5,3,getSurfacePieceRGB(5,2));                                            
	     setSurfacePieceRGB(5,2,getSurfacePieceRGB(2,6));                                            
	     setSurfacePieceRGB(2,6,getSurfacePieceRGB(2,5));                                            
	     setSurfacePieceRGB(2,5,getSurfacePieceRGB(2,4));                                            
	     setSurfacePieceRGB(2,4,getSurfacePieceRGB(0,0));                                            
	     setSurfacePieceRGB(0,0,getSurfacePieceRGB(0,7));                                            
	     setSurfacePieceRGB(0,7,getSurfacePieceRGB(0,6));                                            
	     setSurfacePieceRGB(0,6,getSurfacePieceRGB(4,2));                                            
	     setSurfacePieceRGB(4,2,getSurfacePieceRGB(4,1));                                            
	     setSurfacePieceRGB(4,1,getSurfacePieceRGB(4,0));                                            
	     setSurfacePieceRGB(4,0,temp);                                                       
		}                                                                             
		break;                                                                        
	case 2:                                                     
		//  s2相邻面正序LED顺序:s5-2,s5-1,s5-0,   s3-6,s3-5,s3-4,   s0-2,s0-1,s0-0,   s1-2,s1-1,s1-0  
		temp = getSurfacePieceRGB(5,2);  //备份s5-2                                          
		if(typeRL == 1){ 			// 正转(顺时针)                                        
	     setSurfacePieceRGB(5,2,getSurfacePieceRGB(1,0));                                            
	     setSurfacePieceRGB(1,0,getSurfacePieceRGB(1,1));                                            
	     setSurfacePieceRGB(1,1,getSurfacePieceRGB(1,2));                                            
	     setSurfacePieceRGB(1,2,getSurfacePieceRGB(0,0));                                            
	     setSurfacePieceRGB(0,0,getSurfacePieceRGB(0,1));                                            
	     setSurfacePieceRGB(0,1,getSurfacePieceRGB(0,2));                                            
	     setSurfacePieceRGB(0,2,getSurfacePieceRGB(3,4));                                            
	     setSurfacePieceRGB(3,4,getSurfacePieceRGB(3,5));                                            
	     setSurfacePieceRGB(3,5,getSurfacePieceRGB(3,6));                                            
	     setSurfacePieceRGB(3,6,getSurfacePieceRGB(5,0));                                            
	     setSurfacePieceRGB(5,0,getSurfacePieceRGB(5,1));                                            
	     setSurfacePieceRGB(5,1,temp);                                                       
		}else{	//反转			                                                     
	     setSurfacePieceRGB(5,2,getSurfacePieceRGB(5,1));                                               
	     setSurfacePieceRGB(5,1,getSurfacePieceRGB(5,0));                                            
	     setSurfacePieceRGB(5,0,getSurfacePieceRGB(3,6));                                            
	     setSurfacePieceRGB(3,6,getSurfacePieceRGB(3,5));                                            
	     setSurfacePieceRGB(3,5,getSurfacePieceRGB(3,4));                                            
	     setSurfacePieceRGB(3,4,getSurfacePieceRGB(0,2));                                            
	     setSurfacePieceRGB(0,2,getSurfacePieceRGB(0,1));                                            
	     setSurfacePieceRGB(0,1,getSurfacePieceRGB(0,0));                                            
	     setSurfacePieceRGB(0,0,getSurfacePieceRGB(1,2));                                            
	     setSurfacePieceRGB(1,2,getSurfacePieceRGB(1,1));                                            
	     setSurfacePieceRGB(1,1,getSurfacePieceRGB(1,0));                                            
	     setSurfacePieceRGB(1,0,temp);                                                       
		}                                                                             
		break;                                                                        
	case 3:                                                                    
		//  s3相邻面正序LED顺序:s5-0,s5-7,s5-6,   s4-6,s4-5,s4-4,   s0-4,s0-3,s0-2,   s2-2,s2-1,s2-0  
		temp = getSurfacePieceRGB(5,0);  //备份s5-0                        
		if(typeRL == 1){ 			// 正转(顺时针) 
	     setSurfacePieceRGB(5,0,getSurfacePieceRGB(2,0));
	     setSurfacePieceRGB(2,0,getSurfacePieceRGB(2,1));
	     setSurfacePieceRGB(2,1,getSurfacePieceRGB(2,2));
	     setSurfacePieceRGB(2,2,getSurfacePieceRGB(0,2)); 
	     setSurfacePieceRGB(0,2,getSurfacePieceRGB(0,3));
	     setSurfacePieceRGB(0,3,getSurfacePieceRGB(0,4));
	     setSurfacePieceRGB(0,4,getSurfacePieceRGB(4,4)); 
	     setSurfacePieceRGB(4,4,getSurfacePieceRGB(4,5));
	     setSurfacePieceRGB(4,5,getSurfacePieceRGB(4,6));
	     setSurfacePieceRGB(4,6,getSurfacePieceRGB(5,6)); 
	     setSurfacePieceRGB(5,6,getSurfacePieceRGB(5,7));
	     setSurfacePieceRGB(5,7,temp); 
		}else{	//反转			 
	     setSurfacePieceRGB(5,0,getSurfacePieceRGB(5,7));
	     setSurfacePieceRGB(5,7,getSurfacePieceRGB(5,6));
	     setSurfacePieceRGB(5,6,getSurfacePieceRGB(4,6)); 
	     setSurfacePieceRGB(4,6,getSurfacePieceRGB(4,5));
	     setSurfacePieceRGB(4,5,getSurfacePieceRGB(4,4));
	     setSurfacePieceRGB(4,4,getSurfacePieceRGB(0,4)); 
	     setSurfacePieceRGB(0,4,getSurfacePieceRGB(0,3));
	     setSurfacePieceRGB(0,3,getSurfacePieceRGB(0,2));
	     setSurfacePieceRGB(0,2,getSurfacePieceRGB(2,2)); 
	     setSurfacePieceRGB(2,2,getSurfacePieceRGB(2,1));
	     setSurfacePieceRGB(2,1,getSurfacePieceRGB(2,0));
	     setSurfacePieceRGB(2,0,temp);  
		}
		break;
	case 4:
		//  s4相邻面正序LED顺序:s5-6,s5-5,s5-4,   s1-6,s1-5,s1-4,   s0-6,s0-5,s0-4,    s3-2,s3-1,s3-0  
		temp = getSurfacePieceRGB(5,6);  //备份s5-6
		if(typeRL == 1){ 			// 正转(顺时针) 
	     setSurfacePieceRGB(5,6,getSurfacePieceRGB(3,0));
	     setSurfacePieceRGB(3,0,getSurfacePieceRGB(3,1));
	     setSurfacePieceRGB(3,1,getSurfacePieceRGB(3,2));
	     setSurfacePieceRGB(3,2,getSurfacePieceRGB(0,4)); 
	     setSurfacePieceRGB(0,4,getSurfacePieceRGB(0,5));
	     setSurfacePieceRGB(0,5,getSurfacePieceRGB(0,6));
	     setSurfacePieceRGB(0,6,getSurfacePieceRGB(1,4)); 
	     setSurfacePieceRGB(1,4,getSurfacePieceRGB(1,5));
	     setSurfacePieceRGB(1,5,getSurfacePieceRGB(1,6));
	     setSurfacePieceRGB(1,6,getSurfacePieceRGB(5,4)); 
	     setSurfacePieceRGB(5,4,getSurfacePieceRGB(5,5));
	     setSurfacePieceRGB(5,5,temp);       
		}else{	//反转			 
	     setSurfacePieceRGB(5,6,getSurfacePieceRGB(5,5));
	     setSurfacePieceRGB(5,5,getSurfacePieceRGB(5,4));
	     setSurfacePieceRGB(5,4,getSurfacePieceRGB(1,6)); 
	     setSurfacePieceRGB(1,6,getSurfacePieceRGB(1,5));
	     setSurfacePieceRGB(1,5,getSurfacePieceRGB(1,4));
	     setSurfacePieceRGB(1,4,getSurfacePieceRGB(0,6)); 
	     setSurfacePieceRGB(0,6,getSurfacePieceRGB(0,5));
	     setSurfacePieceRGB(0,5,getSurfacePieceRGB(0,4));
	     setSurfacePieceRGB(0,4,getSurfacePieceRGB(3,2)); 
	     setSurfacePieceRGB(3,2,getSurfacePieceRGB(3,1));
	     setSurfacePieceRGB(3,1,getSurfacePieceRGB(3,0));
	     setSurfacePieceRGB(3,0,temp);  
		}
		break;
	case 5:
		//  s5相邻面正序LED顺序:s4-0,s4-7,s4-6,   s3-0,s3-7,s3-6,   s2-0,s2-7,s2-6,   s1-0,s1-7,s1-6
		temp = getSurfacePieceRGB(4,0);  //备份s4-0
		if(typeRL == 1){ 			// 正转(顺时针) 
	     setSurfacePieceRGB(4,0,getSurfacePieceRGB(1,6));
	     setSurfacePieceRGB(1,6,getSurfacePieceRGB(1,7));
	     setSurfacePieceRGB(1,7,getSurfacePieceRGB(1,0));
	     setSurfacePieceRGB(1,0,getSurfacePieceRGB(2,6)); 
	     setSurfacePieceRGB(2,6,getSurfacePieceRGB(2,7));
	     setSurfacePieceRGB(2,7,getSurfacePieceRGB(2,0));
	     setSurfacePieceRGB(2,0,getSurfacePieceRGB(3,6)); 
	     setSurfacePieceRGB(3,6,getSurfacePieceRGB(3,7));
	     setSurfacePieceRGB(3,7,getSurfacePieceRGB(3,0));
	     setSurfacePieceRGB(3,0,getSurfacePieceRGB(4,6)); 
	     setSurfacePieceRGB(4,6,getSurfacePieceRGB(4,7));
	     setSurfacePieceRGB(4,7,temp);       
		}else{	//反转			 
	     setSurfacePieceRGB(4,0,getSurfacePieceRGB(4,7));
	     setSurfacePieceRGB(4,7,getSurfacePieceRGB(4,6));
	     setSurfacePieceRGB(4,6,getSurfacePieceRGB(3,0)); 
	     setSurfacePieceRGB(3,0,getSurfacePieceRGB(3,7));
	     setSurfacePieceRGB(3,7,getSurfacePieceRGB(3,6));
	     setSurfacePieceRGB(3,6,getSurfacePieceRGB(2,0)); 
	     setSurfacePieceRGB(2,0,getSurfacePieceRGB(2,7));
	     setSurfacePieceRGB(2,7,getSurfacePieceRGB(2,6));
	     setSurfacePieceRGB(2,6,getSurfacePieceRGB(1,0)); 
	     setSurfacePieceRGB(1,0,getSurfacePieceRGB(1,7));
	     setSurfacePieceRGB(1,7,getSurfacePieceRGB(1,6));
	     setSurfacePieceRGB(1,6,temp);  
		}
		break;
	} */
}

//某一个面旋转移动一位,移动两位为 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; 
			} 
} 
/*
//某一个面旋转移动一位,移动两位为 90度。  typeRL=1 为顺时针,其它为逆时针
void tempSurfaceLeftOrRightStep(unsigned char surfaceNumber,unsigned char typeRL){
			unsigned char temp;
			unsigned char i;
			unsigned char cr;
		   for(i = 0;i<3;i++){
				cr = tempCube[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);
				}
				tempCube[surfaceNumber][i] = cr; 
			} 
} 

//调用此方法直接操作某一面旋转90度,typeRL=1 为顺时针,其它为逆时针
void leftOrRightCubeSurface(unsigned char surfaceNumber, unsigned char typeRL) {
		aroundLeftOrRightStep(surfaceNumber, typeRL);
		// 刷新显示
		// 延迟5
		surfaceLeftOrRightStep(surfaceNumber, typeRL);
		// 刷新显示
		// 延迟10
		aroundLeftOrRightStep(surfaceNumber, typeRL);
		// 刷新显示
		// 延迟5
		surfaceLeftOrRightStep(surfaceNumber, typeRL);
		// 刷新显示
		// 延迟10
		aroundLeftOrRightStep(surfaceNumber, typeRL);
		// 刷新显示
}  
*/
//延迟函数//

void delayMinimum(ulong n){ 
	ulong i;
   for(i=0;i<n;i++);
}

//void Delay5us(){}		//@11.0592MHz

void delay_ms(ulong n)
{
	ulong i;
	//unsigned short j;
   for(i=0;i<n;i++) delayMinimum(50);
	   	//for(j=0;j<100;j++);
}

/*
void delays(ulong i){ //i=1时,时间为1s
	unsigned short q;
	for(q=0;q<=1000;q++){
		delay_ms(i);
	}
}*/




/输入信号检测函数:双边自复位开关///
/*sbit RIGHT = P2^6;
sbit LEFT = P2^7;
unsigned char detectInputSwitchVersionSub(){
	unsigned char i;  
	unsigned char test1 = P2;  
	unsigned char test2 = P2;  
	unsigned char test3 = P2;  
	for(i=0;i<6;i++){
		test1 = P2;  
		test2 = P2&(1<<i);
		test3 = 1<<i;
		if((P2&(1<<i))==0x00){
			//消抖
			delay_ms(30);
			if((P2&(1<<i))==0x00){
				return i;
			}
		}
	}
	return 8;
}
unsigned short detectInputSwitchVersion(){ //i=1时,时间为1s	
	unsigned char i;   
	unsigned short count = 0xfff;
	//进入按键检测时所有按键必须处于复位状态,否则直接输出0
	RIGHT = 0;
	LEFT = 0;
	if(P2!=0x3f) return 0x00;
	while((modeBit1==1&&modeBit2==1)||testBit1==0||testBit2==0){//判断是否退出魔方模式
		while(count--){//检测65535次
			//顺时针方向检测
			RIGHT = 0;
			LEFT = 1;
			i = detectInputSwitchVersionSub();
			if(i<8) return 0x0100|i;
		
			//逆时针方向检测
			RIGHT = 1;
			LEFT = 0;
			i = detectInputSwitchVersionSub();
			if(i<8) return 0xff00|i;
		}
	}
	return 0x00;
} */

/输入信号检测函数:三引脚旋转编码器///
#define input8 P2
#define input4 P4
unsigned short detectInputCoderVersionSub(unsigned short data1,unsigned short data2){
	unsigned short i,temp1,temp2;
	unsigned short temp; 
	for(i=0;i<6;i++){ 
		temp = 3<<(i<<1);
		temp1 = (data1&temp)>>(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){
/*	SCK = 0;
	DI = pinData;
	SCK = 1;*/
	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
//eightBitsData高位定义为0,低位为7
unsigned char registerWrite8BitData(unsigned char eightBitsData,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(eightBitsData,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(eightBitsData,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(eightBitsData,j));
		}
		registerWriteOnePinData(getCharBit(eightBitsData,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(eightBitsData,j));
		}
		registerWriteOnePinData(getCharBit(eightBitsData,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,标准正序
/*
	if(surfaceNumber==0){//由于第0号面焊接失误,所以不能使用默认驱动方式
		//第0号面蓝色焊接到了原本接红色LED的0号寄存器上
		colorAndOrder0[0] = 2;
		//第0号面红色焊接到了原本接蓝色LED的2号寄存器上,且顺序焊反
		colorAndOrder2[0] = 0;
		colorAndOrder2[1] = 1;
	}
*/
	
	//定制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个移位寄存器
		registerWrite8BitData(cube[surfaceNumber][colorAndOrder0[0]],colorAndOrder0[1]);
		registerWrite8BitData(cube[surfaceNumber][colorAndOrder1[0]],colorAndOrder1[1]);
		registerWrite8BitData(cube[surfaceNumber][colorAndOrder2[0]],colorAndOrder2[1]);
		registerWrite8BitData(cube[surfaceNumber][colorAndOrder3[0]],colorAndOrder3[1]);
	}else if(cubeNumber==1){
		//每个面4个移位寄存器
		registerWrite8BitData(tempCube[surfaceNumber][colorAndOrder0[0]],colorAndOrder0[1]);
		registerWrite8BitData(tempCube[surfaceNumber][colorAndOrder1[0]],colorAndOrder1[1]);
		registerWrite8BitData(tempCube[surfaceNumber][colorAndOrder2[0]],colorAndOrder2[1]);
		registerWrite8BitData(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 registerWriteOneLEDData(unsigned char oneLedData,unsigned char order){//写入一个LED数据,order为0为正序输入,否则为倒叙输入
	//char位定义从左至右为正序,编号为: 01234567,数据内容为 00000RGB
	//位移寄存器输出引脚从A到H位定义为正序,信号从H后输出,编号为: QA QB QC QD QE QF QG QH - SOH
	char j;
	if(order==0){//写入数据结果 QA-B QB-G QC-R QD- QE- QF- QG- QH-
		for(j=2;j>=0;j--){
			registerWriteOnePinData(getCharBit(oneLedData,j));
		}
	}else{
		for(j=0;j<3;j++){//写入数据结果 QA-R QB-G QC-B QD- QE- QF- QG- QH-
			registerWriteOnePinData(getCharBit(oneLedData,j));
		}
	}
}
void registerWriteSurface2(unsigned char cubeNumber,unsigned char surfaceNumber){//写入一个面的数据
	char j;
	unsigned char oneD;
	if(cubeNumber==0){
		if(j==0){
		 
		}
		for(j=0;j<9;j++){
			oneD = getSurfacePieceRGB(surfaceNumber,j);
			registerWriteOneLEDData(getSurfacePieceRGB(surfaceNumber,j),0);
		}
	}else if(cubeNumber==1){
		for(j=0;j<9;j++){
			oneD = getSurfacePieceRGB(surfaceNumber,j);
			if(j==0){
			 
			}
			registerWriteOneLEDData(getTempSurfaceRGB(surfaceNumber,j),0);
		}
	}else{
		return;
	}
	//再写入5个空位占位
	for(j=0;j<5;j++){
		registerWriteOnePinData(0);
	}
}*/
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);
/*	if(cubeNumber==0){
		Send_Cube(cube);
	}else if(cubeNumber==1){ 
		Send_Cube(tempCube);
	}*/
	rushICOut();
}

初始化LED展示效果1
void initWriteCube1sub(char i,char j,unsigned char sd){
	setTempSurfacePieceRGB(i,j,getSurfacePieceRGB(i,j));
	registerWriteCube(1);
	delay_ms(sd);
}
/*void initWriteCube1(){
	char i,j;
	for(i=0;i<6;i++){
		for(j=0;j<9;j++){
			initWriteCube1sub(i,j,2);
		}
	}
}*/
初始化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);
	}
}
/*
IC测试程序
//一个IC8位,一个面4个,共6个面,24个IC。可以存储24byte数据,输入24个char,然后在串行读取出来,如果读到的和输入的全一样,则认为IC完好
unsigned char testIC(unsigned char ICCount){
	unsigned char j,i,count=0;
	unsigned char serialOutputChar; 
	unsigned char w1,w2;
	for(j=0;j<0xff;j++){ //先清空
		registerWrite8BitData(0,0);
	}
	w1 = 0xaa;
	//写8位
	for(i=0;i<8;i++){  
		registerWriteOnePinData(getCharBit(w1,i));
	}
	w2 = 0xff;
	registerWrite8BitData(w1,1);//写入首位验证
	for(j=0;j<0xff;j++){ //最多检测0xff个IC
		count++;
		//写8位读8位
		for(i=0;i<8;i++){ 
			registerWrite8BitData(0,0);
			delayMinimum(10);
			setCharBit(&serialOutputChar,i,LQH);
		}
		if(serialOutputChar==w1){//读取到首位验证数据
			for(j=0;j<count;j++){//读取数据包
				//写8位
				for(i=0;i<8;i++){
					registerWrite8BitData(0,0);
				}
			} 
			//写8位读8位
			for(i=0;i<8;i++){ 
				registerWrite8BitData(0,0);
				delayMinimum(10);
				setCharBit(&serialOutputChar,i,LQH);
			}
			if(serialOutputChar==w2){//验证结束位
				if(ICCount==count)return 1;//验证通过
				else return 2;//数据准确但芯片数量不是ICCount
			}else{
				return 0;//芯片不好使
			}
		}
	}
	return 0;//芯片不好使或芯片数量超过0xff
}

LED测试自检程序
//依次点亮所有面的0~8号块的LED,再依次熄灭,重复一次
void testLED(){
	unsigned char i,j;
	for(i=0;i<9;i++){
		for(j=0;j<6;j++){
	   	setTempSurfacePieceRGB(j,i,7);
		}
		registerWriteCube(1);
		delay_ms(100);
	}
	for(i=0;i<9;i++){
		for(j=0;j<6;j++){
	   	setTempSurfacePieceRGB(j,i,0);
		}
		registerWriteCube(1);
		delay_ms(100);
	}
}
按键测试自检程序
//先点亮每个面的0号块的LED,当对应面的旋转指令按钮被按下时,对应面的0块向旋转指令方向位移一位
void testSwitch(){
	char i,j;
	unsigned short inputData;
	//进入时熄灭灯
	for(i=0;i<9;i++){
		for(j=0;j<6;j++){
	   	setTempSurfacePieceRGB(j,i,0);
		}
	}
	registerWriteCube(1);
	for(i=0;i<6;i++){ 
	   setTempSurfacePieceRGB(i,0,0x07);
	}
	registerWriteCube(1); 
	while(testBit1==0&&testBit2==1){
		inputData = detectInputSwitchVersion();
		if(inputData!=0){
			tempSurfaceLeftOrRightStep(inputData&0xff,inputData>>8);
			registerWriteCube(1);
		}
	}
	//退出时熄灭灯
	for(i=0;i<9;i++){
		for(j=0;j<6;j++){
	   	setTempSurfacePieceRGB(j,i,0);
		}
	}
	registerWriteCube(1);
}  

编码器测试自检程序
//先点亮每个面的0号块的LED,当对应面的旋转指令编码器被旋转时,对应面的0块向旋转指令方向位移一位
void testCoder(){
	char i,j;
	unsigned short inputData;	
	//进入时熄灭灯
	for(i=0;i<9;i++){
		for(j=0;j<6;j++){
	   	setTempSurfacePieceRGB(j,i,0);
		}
	}
	registerWriteCube(1);
	for(i=0;i<6;i++){ 
	   setTempSurfacePieceRGB(i,0,0x02);
	}
	registerWriteCube(1); 
	while(testBit2==0&&testBit1==1){
		inputData = detectInputCoderVersion(0);
		if(inputData!=0){
			tempSurfaceLeftOrRightStep(inputData&0xff,inputData>>8);
			registerWriteCube(1);
		}
	}
	//退出时熄灭灯
	for(i=0;i<9;i++){
		for(j=0;j<6;j++){
	   	setTempSurfacePieceRGB(j,i,0);
		}
	}
	registerWriteCube(1);
}	 */

面旋转函数
//调用此方法直接操作某一面旋转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开始计时
} /*
void TurnOnTimerInterrupt(){
	//timerInit0();
	EA=1;     //允许总中断
	ET0=1;    //允许定时器0中断
} 
void TurnOffTimerInterrupt(){
	//TR0=0;	//停止计时
	ET0=0;	//关闭定时器中断
	EA=0;		//关闭总中断
	TF0 = 0;	//清除中断标记  
} 
unsigned char scale = 1;//1~10
// 定时中断器控制OE引脚,控制LED亮度
void Timer0_IRQ(void) interrupt 1 {
	static unsigned char tt ;   //tt用来保存当前时间在一秒中的比例位置
	if(modeBit1==1&&modeBit2==1){//11模式:魔方
		//OE= ~OE;
		tt++;    //每1微秒增加1
		if(tt==10){   //10微妙的时钟周期
			tt=0;  //使tt=0,开始新的PWM周期
			opernICOut();  //使LED灯亮
		}else if(scale<tt)closeICOut();   //按照当前占空比切换输出为高电平,使LED灯灭
	}else if(modeBit1==1&&modeBit2==0){//10模式:
		//OE= ~OE;
		tt++;    //每1微秒增加1
		if(tt==10){   //10微妙的时钟周期
			tt=0;  //使tt=0,开始新的PWM周期
			opernICOut();  //使LED灯亮
		}else if(scale<tt)closeICOut();   //按照当前占空比切换输出为高电平,使LED灯灭
	}else if(modeBit1==0&&modeBit2==1){//01模式:
	}else if(modeBit1==0&&modeBit2==0){//00模式:
	}
}*/
/*
void Timer0_IRQ(void) interrupt 1 {
	//OE= ~OE;
}*/

/层先法自动还原//
//获取此块相邻面的坐标(0x[面编号][块编号])
//输入为角块时,返回以输入角块面为左上角,取此角块面上方相邻角块面的坐标
unsigned char getAdjacentBlock(unsigned char surfaceNumber,unsigned char index){
	unsigned char surfaceNumberR=0,indexR=0,offset=0;
/*	unsigned char R[6][8] = {
	{2,3,3,3,4,3,1,3},
	{2,5,0,7,4,1,5,3},
	{3,5,0,1,1,1,5,1},
	{4,5,0,3,2,1,5,7},
	{1,5,0,5,3,1,5,5},
	{2,7,1,7,4,7,3,7}
	};
	if(index%2==0){
		offset = 1;
	}
	surfaceNumberR = R[surfaceNumber][index-1];
	indexR = R[surfaceNumber][index];*/
	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位
		/*switch (index) {
		case 1:surfaceNumberR=2;break;
		case 3:surfaceNumberR=3;break;
		case 5:surfaceNumberR=4;break;
		case 7:surfaceNumberR=1;break;
		}*/
		break;
	case 1: 
		if(index<4){//节省代码空间15位
			surfaceNumberR = (index+1)%4;
			indexR=index+4;
		}else{
			surfaceNumberR = 4+index/6;
			indexR=1+index%5;
		}
		/*switch (index) {
		case 1:surfaceNumberR=2;indexR=5;break;
		case 3:surfaceNumberR=0;indexR=7;break;
		case 5:surfaceNumberR=4;indexR=1;break;
		case 7:surfaceNumberR=5;indexR=3;break;
		}*/
		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位
		/*switch (index) {
		case 1:surfaceNumberR=2;break;
		case 3:surfaceNumberR=1;break;
		case 5:surfaceNumberR=4;break;
		case 7:surfaceNumberR=3;break;
		}*/
		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;
	/*	unsigned char temp,surfaceNumberTemp,surfaceNumberTemp1;
	//获取目标棱块和当前棱块相对位置
	temp = getEdgeRelativePosition(surfaceNumber0,index0,surfaceNumber1,index1);	
	if(temp==0)return 0; 
	//获取顶面编号
	surfaceNumberTemp = getAdjacentBlock(surfaceNumber0,getVertexOrEdgeNumber(index0,'R'))>>4&0x0f;
	if(temp==2||temp==3||temp==10||temp==11||temp==12||temp==20){//在顶面上,移动到固定位置
		if(temp==2||temp==12){//反转
			leftOrRightCubeSurfaceC52(surfaceNumberTemp,0);
		}else{//正转
			leftOrRightCubeSurfaceC52(surfaceNumberTemp,1);
		}
	}else{
		surfaceNumberTemp1 = getAdjacentBlock(surfaceNumber0,index0)>>4&0x0f;//本面相邻面
		if(temp==1||temp==13){//在13位执行本块面还原二层左棱块函数
			restoreOneSecondEdgeSub(surfaceNumber0,surfaceNumberTemp1,surfaceNumberTemp,0);
		}else if (temp==21){//在21位执行本块面相邻临块面还原二层右棱块函数
			restoreOneSecondEdgeSub(surfaceNumberTemp1,surfaceNumber0,surfaceNumberTemp,1);
		} else{ 
			surfaceNumberTemp1 = getAdjacentBlock(surfaceNumber1,index1)>>4&0x0f;//目标面相邻面
			if(temp==4||temp==19||temp==22){//4,19,22,执行目标块还原二层右棱块函数
				restoreOneSecondEdgeSub(surfaceNumber1,surfaceNumberTemp1,surfaceNumberTemp,1);
			}else if(temp==5||temp==18||temp==23){//5,18,23目标块还原二层左棱块函数
				restoreOneSecondEdgeSub(surfaceNumber1,surfaceNumberTemp1,surfaceNumberTemp,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 restoreTopCrossShaped(unsigned char surfaceNumber){
	unsigned char aroundSurfaceNumber[4],tempRGB_R,index;
	unsigned char topSurfaceNumber = getOppositeNumber(surfaceNumber);//获取顶面编号
	unsigned char topRGB = getSurfacePieceRGB(topSurfaceNumber,8);//获取顶面颜色
	//unsigned char count = 30;
	//获取顶面四个相邻面编号
	for(index=1;index<8;index+=2){
		aroundSurfaceNumber[(index-1)/2] = getAdjacentBlock(topSurfaceNumber,index)>>4&0x0f;
	}
	while(1){
		//获取四个棱块面颜色是否为目标色
		for(index=1;index<8;index+=2){
			tempRGB_R = ((tempRGB_R<<1)|(getSurfacePieceRGB(topSurfaceNumber,index)==topRGB))&0x0f;
		}
		//SendOneByte(tempRGB_R);
		switch(tempRGB_R){
		case 0://完全不对情况
			restoreTopCrossShapedSub(aroundSurfaceNumber[0],aroundSurfaceNumber[3],topSurfaceNumber);break;
		case 3:case 6://角情况1 2 
			restoreTopCrossShapedSub(aroundSurfaceNumber[2-tempRGB_R/3],aroundSurfaceNumber[(5-tempRGB_R/3)%4],topSurfaceNumber);break;
		case 12:case 9://角情况3 4
			restoreTopCrossShapedSub(aroundSurfaceNumber[tempRGB_R/6+1],aroundSurfaceNumber[tempRGB_R/6],topSurfaceNumber);break;
		case 5://线情况1
			restoreTopCrossShapedSub(aroundSurfaceNumber[2],aroundSurfaceNumber[1],topSurfaceNumber);break;
		//case 13://线情况2	restoreTopCrossShapedSub(aroundSurfaceNumber[tempRGB_R%12+1],aroundSurfaceNumber[tempRGB_R%12],topSurfaceNumber);break;
		case 10://线情况3456
			//test = aroundSurfaceNumber[tempRGB_R%10];
			restoreTopCrossShapedSub(aroundSurfaceNumber[1],aroundSurfaceNumber[0],topSurfaceNumber);break;
		default:return;//完成情况或意外情况
		}
		//while(key2);//按一下继续
	}
}*/
	
//还原顶面
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 restoreTopSurface(unsigned char surfaceNumber){
	unsigned char aroundSurfaceNumber[4],tempRGB_R,index;
	unsigned char topSurfaceNumber = getOppositeNumber(surfaceNumber);//获取顶面编号
	unsigned char topRGB = getSurfacePieceRGB(topSurfaceNumber,8);//获取顶面颜色
	while(1){
		//获取顶面四个相邻面编号
		for(index=1;index<8;index+=2){
			tempCube[5][(index-1)/2] = getAdjacentBlock(topSurfaceNumber,index)>>4&0x0f;
		}
		//获取4个角块的8个相邻面颜色是否为目标色
		for(index=0;index<8;index+=2){
			surfaceNumber=getAdjacentBlock(topSurfaceNumber,index);
			tempRGB_R = tempRGB_R<<2|(getSurfacePieceRGB(surfaceNumber>>4,surfaceNumber&0xf)==topRGB);
			surfaceNumber=getAdjacentBlock(surfaceNumber>>4,surfaceNumber&0xf);
			tempRGB_R = tempRGB_R|(getSurfacePieceRGB(surfaceNumber>>4,surfaceNumber&0xf)==topRGB)<<1;
		}
		//SendOneByte(tempRGB_R);
		switch(tempRGB_R){
		case 0:return;//完成 
		case 138://情况1
		case 105:case 102:case 24:case 144:case 18://情况3 4 5 6 7
			restoreTopSurfaceSub(getAdjacentBlock(topSurfaceNumber,5)>>4&0x0f,topSurfaceNumber,0);break;
		case 81://情况2
			restoreTopSurfaceSub(getAdjacentBlock(topSurfaceNumber,1)>>4&0x0f,topSurfaceNumber,1);break;
		default:leftOrRightCubeSurfaceC52(topSurfaceNumber,1);break;
		}
	}
}*/


//还原顶面角块
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);//获取顶面颜色
		/* //获取顶面四个相邻面编号
		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;
		} */
		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);
				/*else{//角块拼错了,重拼
					restoreTopVertex(surfaceNumber);continue;
				}*/
				restoreTopVertex(surfaceNumber);
				/*leftOrRightCubeSurfaceC52(tempCube[0][2],0); 
				restoreTopSurfaceSub(tempCube[5][2],tempCube[0][2],1); */
				/*leftOrRightCubeSurfaceC52(tempCube[0][2],1); 
				restoreTopSurfaceSub(tempCube[5][2],tempCube[0][2],1); 
				leftOrRightCubeSurfaceC52(tempCube[0][2],1); 
				restoreTopSurfaceSub(tempCube[5][0],tempCube[0][2],0);*/
				//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();  
/*	opernICOut();
	delay=0;
	while(dw--){
	disorganizeCube();     
	disorganizeCube();  
	restore(5);
	}	  */

/*	restore(1);
	restore(2);
	restore(3);
	restore(4);
	restore(5);*/

	//引脚状态初始化
	P1=0x3f;
/*	P2=0xff;
	P3=0xff;
	P4=0xff;*/
	
	 /* 
	//74HC595 IC自检程序,检测通过显示绿灯,不通过显示红灯,检测数据通过但IC数量不对两个灯都亮。这里需要把最后一片IC的输出接到P1.5引脚上,用于串行输出检测。
	stateB=1;
	stateR=1;
	inputData = testIC(24);
	if(inputData==1)//验证通过
		stateR=0;
	else if(inputData==0) //验证不通过
		stateB=0;
	else;	//数据验证通过但IC数量不对
		
	//硬件检测程序
	if(testBit1==0||testBit2==0){
		opernICOut();
		while(testBit1==0||testBit2==0){
			while(testBit1==0&&testBit2==0)testLED();//显示检测程序
			//if(testBit1==0&&testBit2==1)testSwitch();//按键检测程序
			if(testBit1==1&&testBit2==0)testCoder();//编码器检测程序
		}
		for(i=0;i<9;i++){//退出时清空数据
			for(j=0;j<6;j++){
		   	setTempSurfacePieceRGB(j,i,0);
			}
		}
		closeICOut();
		registerWriteCube(1);
	} */ 
 

	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输出
		/*for(i=0;i<24;i++){//逐面点亮 
			registerWrite8BitData(0xff,0);
			rushICOut();
			delay_ms(100);
		}
		RCK = 0;*/
		//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(scale<tt)closeICOut();   //按照当前占空比切换输出为高电平,使LED灯灭
			//delay_ms(1);
			if(newCube){
				newCube=0;
				if(i==194){
					//颜色改变,刷新颜色任务
					if(j!=0){ 
						if(n==0){
						   if(j<54){
			 			   	setTempSurfacePieceRGB(j/9,j%9,getTempSurfacePieceRGB((j-1)/9,(j-1)%9));
								j++;
								n=255;
							}else{
								j=0;
								registerWriteCube(1);
							}
						}else{
							n--;
						}
						newCube=1;
						continue;
					}
				}else if(i==193){//初始化完成
					j=0;
					i++;
				}else{//初始化任务
					if(j==180){
						i++;
						j=0;
						registerWriteOnePinData(1);
						rushICOut();
					}
					j++;
					newCube=1;
				}
			}
			if(key1==0||key2==0){ //非阻断按键检测
				if(tempValue<0x3fe)
					tempValue++;
			}else{
				tempValue=0;
			}
			inputData = detectInputCoderVersion(0);//旋转编码器检测
			
			if((inputData!=0||(tempValue>0&&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<dw)//亮度+
					scale++;
				else if((inputData>>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);						 
			/*
			//j=tempValue;
			if(i++==10){
				i=1;
				n=(n+1)%3;
				//while(key1);
			}
			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);
			} 
			newCube = tempValue>>4&0x00ff;
			j = tempValue&0x00ff;
			tempValue=tempValue*50;
			while(tempValue--){ 
				inputData = detectInputCoderVersion(inputData>0);//旋转编码器检测
			}
			tempValue = ((tempValue&0)|newCube<<4)|j;
			if(inputData>0){  
				closeICOut();
				if(inputData>>8==1)
					tempValue=min(tempValue,tempValue+70);
				else
					tempValue=tempValue-min(tempValue,70);
				inputData=0;
			}*/
		} 
		goto begin;
	}

	if(modeBit1==0&&modeBit2==0){//-----------------------------00模式:关闭输出,用开发板电源输出口充电时开发板必须处于开机状态,可使用此模式。
		while(modeBit1==0&&modeBit2==0);
   	goto begin;
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值