我们主要要介绍的文件的在USB_User这个组文件。从上面的截图可以看到USB_User这个文件由hw_config.c、usb_desc.c、usb_endp.c、usb_istr.c、usb_prop.c、usb_pwr.c几个文件组成。其中usb_istr.c和usb_pwr.c整两个文件不用修改,其他的文件都需要修改。下面接慢慢将来。uint8_t USART_Rx_Buffer [USART_RX_DATA_SIZE]; //串口接收缓冲
uint32_t USART_Rx_ptr_in = 0;			//这里采用的是一个环形缓冲,串口数据输入起始位置
uint32_t USART_Rx_ptr_out = 0;			//环形缓冲的数据结束位置
uint32_t USART_Rx_length  = 0;			//接收数据的长度
uint8_t  USB_Tx_State = 0;			//USB发送标志,当串口缓冲有数据没有发送,该位置1
其中USART_Rx_ptr_in指向的就是图中read position处,USART_Rx_ptr_out指向write position处, USART_Rx_length就是数据的长度,就是图中橙色的圆弧。当没有数据的时候,USART_Rx_ptr_in=USART_Rx_ptr_out,有数据收到的时候USART_Rx_ptr_in就向后偏移,当数据被读出去的时候USART_Rx_ptr_out也会向后偏移。/*******************************************************************************
* Function Name  :  USART_Config_Default.
* Description    :  串口的默认配置值
* Input          :  None.
* Return         :  None.
*******************************************************************************/
void USART_Config_Default(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	/* 使能 UART2 时钟 */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	/* 配置 USART2 的Tx 引脚类型为推挽式的 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	/* 配置 USART2 的Rx 为输入悬空 */
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);
	/* 串口默认配置*/
	/* 串口配置值如下:
	    - 波特率 = 9600 baud  
	    - 数据长度 = 8 Bits
	    - 1位停止位
	    - 奇校验
	    - 不使能硬件流控制
	    - 接收传输使能
	*/
	USART_InitStructure.USART_BaudRate = 9600;											//波特率9600
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;	//8位数据位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;		//1位停止位
	USART_InitStructure.USART_Parity = USART_Parity_Odd;		//奇校验
	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//没有数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//接收、发送使能	
	USART_Init(USART2, &USART_InitStructure);	//配置串口	
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);	//使能串口接收中断
	USART_Cmd(USART2,ENABLE);			//串口使能
}
/*******************************************************************************
* Function Name  :  USART_Config.
* Description    :  根据line coding 结构体配置串口.
* Input          :  None.
* Return         :  配置状态
                    TRUE : 配置成功
                    FALSE: 配置中断
*******************************************************************************/
bool USART_Config(void)
{
  /*设置停止位*/
	switch (linecoding.format)
	{
		case 0:
			USART_InitStructure.USART_StopBits = USART_StopBits_1;	  //1位停止位
			break;
		case 1:
			USART_InitStructure.USART_StopBits = USART_StopBits_1_5;  //1.5为停止位
			break;
		case 2:
			USART_InitStructure.USART_StopBits = USART_StopBits_2;	  //2位停止位
			break;
		default :
		{
			USART_Config_Default();			//默认配置
			return (FALSE);
		}
	}
	/* 设置校验位*/
	switch (linecoding.paritytype)
	{
		case 0:
			USART_InitStructure.USART_Parity = USART_Parity_No;	//没有校验
			break;;
		case 1:
			USART_InitStructure.USART_Parity = USART_Parity_Even;	 //偶校验
			break;
		case 2:
			USART_InitStructure.USART_Parity = USART_Parity_Odd;	 //奇校验
			break;
		default :
		{
			USART_Config_Default();				 //默认配置
			return (FALSE);
		}
	}
	/*设置数据位: 8位或9位*/
	switch (linecoding.datatype)
	{
		case 0x07:
			USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8为数据位,这个选项就校验位必须设置(奇校验/偶校验)
			break;
		case 0x08:
			if (USART_InitStructure.USART_Parity == USART_Parity_No)//没有设置校验位时
			{
			      USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据位
			}
			else 
			{
			      USART_InitStructure.USART_WordLength = USART_WordLength_9b;//9位数据位
			}			
			break