www.pudn.com > D12Driver.rar > D12Driver.c


/****************************************Copyright (c)***************************** 
*                               广州周立功单片机发展有限公司 
*                                     研    究    所 
*                                        产品一部  
* 
*                                 http://www.zlgmcu.com 
* 
* 文   件   名: D12Driver.c 
* 最后修改日期: 2006年03月27日 
* 描        述: USB驱动程序软件包: PDIUSBD12 设备端驱动程序 驱动层 
* 版	     本:  
************************************************************************************/ 
 
#include  
#include"intrins.h" 
#include"GENERAL.h" 
#include"AGREEMENT.h" 
#include"D12DRIVER.h" 
#include"RS485Driver.h" 
 
INT8U idata GenEpBuf[EP1_PACKET_SIZE];			// 端点1接收缓冲区 
INT8U idata EpBuf[EP2_PACKET_SIZE];				// 端点2接收缓冲区 
 
 
 
 
extern EPPFLAGS idata bEPPflags;				// 引用USB事件标志变量 
 
 
extern CONTROL_XFER idata ControlData;			// 引用控制传输结构变量 
 
extern INT8U idata Len_ep1Buffer;				// 引用端点1接收数据长度 
extern INT8U idata Len_ep2Buffer;				// 引用端点2接收数据长度 
 
//-------------------------------------------------------- 
// 函数名称: void Init_D12Port(void) 
// 功能描述: 初始化D12与MCU的连接端口 
//-------------------------------------------------------- 
void Init_D12Port(void) 
{ 
	MCU_D12CS = 1;								// 释放D12 
	MCU_D12CS = 0;								// 选择D12 
	_nop_(); 
} 
 
//-------------------------------------------------------- 
// 函数名称: void Rst_D12(void) 
// 功能描述: 复位D12 
//-------------------------------------------------------- 
void Rst_D12(void) 
{ 
	INT16U i; 
	 
	MCU_D12RST = 0;							// D12的 RESET引脚置0 
	for(i = 0; i < 0x100; i++);				// 软件延时 
	{ 
		MCU_D12RST = 1;						// D12的 RESET引脚置1 
	} 
	MCU_D12SUSPD = 0;						// D12的 SUSPEND引脚置0 
} 
 
 
//-------------------------------------------------------- 
// 函数名称: outportb() 
// 功能描述: 向D12写入数据 
// 输   入: INT16U Addr:	命令地址或数据地址 
//			 INT8U Data:    命令字节 
// 输   出: 无 
//-------------------------------------------------------- 
void outportb(INT8U Addr, INT8U Data) 
{ 
	MCU_D12RD = 1; 
	MCU_D12WR = 0; 
 
	if(Addr) 
	{ 
		MCU_D12A0 = 1;		 
		P0 = Data;		 
    } 
	else 
	{ 
		MCU_D12A0 = 0; 
		P0 = Data; 
	} 
	MCU_D12WR = 1; 
} 
 
//-------------------------------------------------------- 
// 函数名称: inportd() 
// 功能描述: 读入数据 
// 输   入: INT16U Addr:	数据地址 
// 输   出: 读到的数据 
//-------------------------------------------------------- 
INT8U inportb(void) 
{	 
	INT8U DAT_TEMP; 
	MCU_D12WR = 1; 
	MCU_D12A0 = 0; 
	P0 = 0xFF; 
	MCU_D12RD = 0; 
	_nop_(); 
	DAT_TEMP = P0; 
	_nop_(); 
	MCU_D12RD = 1; 
	return (DAT_TEMP); 
} 
 
//-------------------------------------------------------- 
// 函数名称: connect_USB() 
// 功能描述: 连接USB总线 
//-------------------------------------------------------- 
void connect_USB(void)  //SoftConnect 连接上,并设置为无LazyClock,模式为非同步模式 
{ 
	D12_SetDMA(0x00); 
	D12_SetMode(D12_NOLAZYCLOCK|D12_SOFTCONNECT, D12_SETTOONE | D12_CLOCK_12M); 
}			 
 
 
//-------------------------------------------------------- 
// 函数名称: disconnect_USB()  
// 功能描述: 断开USB总线 
//-------------------------------------------------------- 
void disconnect_USB(void)  //SoftConnect 断开 
{ 
	D12_SetMode(D12_NOLAZYCLOCK, D12_SETTOONE | D12_CLOCK_12M); 
}	 
 
//-------------------------------------------------------- 
// 函数名称: reconnect_USB() 
// 功能描述: 重新连接USB总线 
//-------------------------------------------------------- 
void reconnect_USB(void) 
{ 
	INT16U clk_cnt; 
 
	disconnect_USB();							  	// 断开芯片与USB总线连接 
 
    for (clk_cnt = 0;clk_cnt<= 0x9000;clk_cnt++);	// 延时处理 
	{ 
    	connect_USB();								// 连接到USB总线 
	} 
} 
 
 
//-------------------------------------------------------- 
// 函数名称: D12_ReadChipID() 
// 功能描述: 读取芯片ID 
// 输   入: 无 
// 输   出: 芯片的ID号 
//-------------------------------------------------------- 
INT16U D12_ReadChipID(void) 
{ 
	INT16U i,j; 
 
	if(bEPPflags.bits.in_isr == 0) 
 	{ 
		DISABLE(); 
	}  
	outportb(D12_COMMAND, 0xFD);		// 发送读PDIUSBD12芯片ID号命令	 
	_nop_(); 
	i=inportb();			    		// 读取ID号低字节 
	_nop_(); 
	j=inportb();						// 读取ID号高位字节 
	i += (j<<8);						// 组成16位的PDIUSBD12芯片ID号 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE(); 
	} 
	return i; 
} 
//-------------------------------------------------------- 
// 函数名称: Init_D12() 
// 功能描述: 设置D12与硬件的连接, 初始化D12, 复位D12 
// 输   入: 无 
// 输   出: 0: 初始化成功    1: 初始化失败   
//-------------------------------------------------------- 
INT8U Init_D12(void) 
{ 
 
	bEPPflags.value = 0;					// 初始化USB事件标志变量 
	Init_D12Port();							// 初始化PDIUSBD12与51单片机连接的端口 
	Rst_D12();								// 复位PDIUSBD12 
	reconnect_USB();        				// 重新连接USB 
	if (D12_ReadChipID() != 0x1012)			// 读取芯片ID号,如果不为1012H 
	{ 
		return 1;							// 则复位失败 
	} 
 	return 0;								// 初始化成功 
} 
//-------------------------------------------------------- 
// 函数名称: d12_busreset() 
// 功能描述: USB总线复位处理函数 
// 输	 入: 无 
// 输	 出: 无 
//-------------------------------------------------------- 
void d12_busreset(void) 
{ 
	//在此添加总线复位处理代码 
} 
 
//-------------------------------------------------------- 
// 函数名称: dma_eot() 
// 功能描述: DMA结束处理函数 
// 输	 入: 无 
// 输	 出: 无 
//-------------------------------------------------------- 
void dma_eot(void) 
{ 
	//在此添加DMA结束处理代码 
} 
 
//-------------------------------------------------------- 
// 函数名称: d12_suspend() 
// 功能描述: 总线挂起改变处理函数 
// 输	 入: 无 
// 输	 出: 无 
//-------------------------------------------------------- 
void d12_suspend(void) 
{ 
	//在此添加总线挂起改变代码 
} 
 
 
//-------------------------------------------------------- 
// 函数名称: usbserve() 
// 功能描述: USB事件处理函数 
// 输	 入: 无 
// 输	 出: 无 
//-------------------------------------------------------- 
void usbserve(void) 
{ 
	if(bEPPflags.bits.setup_packet) 
	{											// Setup包处理 
		DISABLE(); 
		bEPPflags.bits.setup_packet = 0; 
		control_handler();						// 调用请求处理子程序 
		ENABLE(); 
	} 
 
	if (bEPPflags.bits.bus_reset) 
	{											// USB总线复位处理 
		DISABLE(); 
		bEPPflags.bits.bus_reset = 0; 
		ENABLE(); 
		d12_busreset();    						//有待处理 
	}  
 
	if (bEPPflags.bits.suspend) 
	{											// D12挂起改变处理 
		DISABLE(); 
		bEPPflags.bits.suspend= 0; 
		ENABLE(); 
		d12_suspend();     						//有待处理 
	}	 
 
	//在此添加其它usb事件处理代码 
} 
 
//-------------------------------------------------------- 
// 函数名称: D12_SetAddressEnable() 
// 功能描述: 设置地址/使能 
// 输   入: INT8U bAddress:  地址 
//	     	 INT8U bEnable :  0 --- 禁止 
//	     		     		  1 --- 使能 
// 输   出: 无 
//-------------------------------------------------------- 
void D12_SetAddressEnable(INT8U bAddress, INT8U bEnable) 
{ 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		DISABLE(); 
	} 
	outportb(D12_COMMAND, 0xD0);		// 输出设置地址/使能指令 
	if(bEnable) 
	{ 
		bAddress |= 0x80;				// bit7置1,使能 
	} 
	outportb(D12_DATA, bAddress);		// 输出设置值 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE(); 
	} 
} 
 
 
//-------------------------------------------------------- 
// 函数名称: D12_SetEndpointEnable() 
// 功能描述: 设置端点使能 
// 输   入: INT8U bEnable :  0 --- 禁止 
//	     		     		  1 --- 允许 
// 输   出: 无 
//-------------------------------------------------------- 
void D12_SetEndpointEnable(INT8U bEnable) 
{ 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		DISABLE(); 
	} 
	outportb(D12_COMMAND, 0xD8);		// 输出设置端点使能指令 
	if(bEnable) 
	{ 
		outportb(D12_DATA, 1);			// 设置端点允许 
	} 
	else 
	{ 
		outportb(D12_DATA, 0);			// 设置端点禁止 
	}	 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE(); 
	} 
} 
 
//-------------------------------------------------------- 
// 函数名称: void D12_SetMode() 
// 功能描述: 模式设置 
// 输   入: INT8U bConfig:  配置字节信息 
//	     	 INT8U bClkDiv:  分频系数 
// 输   出: 无 
//-------------------------------------------------------- 
void D12_SetMode(INT8U bConfig,INT8U bClkDiv) 
{ 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		DISABLE(); 
	} 
	outportb(D12_COMMAND, 0xF3);		// 输出设置模式指令 
	outportb(D12_DATA, bConfig);		// 输出配置字节信息 
	outportb(D12_DATA, bClkDiv);		// 输出时钟分频因数字节 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE();	 
	} 
} 
 
//-------------------------------------------------------- 
// 函数名称: void D12_SetDMA() 
// 功能描述: 设置DMA工作方式设置 
// 输   入: INT8U bMode: 	设置值 
// 输   出: 无 
//-------------------------------------------------------- 
void D12_SetDMA(INT8U bMode) 
{ 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		DISABLE(); 
	} 
	outportb(D12_COMMAND, 0xFB);			// 设置DMA工作方命令 
	outportb(D12_DATA, bMode);				// 输出设置值 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE();			 
	} 
} 
 
//-------------------------------------------------------- 
// 函数名称: D12_ReadInterruptRegister() 
// 功能描述: 读取中断寄存器值 
// 输   入: 无 
// 输   出: 中断寄存器值 
//-------------------------------------------------------- 
INT16U D12_ReadInterruptRegister(void) 
{ 
	INT8U b1; 
	INT16U j; 
 
	outportb(D12_COMMAND, 0xF4);			// 读取中断寄存器命令 
	b1 = inportb();			    			// 读取低8位字节 
	j = inportb();							// 读取高8位字节 
 
	j <<= 8; 
	j += b1;								// 组合为16位 
 
	return j; 
} 
 
//-------------------------------------------------------- 
// 函数名称: D12_SelectEndpoint() 
// 功能描述: 端点选择,将内部指针初始化到选择的缓冲区起始位置 
// 输   入: INT8U bEndp:   端点索引号,取值0 ~ 5 
// 输   出: 读出的字节 
//-------------------------------------------------------- 
INT8U D12_SelectEndpoint(INT8U bEndp) 
{ 
	INT8U c; 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		DISABLE(); 
	} 
	outportb(D12_COMMAND, bEndp);			// 端点选择 
	c = inportb();							// 读出一个字节 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE(); 
	} 
	return c; 
} 
 
//-------------------------------------------------------- 
// 函数名称: D12_ReadEndpointStatus() 
// 功能描述: 读取端点状态 
// 输   入: INT8U bEndp:   端点索引号,取值0 ~ 5 
// 输   出: 端点状态 
//-------------------------------------------------------- 
 
INT8U D12_ReadEndpointStatus(INT8U bEndp) 
{ 
	INT8U c; 
 
	if(bEPPflags.bits.in_isr == 0) 
		DISABLE(); 
 
	outportb(D12_COMMAND, 0x80 + bEndp);	// 读取端点状态命令 
	c = inportb();							// 读取端点状态 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE(); 
	} 
	return c; 
} 
 
 
//-------------------------------------------------------- 
// 函数名称: D12_ReadLastTransactionStatus() 
// 功能描述: 读取最后处理状态寄存器 
// 输   入: INT8U bEndp:   端点索引号,取值0 ~ 5 
// 输   出: 端点最后处理的状态 
//-------------------------------------------------------- 
INT8U D12_ReadLastTransactionStatus(INT8U bEndp) 
{ 
	outportb(D12_COMMAND, 0x40 + bEndp);		// 输出读取最后处理状态寄存器命令 
	return inportb();							// 读取状态 
} 
 
//-------------------------------------------------------- 
// 函数名称: D12_SetEndpointStatus() 
// 功能描述: 设置端点状态 
// 输   入: INT8U bEndp:   端点索引号,取值0 ~ 5 
//	         INT8U bStalled: 状态值 
// 输   出: 端点状态 
//-------------------------------------------------------- 
void D12_SetEndpointStatus(INT8U bEndp,INT8U bStalled) 
{ 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		DISABLE(); 
	} 
	outportb(D12_COMMAND, 0x40 + bEndp);		// 发送设置端点状态命令 
	outportb(D12_DATA, bStalled);				// 设置端点状态 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE(); 
	} 
} 
 
//-------------------------------------------------------- 
// 函数名称: D12_SendResume() 
// 功能描述: 传输恢复 
//-------------------------------------------------------- 
 
/*void D12_SendResume(void) 
{ 
	outportb(D12_COMMAND, 0xF6);				// 设置发送恢复 
} 
 
*/ 
 
/************************************************************ 
** 函数名称: D12_ReadCurrentFrameNumber() 
** 功能描述: 读取当前帧号 
** 输   入: 无 
** 输   出: 当前帧号 
************************************************************/ 
 
/*INT16U D12_ReadCurrentFrameNumber(void) 
{ 
	INT16U i,j; 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		DISABLE(); 
	} 
	outportb(D12_COMMAND, 0xF5);			//发送读取当前帧数目命令 
	i= inportb();					//读取帧数目的低8位 
	j = inportb();					//读取帧数目的高8位 
 
	i += (j<<8); 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE(); 
	} 
	return i;								//返目当前帧数目 
} 
 
*/ 
 
//-------------------------------------------------------- 
// 函数名称: D12_ReadEndpoint() 
// 功能描述: 读取端点数据 
// 输   入: INT8U endp:     端点索引号,取值 0 ~ 5  
//	    	 INT8U len:	     要读取的数据长度 
//	     	 INT8U * buf:    接收数据指针 
// 输   出: 实际读得的字节数 
//-------------------------------------------------------- 
INT8U D12_ReadEndpoint(INT8U endp,INT8U len,INT8U * buf) 
{ 
	INT8U i, j; 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		DISABLE(); 
	} 
	outportb(D12_COMMAND, endp);						// 发送选择端点命令 
	if((inportb() & D12_FULLEMPTY) == 0)  
	{													// 如果缓冲区为空 
		if(bEPPflags.bits.in_isr == 0) 
		{ 
			ENABLE(); 
		} 
		return 0;										// 则返回读到0字节 
	} 
 
	outportb(D12_COMMAND, 0xF0);						// 发送读缓冲区命令 
	j = inportb();										// 读取保留字节 
	j = inportb();										// 读取数据字节的数目/长度 
	 
	if(j > len)											// 如果大于要求读的字节数目 
	{ 
		j = len;										// 则只读取要求的字节长度 
	}	 
	for(i=0; i= 4) 
	{ 
   		outportb(D12_COMMAND,0xF2);						// 清空第2个缓冲区	 
	} 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		ENABLE(); 
	} 
	return j;											// 返回读到的字节数 
} 
 
//-------------------------------------------------------- 
// 函数名称: D12_WriteEndpoint() 
// 功能描述: 把数据写入端点 
// 输   入: INT8U endp:     端点索引号,取值 0 ~ 5  
//	     	 INT8U len:	     要写入的数据长度 
//	     	 INT8U * buf:    发送数据指针 
// 输   出: 实际写入的字节数 
//-------------------------------------------------------- 
INT8U D12_WriteEndpoint(INT8U endp, INT8U len,INT8U * buf) 
{ 
	INT8U i; 
 
	if(bEPPflags.bits.in_isr == 0) 
	{ 
		DISABLE(); 
	} 
	outportb(D12_COMMAND, endp);				// 发送选择端点命令 
	i = inportb();				        		// 可选地读取一个字节 
 
	outportb(D12_COMMAND, 0xF0);				//发送写缓冲区命令	 
	outportb(D12_DATA, 0);						//写入一个保留字节 
	outportb(D12_DATA, len);					//写入即将写入的字节数目 
 
	for(i=0; i MAX_CONTROLDATA_SIZE)  
				{													 // 数据长度出错 
					     bEPPflags.bits.control_state = USB_IDLE;	 // 设置为等待状态	 
					     D12_SetEndpointStatus(0, 1);			  	 // 停止控制端点0 
				 	     D12_SetEndpointStatus(1, 1);			     // 停止控制端点1 
				} 
				else 
				{ 
					    bEPPflags.bits.control_state = USB_RECEIVE;  // 设置为接收状态 
			  	} 
		 	} 
		} 
	} 
	/*****  下面为控制写入的数据阶段  ***************/ 
	else if(bEPPflags.bits.control_state == USB_RECEIVE)  
	{														  	     // 如果为接收状态 
		i = D12_ReadEndpoint(0, EP0_PACKET_SIZE, 
		ControlData.dataBuffer + ControlData.wCount);	 	    	 // 从端点0接收数据 
		ControlData.wCount += i;					 			  	 // 统计已接收的字节数 
		if( i != EP0_PACKET_SIZE || ControlData.wCount >= ControlData.wLength) 
		{                                                        	 // 数据接收完毕 
			bEPPflags.bits.setup_packet = 1;			     	     // 通知control_handler()处理Setup包				   
			bEPPflags.bits.control_state = USB_IDLE;	             // 设置为等待状态 
		} 
	} 
	else 
 	{ 
		bEPPflags.bits.control_state = USB_IDLE;				 	 // 设置等待状态 
	} 
} 
//-------------------------------------------------------- 
// 函数名称: void ep0_txdone(void) 
// 功能描述: 通过端点索引 1 发送数据 
//-------------------------------------------------------- 
void ep0_txdone(void) 
{ 
	INT16 i = ControlData.wLength - ControlData.wCount;		// 计算未发送的字节数 
 
	D12_ReadLastTransactionStatus(1); 						// 清除中断寄存器标志位 
 
	if (bEPPflags.bits.control_state != USB_TRANSMIT) 
	{														// 非发送状态												 
		single_transmit(0, 0);						 
		return;												// 返回 
	}	 
	 
	if( i >= EP0_PACKET_SIZE) 
	{														// 未发送字节数大于16,发送16个字节 
		D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData + ControlData.wCount); 
		ControlData.wCount += EP0_PACKET_SIZE; 
		bEPPflags.bits.control_state = USB_TRANSMIT;	 
	} 
	else if( i != 0) 
	{												    	// 发送所有未发送的字节 
		D12_WriteEndpoint(1, i, ControlData.pData + ControlData.wCount); 
		ControlData.wCount += i; 
		bEPPflags.bits.control_state = USB_IDLE;			// 置状态为等待状态 
	} 
	else if (i == 0) 
	{ 
		D12_WriteEndpoint(1, 0, 0); 						// 发送完毕,发0个字节 
		bEPPflags.bits.control_state = USB_IDLE; 
	} 
} 
 
 
//-------------------------------------------------------- 
// 函数名称: ep1_rxdone() 
// 功能描述: 通过端点索引 2 接收数据 
// 输	 入: 无 
// 输	 出: 接收数据长度 
//-------------------------------------------------------- 
INT8U ep1_rxdone(void) 
{ 
	INT8U len = 0; 
 
	D12_ReadLastTransactionStatus(2);		 			 		// 清中断标志位 
	len = D12_ReadEndpoint(2,EP1_PACKET_SIZE,GenEpBuf);			// 读取数据 
	return len; 
} 
 
//-------------------------------------------------------- 
// 函数名称: ep2_rxdone() 
// 功能描述: 通过端点索引 4 接收数据 
// 输	 入: 无 
// 输	 出: 接收数据长度 
//-------------------------------------------------------- 
INT8U ep2_rxdone(void) 
{ 
	INT8U len = 0; 
	 
	D12_ReadLastTransactionStatus(4); 					// 清中断标志位 
	len = D12_ReadEndpoint(4,EP2_PACKET_SIZE,EpBuf);	// 读取缓冲区中的数据 
	return len; 
} 
 
//-------------------------------------------------------- 
// 函数名称: void Usb_Exception(void) 
// 功能描述: D12中断服务程序 
//-------------------------------------------------------- 
void USB_INT1()  interrupt 2 
{ 
	INT16U i_st; 
	 
	DISABLE();					       				// 进入D12中断服务程序时关中断 
 
	bEPPflags.bits.in_isr = 1; 
	i_st = D12_ReadInterruptRegister();				// 读取PDIUSBD12中断寄存器值 
	if(i_st != 0) 
	{ 
		if(i_st & D12_INT_BUSRESET) 
		{ 
			bEPPflags.bits.bus_reset = 1;			// USB总线复位标志 
		} 
		if(i_st & D12_INT_EOT) 
		{ 
			dma_eot();								// DMA传输技术处理 
		} 
		if(i_st & D12_INT_SUSPENDCHANGE) 
		{ 
			bEPPflags.bits.suspend = 1;				// 挂起改变标志置1 
		} 
		if(i_st & D12_INT_ENDP0IN) 
		{ 
			ep0_txdone();							// 控制端点发送数据处理 
		} 
		if(i_st & D12_INT_ENDP0OUT) 
		{ 
			ep0_rxdone();							// 控制端点接收数据处理 
		} 
		if(i_st & D12_INT_ENDP1IN) 
		{											// 端点 1发送数据处理 
			D12_ReadLastTransactionStatus(3); 
		} 
		if(i_st & D12_INT_ENDP1OUT) 
		{ 
			Len_ep1Buffer = ep1_rxdone();			// 端点 1接收数据处理 
		} 
		if((i_st & D12_INT_ENDP2IN)) 
		{ 
			D12_ReadLastTransactionStatus(5);		// 端点 2发送数据处理 
		} 
		if(i_st & D12_INT_ENDP2OUT) 
		{ 
			Len_ep2Buffer = ep2_rxdone();			// 端点 2 接收数据处理 
		} 
	} 
   	bEPPflags.bits.in_isr = 0; 
	 
   	ENABLE();										// 退出D12中断服务程序时开中断 
} 
 
 
//-------------------------------------------------------- 
// 函数名称: Get_D12_FirmwareVer() 
// 功能描述: 重新连接USB总线 
// 输	 入: 无 
// 输	 出: 16bit整数,如0x0500表示D12固件软件版本号为5.00 
//-------------------------------------------------------- 
/*INT16U Get_D12_FirmwareVer(void) 
{ 
	return 0x0500;					//D12固件软件版本号为5.00 
} 
*/