



u8 newCmd = 0;//接收标志位
u8 dataIn[15] = {0}; //存储接收到的数据
u8 Addr;//存储传感器地址


enum RdSerialState {
	SeekForHead,		//字头
	ReadLength,			//字长
	ReadAddr,				//地址
	ReadData,				//读数据
	ReadRange,			//读功能码
	ReadChecksum		//读校验位
};

/*
函数作用：解析收到的数据
输入：uartIn  接收到的数据
输出：addr  地址
输出：dataOut 接收到的角度数据
*/
u8 ReadSerial(u8 uartIn, u8* addr,u8* dataOut)
{
	static u8 checksum = 0;
	static enum RdSerialState rdSerialState = SeekForHead;
	static u8 length = 0;
	static u8 dataArrIndex = 0;
	int i;
	u8 newCmd = 0;

	switch(rdSerialState) {
		case SeekForHead: {
			if(0x77==uartIn) {
				rdSerialState = ReadLength;
			}
			checksum = 0;
			dataArrIndex = 0;
			break;
		}		
	case ReadLength: {
			checksum = checksum+uartIn;
			rdSerialState = ReadAddr;
			length = uartIn-1;
			break;
		}
		case ReadAddr: {
			checksum = checksum+uartIn;
			*addr = uartIn;
			rdSerialState = ReadRange;
			length--;
			break;
		}
		case ReadRange: {
			checksum = checksum+uartIn;
			length--;	
			if(0x84==uartIn) {
				rdSerialState = ReadData;
				for(i = 1; i<10; i++) 
				{
					dataOut[i] = 0;
				}
			}
			else rdSerialState = SeekForHead;
			
			break;
		}
		case ReadData: {
			checksum = checksum+uartIn;
			
			length--;
			if(1==length) {
				rdSerialState = ReadChecksum;
			}else {
				rdSerialState = ReadData;
			}
			if(dataArrIndex>=15) {
				rdSerialState = SeekForHead; 
			}else {
				dataOut[dataArrIndex] = uartIn;
				dataArrIndex++;
			}
			
			break;	
		}
	
		case ReadChecksum: {
			rdSerialState = SeekForHead;
			if((checksum==uartIn) && (length == 1)) {	   //Be sure the command is for the sensor of the right addr
				newCmd = 1;
			}
			break;
		}
	}

	return newCmd;
}



// void USART1_IRQHandler(void)
// { 
// 	u8 data;
// 	
//   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
//   {
//     	/* Read one byte from the receive data register */
//     	data = USART_ReceiveData(USART1);

// 			newCmd = ReadSerial(data,&Addr,dataIn); 
// 	}
// }

//USART3接收中断
void USART3_IRQHandler(void)
{ 
	u8 data;
	
  	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
  	{
    	/* Read one byte from the receive data register */
    	data = USART_ReceiveData(USART3);
		//put the data to fifo, the readSerial() will get data from fifo at proper time
			newCmd = ReadSerial(data,&Addr,dataIn);     
	}
}

void USART1_Send_Byte(u8 byte)   //串口发送一个字节
{
	GPIO_SetBits(GPIOB,GPIO_Pin_12);		//输出允许
	delay_ms(5);
  USART_SendData(USART1, byte);        //通过库函数  发送数据
  while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);  
        //等待发送完成。   检测 USART_FLAG_TC 是否置1；    //见库函数 P359 介绍
	GPIO_ResetBits(GPIOB,GPIO_Pin_12);	//接收允许
}

/*------------串口1 发送一个字符串-------------------
程序调用示例：
uchar code str1[]="XiaoQiang";  //定义一个 字符串  注意 字符串 是"" 
UART1_Send_Str(str1);         //发送字符串
-----------------------------------------------------*/
//发送字符串 函数   应用指针 方法
void UART1_Send_Str(unsigned char *s)//发送字符串 函数   应用指针 方法
{
        unsigned char i=0;  //定义一个局部变量  用来 发送字符串 ++运算

        while(s[i]!='\0')  // 每个字符串结尾 都是以  \0 结尾的
        {
                USART_SendData(USART1,s[i]);        //通过库函数  发送数据
                while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);  
                //等待发送完成。   检测 USART_FLAG_TC 是否置1；    //见库函数 P359 介绍

                i++;                 //i++一次
        }

}





 int main(void)
 {
	float Out_X;
	float Out_Y;
// 	float Out_Z; 
	 
 	SystemInit();//系统时钟等初始化
	delay_init(72);	     //延时初始化
	NVIC_Configuration();//设置NVIC中断分组2:2位抢占优先级，2位响应优先级
	uart_init(9600);//串口初始化为9600
	while(1)
	{
		if(newCmd) 
		{
			newCmd = 0;
		
			Out_X=(dataIn[0]&0x0F)*100+(dataIn[1]>>4)*10+(dataIn[1]&0x0F)+(dataIn[2]>>4)*0.1+(dataIn[2]&0x0F)*0.01+(dataIn[3]>>4)*0.001+(dataIn[3]&0x0F)*0.0001;//转换X轴角度数据
			if((dataIn[0]&0xF0))Out_X=-Out_X;  //首位代表正负号
			Out_Y=(dataIn[4]&0x0F)*100+(dataIn[5]>>4)*10+(dataIn[5]&0x0F)+(dataIn[6]>>4)*0.1+(dataIn[6]&0x0F)*0.01+(dataIn[7]>>4)*0.001+(dataIn[7]&0x0F)*0.0001;//转换Y轴角度数据
		  if((dataIn[4]&0xF0))Out_Y=-Out_Y;		 //首位代表正负号
// 			Out_Z=(dataIn[6]&0x0F)*100+(dataIn[7]>>4)*10+(dataIn[7]&0x0F)+(dataIn[8]>>4)*0.1+(dataIn[8]&0x0F)*0.01;//转换Z轴角度数据
// 		  if((dataIn[6]&0xF0))Out_Z=-Out_Z;		 //首位代表正负号,gZ=%5.4f,Out_Z
			printf("ID:%d,gX=%5.4f,gY=%5.4f\r\n",Addr,Out_X,Out_Y);					
		}		

	}	 

 }












