#include "USART.h"

// int fputc(int ch, FILE *f)
//{
//	RS485_4_TX_EN=1;
//	USART_SendData(USART2, (uint8_t) ch);
//	while((USART2->SR&0X40)==0);//循环发送,直到发送完毕
//	RS485_4_TX_EN=0;
//	return ch;
// }

int fputc(int ch, FILE *p) // 函数默认的，在使用printf函数时自动调用
{
	RS485_4_TX_EN = 1;
	USART_SendData(USART2, (u8)ch);
	while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
		;
	RS485_4_TX_EN = 0;
	return ch;
}

// 串口1中断服务程序
// 注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART2_RX_BUF[USART2_REC_LEN]; // 接收缓冲,最大USART_REC_LEN个字节.
// 接收状态
// bit15，	接收完成标志
// bit14，	接收到0x0d
// bit13~0，	接收到的有效字节数目
u16 USART2_RX_STA = 0; // 接收状态标记

void USART2_Init(u32 bound)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);						 // 使能USART1，GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA, ENABLE); // 使能USART1，GPIOA时钟

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // RE485-DE  PA8
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
	GPIO_Init(GPIOB, &GPIO_InitStructure);			 // 初始化

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // USART1_TX   PA9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);			// 初始化

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;				  // USART1_RX	  PA10初始化
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	  // 浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);					  // 初始化
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;		  // Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4; // 抢占优先级3
	// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);					// 根据指定的参数初始化VIC寄存器

	// 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(USART2, &USART_InitStructure);	   // 初始化串口1
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 开启串口接受中断
	USART_Cmd(USART2, ENABLE);					   // 使能串口1
	RS485_4_TX_EN = 0;							   // 拉低
}

// void USART2_IRQHandler(void)                	//串口1中断服务程序
//{
//	u8 Res;
//	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断
//	{
//		USART_ClearFlag(USART2, USART_IT_RXNE); //清除标志位；
//		Res =USART_ReceiveData(USART2);	//读取接收到的数据
//	  	/*写入要执行的操作*/
//	}

//}

///*******************************************************************************
//* 函 数 名         : USART1_Init
//* 函数功能		   : USART1初始化函数
//* 输    入         : bound:波特率
//* 输    出         : 无
//*******************************************************************************/
// void USART2_Init(u32 bound)
//{
//   //GPIO端口设置
//	GPIO_InitTypeDef GPIO_InitStructure;
//	USART_InitTypeDef USART_InitStructure;
//	NVIC_InitTypeDef NVIC_InitStructure;
//
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
//
//
//	/*  配置GPIO的模式和IO口 */
//	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;//TX			   //串口输出PA9
//	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;	    //复用推挽输出
//	GPIO_Init(GPIOA,&GPIO_InitStructure);  /* 初始化串口输入IO */
//	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;//RX			 //串口输入PA10
//	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;		  //模拟输入
//	GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化GPIO */
//

//	//USART1 初始化设置
//	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(USART2, &USART_InitStructure); //初始化串口1
//
//	USART_Cmd(USART2, ENABLE);  //使能串口1
//
//	USART_ClearFlag(USART2, USART_FLAG_TC);
//
//	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启相关中断

//	//Usart1 NVIC 配置
//	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//串口1中断通道
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级3
//	//NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级3
//	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
//	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器、
//}

/*******************************************************************************
 * 函 数 名         : USART1_IRQHandler
 * 函数功能		   : USART1中断函数
 * 输    入         : 无
 * 输    出         : 无
 *******************************************************************************/
void USART2_IRQHandler(void) // 串口1中断服务程序
{
	u8 r;
	if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) // 接收中断
	{
		r = USART_ReceiveData(USART2);	   //(USART1->DR);	//读取接收到的数据
		if ((USART2_RX_STA & 0x8000) == 0) // 接收未完成
		{
			if (USART2_RX_STA & 0x4000) // 接收到了0x0d
			{
				if (r != 0x0a)
					USART2_RX_STA = 0; // 接收错误,重新开始
				else
					USART2_RX_STA |= 0x8000; // 接收完成了
			}
			else // 还没收到0X0D
			{
				if (r == 0x0d)
					USART2_RX_STA |= 0x4000;
				else
				{
					USART2_RX_BUF[USART2_RX_STA & 0X3FFF] = r;
					USART2_RX_STA++;
					if (USART2_RX_STA > (USART2_REC_LEN - 1))
						USART2_RX_STA = 0; // 接收数据错误,重新开始接收
				}
			}
		}
	}
}
