参考资料:
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;
}
}