#include "stm32f10x.h"
#include "uart.h"
#include "delay.h"

#include "led.h"
#include "beep.h"

//C库
#include <stdarg.h>
#include <string.h>
#include <stdio.h>

char datas[100];
char datas_uart3[200];
char datas_uart2[200];
int cnt_uart3=0,cntPre_uart3;
int cnt_uart2=0,cntPre_uart2;
int cnt=0,cntPre;
int *p=&cnt;

/*
************************************************************
*	函数名称：	Usart_SendString
*
*	函数功能：	串口数据发送
*
*	入口参数：	USARTx：串口组
*				str：要发送的数据
*				len：数据长度
*
*	返回参数：	无
*
*	说明：		
************************************************************
*/
void Usart_SendString(USART_TypeDef *USARTx, unsigned char *str, unsigned short len)
{

	unsigned short count = 0;
	
	for(; count < len; count++)
	{
		USART_SendData(USARTx, *str++);									//发送数据
		while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);		//等待发送完成
	}

}

/*
************************************************************
*	函数名称：	UsartPrintf
*
*	函数功能：	格式化打印
*
*	入口参数：	USARTx：串口组
*				fmt：不定长参
*
*	返回参数：	无
*
*	说明：		
************************************************************
*/

void UsartPrintf(USART_TypeDef *USARTx, char *fmt,...)
{
	unsigned char UsartPrintfBuf[296];
	va_list ap;
	unsigned char *pStr = UsartPrintfBuf;
	USART_ClearFlag(USART1 , USART_FLAG_TC);																				//解决第一个数据发送失败的问题
	va_start(ap, fmt);
	vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap);							//格式化
	va_end(ap);
	
	while(*pStr != 0)
	{
		USART_SendData(USARTx, *pStr++);
		while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);
	}

}

void USER_USART1(void)
{ 
	GPIO_InitTypeDef GPIO_Initstr;
	USART_InitTypeDef USART_Initstr;
	NVIC_InitTypeDef NVIC_Initstr;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	GPIO_Initstr.GPIO_Mode=GPIO_Mode_AF_PP;   //推挽复用输出
	GPIO_Initstr.GPIO_Pin=GPIO_Pin_9;
	GPIO_Initstr.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&GPIO_Initstr);
	
	GPIO_Initstr.GPIO_Mode=GPIO_Mode_IN_FLOATING;  //浮空输入
	GPIO_Initstr.GPIO_Pin=GPIO_Pin_10;
	GPIO_Initstr.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&GPIO_Initstr);
	
	USART_Initstr.USART_BaudRate=9600;    //波特率
	USART_Initstr.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //不使用硬件流
	USART_Initstr.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_Initstr.USART_Parity=USART_Parity_No;    //无奇偶校验
	USART_Initstr.USART_StopBits=USART_StopBits_1; //停止位1位
	USART_Initstr.USART_WordLength=USART_WordLength_8b;  //数据位8位
	
	USART_Init(USART1,&USART_Initstr);
	USART_Cmd(USART1,ENABLE);
	USART_ClearFlag(USART1 , USART_FLAG_TC);//解决第一个数据发送失败的问题
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	NVIC_Initstr.NVIC_IRQChannel=USART1_IRQn;
	NVIC_Initstr.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Initstr.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_Initstr.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_Initstr);
}

void USER_USART2(void)
{ 
	GPIO_InitTypeDef GPIO_Initstr;
	USART_InitTypeDef USART_Initstr;
	NVIC_InitTypeDef NVIC_Initstr;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
	
	GPIO_Initstr.GPIO_Mode=GPIO_Mode_AF_PP;   //推挽复用输出
	GPIO_Initstr.GPIO_Pin=GPIO_Pin_2;
	GPIO_Initstr.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&GPIO_Initstr);
	
	GPIO_Initstr.GPIO_Mode=GPIO_Mode_IN_FLOATING;  //浮空输入
	GPIO_Initstr.GPIO_Pin=GPIO_Pin_3;
	GPIO_Initstr.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&GPIO_Initstr);
	
	USART_Initstr.USART_BaudRate=9600;    //波特率
	USART_Initstr.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //不使用硬件流
	USART_Initstr.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_Initstr.USART_Parity=USART_Parity_No;    //无奇偶校验
	USART_Initstr.USART_StopBits=USART_StopBits_1; //停止位1位
	USART_Initstr.USART_WordLength=USART_WordLength_8b;  //数据位8位
	
	USART_Init(USART2,&USART_Initstr);
	USART_Cmd(USART2,ENABLE);
	USART_ClearFlag(USART2 , USART_FLAG_TC);//解决第一个数据发送失败的问题
	
	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
	
	NVIC_Initstr.NVIC_IRQChannel=USART2_IRQn;
	NVIC_Initstr.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Initstr.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_Initstr.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_Initstr);
}


void USER_USART3(void)
{ 
	GPIO_InitTypeDef GPIO_Initstr;
	USART_InitTypeDef USART_Initstr;
	NVIC_InitTypeDef NVIC_Initstr;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
	
	USART_DeInit(USART3);    //复位串口3
	
	GPIO_Initstr.GPIO_Mode=GPIO_Mode_AF_PP;  //推挽复用输出
	GPIO_Initstr.GPIO_Pin=GPIO_Pin_10;
	GPIO_Initstr.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOB,&GPIO_Initstr);
	
	GPIO_Initstr.GPIO_Mode=GPIO_Mode_IN_FLOATING;		 //浮空输入
	GPIO_Initstr.GPIO_Pin=GPIO_Pin_11;
	GPIO_Initstr.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOB,&GPIO_Initstr);
	
	USART_Initstr.USART_BaudRate=9600;    //波特率
	USART_Initstr.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //不使用硬件流
	USART_Initstr.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_Initstr.USART_Parity=USART_Parity_No;    //无奇偶校验
	USART_Initstr.USART_StopBits=USART_StopBits_1; //停止位1位
	USART_Initstr.USART_WordLength=USART_WordLength_8b;  //数据位8位
	
	USART_Init(USART3,&USART_Initstr);
	USART_Cmd(USART3,ENABLE);
	USART_ClearFlag(USART3 , USART_FLAG_TC);//解决第一个数据发送失败的问题
	
	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
	
	NVIC_Initstr.NVIC_IRQChannel=USART3_IRQn;
	NVIC_Initstr.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Initstr.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_Initstr.NVIC_IRQChannelSubPriority=3;
	NVIC_Init(&NVIC_Initstr);
	
	
}

/*
************************************************************
*	函数名称：	Usart3_Init
*
*	函数功能：	串口3初始化
*
*	入口参数：	baud：设定的波特率
*
*	返回参数：	无
*
*	说明：		TX-PB10		RX-PB11
************************************************************
*/
void Usart3_Init(unsigned int baud)
{

	GPIO_InitTypeDef gpioInitStruct;
	USART_InitTypeDef usartInitStruct;
	NVIC_InitTypeDef nvicInitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	
	//PB10	TXD
	gpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	gpioInitStruct.GPIO_Pin = GPIO_Pin_10;
	gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &gpioInitStruct);
	
	//PB11	RXD
	gpioInitStruct.GPIO_Mode = GPIO_Mode_IPU;
	gpioInitStruct.GPIO_Pin = GPIO_Pin_11;
	gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &gpioInitStruct);
	
	usartInitStruct.USART_BaudRate = baud;
	usartInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;		//无硬件流控
	usartInitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;						//接收和发送
	usartInitStruct.USART_Parity = USART_Parity_No;									//无校验
	usartInitStruct.USART_StopBits = USART_StopBits_1;								//1位停止位
	usartInitStruct.USART_WordLength = USART_WordLength_8b;							//8位数据位
	USART_Init(USART3, &usartInitStruct);
	
	USART_Cmd(USART3, ENABLE);														//使能串口
	
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);									//使能接收中断
	
	nvicInitStruct.NVIC_IRQChannel = USART3_IRQn;
	nvicInitStruct.NVIC_IRQChannelCmd = ENABLE;
	nvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	nvicInitStruct.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&nvicInitStruct);

}

void Serial_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
 
 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOB, &GPIO_InitStructure);
 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOB, &GPIO_InitStructure);
 
 
 USART_InitStructure.USART_BaudRate = 9600;
 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
 USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
 USART_InitStructure.USART_Parity = USART_Parity_No;
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 USART_Init(USART3, &USART_InitStructure);
 
 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
 
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
 
 
 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
 NVIC_Init(&NVIC_InitStructure);
 
 USART_Cmd(USART3, ENABLE);
}


/*
************************************************************
*	函数名称：	Usart1_Init
*
*	函数功能：	串口1初始化
*
*	入口参数：	baud：设定的波特率
*
*	返回参数：	无
*
*	说明：		TX-PA9		RX-PA10
************************************************************
*/
void Usart1_Init(unsigned int baud)
{

	GPIO_InitTypeDef gpioInitStruct;
	USART_InitTypeDef usartInitStruct;
	NVIC_InitTypeDef nvicInitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	//PA9	TXD
	gpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	gpioInitStruct.GPIO_Pin = GPIO_Pin_9;
	gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &gpioInitStruct);
	
	//PA10	RXD
	gpioInitStruct.GPIO_Mode = GPIO_Mode_IPU;
	gpioInitStruct.GPIO_Pin = GPIO_Pin_10;
	gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &gpioInitStruct);
	
	usartInitStruct.USART_BaudRate = baud;
	usartInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;		//无硬件流控
	usartInitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;						//接收和发送
	usartInitStruct.USART_Parity = USART_Parity_No;									//无校验
	usartInitStruct.USART_StopBits = USART_StopBits_1;								//1位停止位
	usartInitStruct.USART_WordLength = USART_WordLength_8b;							//8位数据位
	USART_Init(USART1, &usartInitStruct);
	
	USART_Cmd(USART1, ENABLE);														//使能串口
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);									//使能接收中断
	
	nvicInitStruct.NVIC_IRQChannel = USART1_IRQn;
	nvicInitStruct.NVIC_IRQChannelCmd = ENABLE;
	nvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	nvicInitStruct.NVIC_IRQChannelSubPriority = 2;
	NVIC_Init(&nvicInitStruct);

}


//void USART1_IRQHandler(void)
//{

//	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
//	{
//		USART_ClearFlag(USART1, USART_FLAG_RXNE);
//	}

//}


_Bool WaitRecive(void)
{

	if(cnt == 0) 							//如果接收计数为0 则说明没有处于接收数据中，所以直接跳出，结束函数
		return 0;
		
	if(cnt == cntPre)				//如果上一次的值和这次相同，则说明接收完毕
	{
		cnt = 0;							//清0接收计数
//		Usart_SendString(USART1,(unsigned char *)cnt,strlen((unsigned char *)cnt));

//		UsartPrintf(USART1,"ok");
		return 1;								//返回接收完成标志
	}
		
	cntPre = cnt;					//置为相同
	
	return 0;								//返回接收未完成标志

}

_Bool WaitRecive2(void)
{

	if(cnt_uart2 == 0) 							//如果接收计数为0 则说明没有处于接收数据中，所以直接跳出，结束函数
		return 0;
		
	if(cnt_uart2 == cntPre_uart2)				//如果上一次的值和这次相同，则说明接收完毕
	{
		cnt_uart2 = 0;							//清0接收计数
//		Usart_SendString(USART1,(unsigned char *)cnt,strlen((unsigned char *)cnt));

//		UsartPrintf(USART1,"ok");
		return 1;								//返回接收完成标志
	}
		
	cntPre_uart2 = cnt_uart2;					//置为相同
	
	return 0;								//返回接收未完成标志

}

_Bool WaitRecive3(void)
{

	if(cnt_uart3 == 0) 							//如果接收计数为0 则说明没有处于接收数据中，所以直接跳出，结束函数
		return 0;
		
	if(cnt_uart3 == cntPre_uart3)				//如果上一次的值和这次相同，则说明接收完毕
	{
		cnt_uart3 = 0;							//清0接收计数
//		Usart_SendString(USART1,(unsigned char *)cnt,strlen((unsigned char *)cnt));

//		UsartPrintf(USART1,"ok");
		return 1;								//返回接收完成标志
	}
		
	cntPre_uart3 = cnt_uart3;					//置为相同
	
	return 0;								//返回接收未完成标志

}

void datas_Clear(void)  //清空
{

	memset(datas, 0, sizeof(datas));
	cnt = 0;

}

void datas2_Clear(void)  //清空
{

	memset(datas_uart2, 0, sizeof(datas_uart2));
	cnt_uart2 = 0;

}

void datas3_Clear(void)  //清空
{

	memset(datas_uart3, 0, sizeof(datas_uart3));
	cnt_uart3 = 0;

}

unsigned char SendCmd(char *res)
{
	
	unsigned char timeOut = 20;
	char *a,b;
	
	while(timeOut--)
	{
		if(WaitRecive() == 1)							//如果收到数据
		{
			a = strstr((const char *)datas, res);
			if(a != NULL)		//如果检索到关键词
			{
				UsartPrintf(USART1,(char *)datas);
				
				a = strchr(a,':');
				if(a != NULL)
				{
					a++;
					b = *a;
					datas_Clear();
					return (unsigned char)b;
				}else{
					datas_Clear();
					return 0;
				}
				
			}
		}
		
		delay_ms(2);
	}
	
	return 0;

}

unsigned char SendCmd2(char *res)
{
	
	unsigned char timeOut = 20;
	char *a,b;
	
	while(timeOut--)
	{
		if(WaitRecive2() == 1)							//如果收到数据
		{
			UsartPrintf(USART2,(char *)datas_uart2);
			a = strstr((const char *)datas_uart2, res);
			if(a != NULL)		//如果检索到关键词
			{
				UsartPrintf(USART2,(char *)datas_uart2);
				
				a = strchr(a,':');
				if(a != NULL)
				{
					a++;
					b = *a;
					datas2_Clear();
					return (unsigned char)b;
				}else{
					datas2_Clear();
					return 0;
				}
				
			}
		}
		
		delay_ms(2);
	}
	
	return 0;

}

unsigned char SendCmd3(char *res)
{
	
	unsigned char timeOut = 20;
	char *a,b;
	
	while(timeOut--)
	{
		if(WaitRecive3() == 1)							//如果收到数据
		{
			a = strstr((const char *)datas_uart3, res);
			if(a != NULL)		//如果检索到关键词
			{
					
					UsartPrintf(USART3,(char *)datas_uart3);
//					datas3_Clear();
//					return (unsigned char)b;

				
				a = strchr(a,':');
				if(a != NULL)
				{
					a++;
					b = *a;
					datas3_Clear();
					return (unsigned char)b;
				}else{
					datas3_Clear();
					return 0;
				}
				
			}
		}
		
		delay_ms(2);
	}
	
	return 0;

}

void USART1_IRQHandler(void)
{
//	u8 rec_date;
	if(USART_GetITStatus(USART1,USART_IT_RXNE))
	{
//		rec_date = USART_ReceiveData(USART1);
//		USART_SendData(USART1,rec_date);
//		//delay_ms(1000);
//		if(rec_date == 0x11)
//		{
//			BEEP=!BEEP;
//		}
				if(cnt >= sizeof(datas))	cnt = 0; //防止串口被刷爆
				datas[cnt++] = USART1->DR;
				
				USART_ClearFlag(USART1, USART_FLAG_RXNE);

//		LED0=0;
	}
	
}

void USART2_IRQHandler(void)
{
//	unsigned char datass2;
	if(USART_GetITStatus(USART2,USART_IT_RXNE))
	{

				if(cnt_uart2 >= sizeof(datas_uart2))	cnt_uart2 = 0; //防止串口被刷爆
				datas_uart2[cnt_uart2++] = USART2->DR;
				
//				datass2 = SendCmd2("CM");
//				if(datass2=='G'){
//					BEEP=!BEEP;
//				}else if(datass2=='S'){
//					LED0=!LED0;
//				}else if(datass2=='B'){
//					LED1=!LED1;
//				}
//				UsartPrintf(USART2,"aaaa\r\n");
				USART_ClearFlag(USART2, USART_FLAG_RXNE);

	}
	
}


void USART3_IRQHandler(void)
{
	if(USART_GetITStatus(USART3,USART_IT_RXNE))
	{

				if(cnt_uart3 >= sizeof(datas_uart3))	cnt_uart3 = 0; //防止串口被刷爆
				datas[cnt_uart3++] = USART3->DR;
				
				USART_ClearFlag(USART3, USART_FLAG_RXNE);

	}
	
}
