void uart_init(u32 bound){
   
    GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);  
	
	
	
     //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    //USART1_RX	  PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

	//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;	    		
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 
		GPIO_Init(GPIOB, &GPIO_InitStructure);	
		GPIO_ResetBits(GPIOB,GPIO_Pin_12); 						
	
	
        /* Configure USART3 Rx as input floating */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

		/* Configure USART3 Tx as alternate function push-pull */
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
		GPIO_Init(GPIOB, &GPIO_InitStructure);	
	
	
   //Usart1 NVIC ????

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//

	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
	NVIC_Init(&NVIC_InitStructure);	
  
   //USART 
   
	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);
   

//     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
   
    USART_Cmd(USART1, ENABLE);                   
		
		
		
   //Usart3

  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
	NVIC_Init(&NVIC_InitStructure);	
  
   //USART 3?¨º??¡¥¨¦¨¨??
   
	USART_InitStructure.USART_BaudRate = bound;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART3, &USART_InitStructure);
   

    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
   
    USART_Cmd(USART3, ENABLE);                 		
}



u8 newCmd = 0;
u8 dataIn[10] = {0}; 
u8 Addr;


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>=10) {
				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 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);     
	}
}

u8 Data1[5]={0x77,0x04,0x00,0x04,0x08};
int main(void)
 {
	float Out_X;
	float Out_Y;
	float Out_Z; 
	 
 	SystemInit();
	delay_init(72);	   
	NVIC_Configuration();
	uart_init(9600);//¡ä??¨²3?¨º??¡¥?a9600
	while(1)
	{
		USARTSendString(USART3, Data1, 5);
		delay_ms(30);		
		
		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;
			if((dataIn[0]&0xF0))Out_X=-Out_X;  
			Out_Y=(dataIn[3]&0x0F)*100+(dataIn[4]>>4)*10+(dataIn[4]&0x0F)+(dataIn[5]>>4)*0.1+(dataIn[5]&0x0F)*0.01;
		  if((dataIn[3]&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;
		  if((dataIn[6]&0xF0))Out_Z=-Out_Z;		
			printf("ID:%d,gX=%5.4f,gY=%5.4f,gZ=%5.4f\r\n",Addr,Out_X,Out_Y,Out_Z);					
		}	
	}	 

 }




