⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbd12.c

📁 1.实现单片机驱动USBD12的固件
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (len!=0)
		USB_FLAG.ep2_rxdone = 1;
}
/*******************************************
函数名称: Control_handler
功    能: 控制传输
参    数: 无   
返回值  : 无
/********************************************/
void Control_handler(void)
{
	uchar type,req; 
	
	type=ControlData.DeviceRequest.bmRequestType&USB_REQUEST_TYPE_MASK;
												//读取请求代码													
	req=ControlData.DeviceRequest.bRequest&USB_REQUEST_MASK;
	if(type==USB_STANDARD_REQUEST)
		(*StandardDeviceRequest[req])();		//标准请求处理
	else
		Stall_ep0();							//无效请求,返回STALL				
}
/*******************************************
函数名称: Reserved
功    能: 保留子程序
参    数: 无   
返回值  : 无
/********************************************/
void Reserved(void)
{
	Stall_ep0();				//返回STALL
}
/*******************************************
函数名称: Init_unconfig
功    能: 进入地址状态,禁止0除外的所有端点
参    数: 无   
返回值  : 无
/********************************************/
void Init_unconfig(void)
{
	Set_EPen(0);	//禁止0除外的所有端点
}
/*******************************************
函数名称: Init_config
功    能: 配置处理,允许端点收发
参    数: 无   
返回值  : 无
/********************************************/
void Init_config(void)
{
	Set_EPen(1);	//使能普通/同步端点使能
}
/*******************************************
函数名称: Get_status
功    能: 主机要求获取状态,设备返回16位的状态描述给主机
参    数: 无   
返回值  : 无
/********************************************/
void Get_status(void)
{
	uchar endp,txdat[2],c;
	uchar bRecipient=ControlData.DeviceRequest.bmRequestType&USB_RECIPIENT;	
																//取得设备请求类型	
	if (bRecipient==USB_RECIPIENT_DEVICE) 
	{					//对设备请求
		if(USB_FLAG.remote_wakeup==1)			
		{
			txdat[0]=3;										//支持远程唤醒、自供电
		}
		else
		{
			txdat[0]=1;										//不支持远程唤醒、自供电
		}
		txdat[1]=0;												//高8位为0
		S_trans(txdat,2);								//发送16位的状态到主机
		
	} 
	else if (bRecipient == USB_RECIPIENT_INTERFACE) 
	{			//对接口请求
		txdat[0]=0;
		txdat[1]=0;
		S_trans(txdat, 2);	
									//发送16位的状态到主机
	} 
	else if (bRecipient == USB_RECIPIENT_ENDPOINT) 
	{			//对端点请求
		endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
		{
			c = Sel_EP(endp*2+1);					//读取输入端点状态
		}
		else
		{
			c = Sel_EP(endp*2);						//读取输出端点状态
		}
		if(c & STALL)//----------------
		{
			txdat[0] = 1;										//端点禁止
		}
		else
		{
			txdat[0] = 0;										//端点有效
		}
		txdat[1] = 0;
		S_trans(txdat, 2);								//发送16位的状态到主机

	} 
	else
	{
		Stall_ep0();					//非标准请求,发STALL
	}
}
/*******************************************
函数名称: Clr_feature
功    能: 清除特性
参    数: 无   
返回值  : 无
/********************************************/
void Clr_feature(void)
{
	uchar endp;												//读取请求类型中的接收方
	uchar bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
															//读取请求类型
	if (bRecipient == USB_RECIPIENT_DEVICE					//对设备请求
	&&ControlData.DeviceRequest.wValue==USB_FEATURE_REMOTE_WAKEUP) //清除远程唤醒特性	
	{
		UEN_GINT();								
		USB_FLAG.remote_wakeup = 0;					//清0远程唤醒标志
		EN_GINT();
		S_trans(0,0);								//返回一个空的数据表示执行完毕
	}
	
	else if (bRecipient == USB_RECIPIENT_ENDPOINT			//对端点请求
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) //清除端点禁止特性,恢复其使用
	{
		
		endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
		{
			Set_EPsta(endp*2 + 1, 0);			//清除控制输入端点STALL特性
		}
		else
		{
			Set_EPsta(endp*2, 0);				//清除控制输出端点STALL特性
		}
		S_trans(0, 0);								//返回一个空的数据表示执行完毕
	} 
	else
	{
		Stall_ep0();					//没有该请求,返回STALL	
	}						
}
/*******************************************
函数名称: Set_feature
功    能: 设置特性
参    数: 无   
返回值  : 无
/********************************************/
void Set_feature(void)
{
	uchar endp;											//读取请求类型中的接收方
	uchar bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
														//读取请求类型
	if (bRecipient == USB_RECIPIENT_DEVICE				//对设备请求
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) //设置远程唤醒特性
	{														
		UEN_GINT();
		USB_FLAG.remote_wakeup = 1;				//置1远程唤醒标志
		EN_GINT();
		S_trans(0, 0);							//返回一个空的数据表示执行完毕
	}		
	else if (bRecipient == USB_RECIPIENT_ENDPOINT		//对端点请求
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) //禁止端点
	{		
		endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
		{
			Set_EPsta(endp*2 + 1, 1);		//设置输入端点禁止
		}
		else
		{
			Set_EPsta(endp*2, 1);			//设置输出端点禁止
		}
		S_trans(0, 0);							//返回一个空的数据表示执行完毕
	} 
	else
	{
		Stall_ep0();					//没有该请求,返回STALL
	}
}
/*******************************************
函数名称: Set_addr
功    能: 设置地址
参    数: 无   
返回值  : 无
/********************************************/
void Set_addr(void)
{
	Set_addren((uchar)(ControlData.DeviceRequest.wValue&DEVICE_ADDRESS_MASK), 1);
	S_trans(0, 0);				//发送一个空的数据响应
}
/*******************************************
函数名称: Get_descriptor
功    能: 获取描述符
参    数: 无   
返回值  : 无
/********************************************/
void Get_descriptor(void)
{
	uchar bDescriptor = MSB(ControlData.DeviceRequest.wValue);			//读取请求的描述符类型

	if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE)//获取设备描述符
	{						
		Code_trans((uchar *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
	
	}
	else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) //获取其它描述符
	{		
		  		if (ControlData.DeviceRequest.wLength > CONFIG_DESCRIPTOR_LENGTH)
				{ 
					 ControlData.DeviceRequest.wLength = CONFIG_DESCRIPTOR_LENGTH;
				}
			    Code_trans((uchar *)&(usb_descr.ConfigDescr), ControlData.DeviceRequest.wLength);
			    														//发送描述符内容
	}
	else
	{
				Stall_ep0();					//没有该请求,返回STALL
	}
	 
}
/*******************************************
函数名称: Get_config
功    能: 获取配置
参    数: 无   
返回值  : 无
/********************************************/
void Get_config(void)
{
	uchar c = USB_FLAG.configuration;	//取出配置值
		
	S_trans(&c, 1);				//发送配置值
}
/*******************************************
函数名称: Set_config
功    能: 设置配置
参    数: 无   
返回值  : 无
/********************************************/
void Set_config(void)
{
	if (ControlData.DeviceRequest.wValue == 0)
	{			//配置值不对,设备进入未配置状态
		S_trans(0, 0);								//发向一个空包响应
		UEN_GINT();
		USB_FLAG.configuration = 0;					//标记未配置
		EN_GINT();
		Init_unconfig();									//进入地址状态,禁止0除外的所有端点
		
	} 
	else if (ControlData.DeviceRequest.wValue == 1) 
	{		//配置设备
		S_trans(0, 0);								//发向一个空包响应
		Init_unconfig();									//进入地址状态,禁止0除外的所有端点
		Init_config();										//配置处理,允许端点收发
		UEN_GINT();
		USB_FLAG.configuration = 1;					//标志已配置
		EN_GINT();
	} 
	else
	{
		Stall_ep0();						//没有该请求,返回STALL
	}
}
/*******************************************
函数名称: Get_interface
功    能: 获取接口信息
参    数: 无   
返回值  : 无
/********************************************/
void Get_interface(void)
{
	uchar txdat = 0;				//本设备只有一个接口
	S_trans(&txdat, 1);		//发送一个字节
}
/*******************************************
函数名称: Set_interface
功    能: 设置接口信息
参    数: 无   
返回值  : 无
/********************************************/
void Set_interface(void)
{
	if (ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
	{
		S_trans(0, 0);			//发送一个空的数据表示执行完毕
	}
	else		
	{
		Stall_ep0();					//没有该请求,返回STALL	
	}				
}
/*******************************************
函数名称: USB_connect
功    能: 连接USB总线
参    数: 无   
返回值  : 无
/********************************************/
void USB_connect(void)
{
	// Initialize D12 configuration
	Set_DMA(0x00);
	Set_mode(NOLAZYCLOCK|SOFTCONNECT, SETTOONE | CLOCK_12M);
}	//SoftConnect 连接上,并设置为无LazyClock,模式为非同步模式

/*******************************************
函数名称: Set_interface
功    能: 设置接口信息
参    数: 无   
返回值  : 无
/********************************************/
void USB_disconnect(void)
{
	// Initialize D12 configuration
	Set_mode(NOLAZYCLOCK, SETTOONE | CLOCK_12M);
}	//SoftConnect 断开
/*******************************************
函数名称: USB_reconnect
功    能: 重新连接USB总线
参    数: 无   
返回值  : 无
/********************************************/
void USB_reconnect(void)
{
	uint clk_cnt;

	USB_disconnect();							   //断开芯片与USB总线连接
	Delayms(200);
    //for (clk_cnt = 0;clk_cnt<= 0x10000;clk_cnt++); //延时处理
	Set_addren(0,1);
	Set_EPen(1);
    USB_connect();								   //连接到USB总线
}
uint Read_chipID(void)
{
	uint i,j;
	if(USB_FLAG.in_isr == 0)
		UEN_GINT();
	OutB(CMD, 0xFD);
	i=InB( );
	j=InB( );
	i += (j<<8);
	if(USB_FLAG.in_isr == 0)
		EN_GINT();
	return i;
}

/*******************************************
函数名称: Uart_init
功    能: 异步串口初始化
参    数: baud--设置的波特率
返回值  : 无
/********************************************/
/*void Uart_init(uint baud)			  			 	  
{ 
   baud=MCLK/16/baud-1;				  //波特率最大为65K
   UCSRB=0x00; 
   UCSRA=0x00; 						 	  //控制寄存器清零
   UCSRC=(1<<URSEL)|(0<<UPM0)|(3<<UCSZ0); //选择UCSRC,异步模式,禁止校验,1位停止位,8位数据位
   UBRRL=baud; 					     	  
   UBRRH=baud>>8; 						  //设置波特率
   UCSRB=(1<<TXEN)|(1<<RXEN)|(1<<RXCIE);  //接收、发送使能,接收中断使能
   SREG=(1<<7);							  //全局中断开放
   DDRD|=0X02;							  //配置TX为输出(很重要)
}
/*******************************************
函数名称: Uart_sendB
功    能: 异步串口发送一个字节
参    数: sendB--发送的字节数据
返回值  : 无
/********************************************/
/*void Uart_sendB(uchar sendB)
{
 while(!(UCSRA&(1<<UDRE)));		 //等待发送缓冲区为空
 UDR=sendB;						 //发送数据
 while(!(UCSRA&(1<<TXC)));		 //等待发送完毕
 UCSRA|=1<<TXC;					 //清除发送完毕状态位
}*/
/*******************************************
函数名称: main
功    能: 主函数文件
参    数: 无   
返回值  : 无
/********************************************/
void main(void)
{
 uchar a,b;//,i;
 uint c;
 Board_init( );	   			//初始化开发板
 //Uart_init(9600);
 D12_init();
 //Set_addren(0x80,0x01);
 //Set_EPen(0x01); 
 //c=Read_chipID();
 USB_reconnect();
 while(1)
 {
  if (USB_FLAG.setup_packet)
  {		//Setup包处理
		UEN_GINT();
		USB_FLAG.setup_packet = 0;
		Control_handler();					//调用请求处理子程序
		EN_GINT();
  }
  if(USB_FLAG.ep1_rxdone == 1)		//标志接收到数据
  {
   UEN_GINT();
   USB_FLAG.ep1_rxdone=0;
   All_led(FALSE);
   One_led(GenEpBuf[0],GenEpBuf[1]);
   EN_GINT();
  }    
 }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -