#include "usart.h"

//支持printf
//注意,读取USARTx->SR能避免莫名其妙的错误 

#if EN_USART1 == 1
char USART1_DMA_Send_Buff[USART1_SEND_LEN];	//DMA发送缓冲,最大USART1_SEND_LEN个字节.
char USART1_DMA_Recv_Buff[USART1_RECV_LEN];//DMA接收缓冲,最大USART_REC_LEN个字节.
char USART1_Recv_Buff[USART1_RECV_LEN];//接收缓冲,最大USART1_RECV_LEN个字节
u8 USART1_Recv_Flag=0;					//接收状态标记	 
u8 USART1_TX_Finish=1;
u32 USART1_ReceDatalen=0;
#endif

#if EN_USART2 == 1
char USART2_DMA_Send_Buff[USART2_SEND_LEN];
char USART2_DMA_Recv_Buff[USART2_RECV_LEN];
char USART2_Recv_Buff[USART2_RECV_LEN];
u8 USART2_Recv_Flag=0;
u8 USART2_TX_Finish=1;
#endif

#if EN_USART3 == 1
char USART3_DMA_Send_Buff[USART2_SEND_LEN];
char USART3_DMA_Recv_Buff[USART3_RECV_LEN];
char USART3_Recv_Buff[USART3_RECV_LEN];
u8 USART3_Recv_Flag=0; 
u8 USART3_TX_Finish=1;
#endif

//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
_sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数  (串口2可使用printf)
int fputc(int ch, FILE *f)
{      
	while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); 
    USART_SendData(USART1,(uint8_t)ch);   
	return ch;
}
#endif 

/*
//重定向c库函数printf到USART1,需要选择use MicroLIB
int fputc(int ch, FILE *f)
{
	USART_SendData(USART1, (uint8_t) ch);//发送一个字节数据到USART1
	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);//等待发送完毕
	return (ch);
}
*/

int SendChar (int ch)
{ 
  USART_SendData(USART1, (unsigned char) ch);
  while (!(USART1->SR & USART_FLAG_TXE));
  return (ch);
}

/*********************************************
整形数据转字符串函数
char *itoa(int value, char *string, int radix)
radix=10 标示是10进制	非十进制，转换结果为0;  
例：d=-379;
执行	itoa(d, buf, 10); 后
buf="-379"							   			  
**********************************************/
char *itoa(int value, char *string, int radix)
{
	int i, d;
	int flag = 0;
	char *ptr = string;

	if (radix != 10)
	{
		*ptr = 0;
		return string;
	}

	if (!value)
	{
		*ptr++ = 0x30;
		*ptr = 0;
		return string;
	}

	if (value < 0)
	{
		*ptr++ = '-';
		value *= -1;
	}

	for (i = 10000; i > 0; i /= 10)
	{
		d = value / i;

		if (d || flag)
		{
			*ptr++ = (char)(d + 0x30);
			value -= (d * i);
			flag = 1;
		}
	}

	*ptr = 0;
	return string;
}

/******************************************************
格式化串口输出函数
"\r"	回车符	   my_printf(USART1, "abcdefg\r")   
"\n"	换行符	   my_printf(USART1, "abcdefg\r\n")
"%s"	字符串	   my_printf(USART1, "字符串是：%s","abcdefg")
"%d"	十进制	   my_printf(USART1, "a=%d",10)
**********************************************************/
void my_printf(USART_TypeDef* USARTx, char *Data,...)
{ 
	const char *s;
	int d;
	char buf[16];
	va_list ap;
	va_start(ap, Data);

	while(*Data!=0)//判断是否到达字符串结束符
	{
		if(*Data==0x5c)//'\'
		{									 
			switch (*++Data)
			{
				case 'r'://回车符
					USART_SendData(USARTx, 0x0d);	   
					Data++;
					break;
				case 'n'://换行符
					USART_SendData(USARTx, 0x0a);	
					Data++;
					break;
				default:
					Data++;
				break;
			}
		}
		else if(*Data=='%')
		{
			switch (*++Data)
			{				
				case 's'://字符串
					s = va_arg(ap, const char *);
					for ( ; *s; s++) 
				  {
						USART_SendData(USARTx,*s);
						while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
					}
					Data++;
				break;
				case 'd'://十进制
					d = va_arg(ap,int);
					itoa(d, buf, 10);
					for (s = buf; *s; s++) 
					{
						USART_SendData(USARTx,*s);
						while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
					}
					Data++;
				break;
				default:
					Data++;
				break;
			}		 
		}
		else 
			USART_SendData(USARTx, *Data++);
		while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
	}
}

#if EN_USART1 == 1
void UART1_Init(u32 bound)//bound:波特率
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);//使能USART1，GPIOA时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA1

 	USART_DeInit(USART1);//复位串口1
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//PA.9 TX
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA9

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA.10 RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA10

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器
	
	//Enable DMA Channel4 Interrupt TX
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	//Enable DMA Channel5 Interrupt RX
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	//USART 参数初始化设置
	USART_InitStructure.USART_BaudRate = bound;//波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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_ITConfig(USART1, USART_IT_IDLE , ENABLE);	//开启空闲中断
	USART_Cmd(USART1, ENABLE);//使能串口 

	//DMA1 Channel4(串口1 TX)Config
	DMA_DeInit(DMA1_Channel4);	
	DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_DMA_Send_Buff;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
	DMA_InitStructure.DMA_BufferSize = USART1_SEND_LEN;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA工作模式DMA_Mode_Circular,DMA_Mode_Normal
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel4, &DMA_InitStructure);
	DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA1_Channel4, DMA_IT_TE, ENABLE);
	
	//Enable USART1 DMA TX request
	USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
	DMA_Cmd(DMA1_Channel4, DISABLE);//使能

	//DMA1 Channel5(串口1 RX)Config
	DMA_DeInit(DMA1_Channel5);	
	//DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;//DMA外设ADC基地址
	DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_DMA_Recv_Buff;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = USART1_RECV_LEN;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA工作模式DMA_Mode_Circular,DMA_Mode_Normal
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel5, &DMA_InitStructure);
	DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA1_Channel5, DMA_IT_TE, ENABLE);
	
	//Enable USART1 DMA RX request
	USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
	DMA_Cmd(DMA1_Channel5, ENABLE);	//使能
}

//串口1中断服务程序
void USART1_IRQHandler(void)	
{
	u16 data_len,i;
 	if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
	{
		DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
		data_len=USART1_RECV_LEN-DMA_GetCurrDataCounter(DMA1_Channel5); 
		if(data_len > 0)
		{
			USART1_ReceDatalen=data_len;
			for(i=0;i<data_len;i++)
			{
				USART1_Recv_Buff[i]=USART1_DMA_Recv_Buff[i];//将数据送缓冲区存储
				USART1_DMA_Send_Buff[i]=USART1_DMA_Recv_Buff[i];//将数据送DMA存储地址
			}
			USART1_Recv_Buff[i]='\0';
			USART1_Recv_Flag=1;
			
			//USART用DMA传输替代查询方式发送，克服被高优先级中断而产生丢帧现象。
			DMA_Cmd(DMA1_Channel4, DISABLE);//改变datasize前先要禁止通道工作
			DMA1_Channel4->CNDTR=data_len; //DMA1,传输数据量
			USART1_TX_Finish=0;//DMA传输开始标志量
			DMA_Cmd(DMA1_Channel4, ENABLE);			
		}
		DMA_ClearFlag(DMA1_FLAG_GL5 | DMA1_FLAG_TC5 | DMA1_FLAG_TE5 | DMA1_FLAG_HT5);//清标志
		DMA1_Channel5->CNDTR = USART1_RECV_LEN;//重装填
		DMA_Cmd(DMA1_Channel5, ENABLE);//处理完,重开DMA
		
		//读SR后读DR清除Idle
		i = USART1->SR;
		i = USART1->DR;
		//USART_ReceiveData(USART1);//读取数据 注意：这句必须要，否则不能够清除中断标志位
		
	}
	if(USART_GetITStatus(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出错
	{
		USART_ClearITPendingBit(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE);
	}
	//USART_ClearITPendingBit(USART1, USART_IT_TC);
	USART_ClearITPendingBit(USART1, USART_IT_IDLE);
}

//USART1使用DMA发数据中断服务程序
void DMA1_Channel4_IRQHandler(void)
{
	DMA_ClearITPendingBit(DMA1_IT_TC4);
	DMA_ClearITPendingBit(DMA1_IT_TE4);
	DMA_Cmd(DMA1_Channel4, DISABLE);//关闭DMA
	USART1_TX_Finish=1;//置DMA传输完成
}

void DMA1_Channel5_IRQHandler(void)
{
	DMA_ClearITPendingBit(DMA1_IT_TC5);
	DMA_ClearITPendingBit(DMA1_IT_TE5);
	DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
	DMA1_Channel5->CNDTR = USART1_RECV_LEN;//重装填
	DMA_Cmd(DMA1_Channel5, ENABLE);//处理完,重开DMA
}

void USART1_SendByte(unsigned char c)//串口1发送一个字符
{
	USART_SendData(USART1, c);
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );
}

void USART1_SendStr(char * str)//串口1发送字符串
{
	while(*str)
	{
		USART_SendData(USART1, *str++);
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
	}
}

//串口1DMA发送程序
void USART1_DMA_SendStr(char *senddata)	
{ 
	u16 data_len,i;
	
	//sizeof(lenbuff)//计算数组大小
	//strlen(lenbuff)//计算指针指向数组大小

	data_len=strlen(senddata); 
	if(data_len > 0)
	{			
		for(i=0;i<data_len;i++)
		{
			USART1_DMA_Send_Buff[i]=*senddata;//将数据送DMA存储地址
			senddata++;
		}
		//USART用DMA传输替代查询方式发送，克服被高优先级中断而产生丢帧现象。
		DMA_Cmd(DMA1_Channel4, DISABLE);//改变datasize前先要禁止通道工作
		DMA1_Channel4->CNDTR=data_len; //DMA1,传输数据量
		USART1_TX_Finish=0;//DMA传输开始标志量
		DMA_Cmd(DMA1_Channel4, ENABLE);			
	}
} 
#endif

#if EN_USART2 == 1
//初始化IO 串口2 
void UART2_Init(u32 bound)//bound:波特率
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA1

	USART_DeInit(USART2);//复位串口2
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//PA2 TX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3 RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);	

	RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);//复位串口2
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);//停止复位
	
	USART_InitStructure.USART_BaudRate = bound;//波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据长度
	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;//收发模式

	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//使能串口2中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//先占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//从优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
	NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
	
	//Enable DMA Channel7 Interrupt 
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	//Enable DMA Channel6 Interrupt 
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
 
	USART_Init(USART2, &USART_InitStructure);//初始化串口2
	//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
	USART_ITConfig(USART2, USART_IT_IDLE , ENABLE);	//开启空闲中断
	USART_Cmd(USART2, ENABLE);//使能串口 

	//DMA1 Channel7(串口2 TX)Config
	DMA_DeInit(DMA1_Channel7);	
	DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_Send_Buff;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
	DMA_InitStructure.DMA_BufferSize = USART2_SEND_LEN;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA工作模式DMA_Mode_Circular,DMA_Mode_Normal
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel7, &DMA_InitStructure);
	DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA1_Channel7, DMA_IT_TE, ENABLE);
	
	//Enable USART2 DMA TX request
	USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
	DMA_Cmd(DMA1_Channel7, DISABLE);//使能

	//DMA1 Channel6(串口2 RX)Config
	DMA_DeInit(DMA1_Channel6);	
	DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_Recv_Buff;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = USART2_RECV_LEN;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA工作模式DMA_Mode_Circular,DMA_Mode_Normal
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel6, &DMA_InitStructure);
	DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA1_Channel6, DMA_IT_TE, ENABLE);
	
	//Enable USART2 DMA RX request
	USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
	DMA_Cmd(DMA1_Channel6, ENABLE);//使能
}

//串口2中断服务程序
void USART2_IRQHandler(void)	
{ 
	u16 data_len,i;
 	if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
	{
		DMA_Cmd(DMA1_Channel6, DISABLE);//关闭DMA,防止处理其间有数据
		data_len=USART2_RECV_LEN-DMA_GetCurrDataCounter(DMA1_Channel6); 
		if(data_len > 0)
		{			
			for(i=0;i<data_len;i++)
			{
				USART2_Recv_Buff[i]=USART2_DMA_Recv_Buff[i];//将数据送缓冲区存储
				//USART2_DMA_Send_Buff[i]=USART2_DMA_Recv_Buff[i];//将数据送DMA存储地址
			}
			USART2_Recv_Buff[i]='\0';
			USART2_Recv_Flag=1;
			//esp8266不用，否则会形成回环，esp8266会死机
			//DMA_Cmd(DMA1_Channel7, DISABLE); //改变datasize前先要禁止通道工作
			//DMA1_Channel7->CNDTR=data_len; //DMA1,传输数据量
			//USART2_TX_Finish=0;//DMA传输开始标志量
			//DMA_Cmd(DMA1_Channel7, ENABLE);			
		}
		DMA_ClearFlag(DMA1_FLAG_GL6 | DMA1_FLAG_TC6 | DMA1_FLAG_TE6 | DMA1_FLAG_HT6);//清标志
		DMA1_Channel6->CNDTR = USART2_RECV_LEN;//重装填
		DMA_Cmd(DMA1_Channel6, ENABLE);//处理完,重开DMA
		//读SR后读DR清除Idle
		i = USART2->SR;
		i = USART2->DR;
	}
	if(USART_GetITStatus(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出错
	{
		USART_ClearITPendingBit(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE);
	}
	USART_ClearITPendingBit(USART2, USART_IT_IDLE);
}

//USART2使用DMA发数据中断服务程序
void DMA1_Channel7_IRQHandler(void)
{	 
	DMA_ClearITPendingBit(DMA1_IT_TC7);
	DMA_ClearITPendingBit(DMA1_IT_TE7);
	DMA_Cmd(DMA1_Channel7, DISABLE);//关闭DMA
	USART2_TX_Finish=1;//置DMA传输完成
}

void DMA1_Channel6_IRQHandler(void)
{
	DMA_ClearITPendingBit(DMA1_IT_TC6);
	DMA_ClearITPendingBit(DMA1_IT_TE6);
	DMA_Cmd(DMA1_Channel6, DISABLE);//关闭DMA,防止处理其间有数据
	DMA1_Channel6->CNDTR = USART2_RECV_LEN;//重装填
	DMA_Cmd(DMA1_Channel6, ENABLE);//处理完,重开DMA
}

void USART2_SendByte(unsigned char c)//串口2发送一个字符
{
	USART_SendData(USART2, c);
	while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET );
}

void USART2_SendStr(char * str)//串口2发送字符串
{
	while(*str)
	{
		USART_SendData(USART2, *str++);
		while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
	}
}

//串口2DMA发送程序
void USART2_DMA_SendStr(char *senddata)	
{ 
	u16 data_len,i;
	data_len=strlen(senddata); 
	if(data_len > 0)
	{			
		for(i=0;i<data_len;i++)
		{
			USART2_DMA_Send_Buff[i]=*senddata;//将数据送DMA存储地址
			senddata++;
		}
		DMA_Cmd(DMA1_Channel7, DISABLE);//改变datasize前先要禁止通道工作
		DMA1_Channel7->CNDTR=data_len;//DMA1,传输数据量
		USART2_TX_Finish=0;//DMA传输开始标志量
		DMA_Cmd(DMA1_Channel7, ENABLE);			
	}
}		
#endif

#if EN_USART3 == 1
//初始化IO 串口3
void UART3_Init(u32 bound)//bound:波特率
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能GPIOB时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//DMA1

 	USART_DeInit(USART3);//复位串口3
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PB.10 TX
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化PB.10
	 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PB.11 RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化PB.11

	//USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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;//收发模式
	
	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器

	//Enable DMA Channel2 Interrupt
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	//Enable DMA Channel3 Interrupt
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	USART_Init(USART3, &USART_InitStructure);//初始化串口
	//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断
	USART_ITConfig(USART3, USART_IT_IDLE , ENABLE);//开启空闲中断
	USART_Cmd(USART3, ENABLE);//使能串口
	
	//DMA1 Channel2(串口3 TX)Config
	DMA_DeInit(DMA1_Channel2);	
	DMA_InitStructure.DMA_PeripheralBaseAddr =0x4004804;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART3_DMA_Send_Buff;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
	DMA_InitStructure.DMA_BufferSize = USART3_SEND_LEN;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//DMA工作模式DMA_Mode_Circular,DMA_Mode_Normal
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel2, &DMA_InitStructure);
	DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA1_Channel2, DMA_IT_TE, ENABLE);
	
	//Enable USART3 DMA TX request
	USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
	DMA_Cmd(DMA1_Channel2, DISABLE);//使能

	//DMA1 Channel3(串口3 RX)Config
	DMA_DeInit(DMA1_Channel3);	
	DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004804;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART3_DMA_Recv_Buff;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = USART3_REC_LEN;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA工作模式DMA_Mode_Circular,DMA_Mode_Normal
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel3, &DMA_InitStructure);
	DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA1_Channel3, DMA_IT_TE, ENABLE);
	
	//Enable USART3 DMA RX request
	USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
	DMA_Cmd(DMA1_Channel3, ENABLE);//使能
}

//串口3中断服务程序
void USART3_IRQHandler(void)	
{
	u16 data_len,i;
 	if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)
	{	
		DMA_Cmd(DMA1_Channel3, DISABLE);//关闭DMA,防止处理其间有数据
		data_len=USART3_REC_LEN-DMA_GetCurrDataCounter(DMA1_Channel3); 
		if(data_len > 0)
		{			
			for(i=0;i<data_len;i++)
			{
				USART3_RX_BUF[i]=USART3_DMA_Recv_Buff[i];//将数据送缓冲区存储
				USART3_DMA_Send_Buff[i]=USART3_DMA_Recv_Buff[i];//将数据送DMA存储地址
			}
			USART3_RX_BUF[i]='\0';
			USART3_Flag=1;
			
			DMA_Cmd(DMA1_Channel2, DISABLE);//改变datasize前先要禁止通道工作
			DMA1_Channel2->CNDTR=data_len;//DMA1,传输数据量
			USART3_TX_Finish=0;//DMA传输开始标志量
			DMA_Cmd(DMA1_Channel2, ENABLE);
			LED0=!LED0;			
		}
		DMA_ClearFlag(DMA1_FLAG_GL3 | DMA1_FLAG_TC3 | DMA1_FLAG_TE3 | DMA1_FLAG_HT3);//清标志
		DMA1_Channel6->CNDTR = USART3_REC_LEN;//重装填
		DMA_Cmd(DMA1_Channel3, ENABLE);//处理完,重开DMA
		//读SR后读DR清除Idle
		i = USART3->SR;
		i = USART3->DR;
	}
	if(USART_GetITStatus(USART3, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出错
	{
		USART_ClearITPendingBit(USART3, USART_IT_PE | USART_IT_FE | USART_IT_NE);
	}
	USART_ClearITPendingBit(USART3, USART_IT_IDLE);
}

//USART3使用DMA发数据中断服务程序
void DMA1_Channel2_IRQHandler(void)
{	 
	DMA_ClearITPendingBit(DMA1_IT_TC2);
	DMA_ClearITPendingBit(DMA1_IT_TE2);
	DMA_Cmd(DMA1_Channel2, DISABLE);//关闭DMA
	USART3_TX_Finish=1;//置DMA传输完成
}

void DMA1_Channel3_IRQHandler(void)
{
	DMA_ClearITPendingBit(DMA1_IT_TC3);
	DMA_ClearITPendingBit(DMA1_IT_TE3);
	DMA_Cmd(DMA1_Channel3, DISABLE);//关闭DMA,防止处理其间有数据
	DMA1_Channel3->CNDTR = USART3_REC_LEN;//重装填
	DMA_Cmd(DMA1_Channel3, ENABLE);//处理完,重开DMA
}

void USART3_SendByte(unsigned char c)//串口3发送一个字符
{
	USART_SendData(USART3, c);
	while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET );
}

void USART3_SendStr(char * str)//串口3发送字符串
{
	while(*str)
	{
		USART_SendData(USART3, *str++);
		while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
	}
}

//串口3DMA发送程序
void USART3_DMA_SendStr(char *senddata)	
{ 
	u16 data_len,i;
	data_len=strlen(senddata); 
	if(data_len > 0)
	{			
		for(i=0;i<data_len;i++)
		{
			USART3_DMA_Send_Buff[i]=*senddata;//将数据送DMA存储地址
			senddata++;
		}
		DMA_Cmd(DMA1_Channel2, DISABLE);//改变datasize前先要禁止通道工作
		DMA1_Channel2->CNDTR=data_len;//DMA1,传输数据量
		USART3_TX_Finish=0;//DMA传输开始标志量
		DMA_Cmd(DMA1_Channel2, ENABLE);			
	}
}	
#endif
