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

📄 usb.c

📁 PDIUSB12+51做 U盘程序,可以将自己的系统单做U盘跟 电脑通信
💻 C
📖 第 1 页 / 共 4 页
字号:
   unsigned char DMA_EOT           :1;
   unsigned char not_use           :7;
  }Interrupt;
}Interrupt_Register;    //中断寄存器

union
{
	unsigned int	Register;
	struct
	{
		unsigned char bus_reset        :1;		//总线复位标志
 		unsigned char suspend          :1;		//挂起标志
		unsigned char remote_wakeup    :1;
 		unsigned char int_isr          :1;
 		unsigned char not_end          :1;		//上次访问未结束标志
 		unsigned char usb_idle         :1;	   //总线空闲
 		unsigned char usb_busy         :1;	   //总线忙
		unsigned char setup_packet_in  :1;	   //setup包输入标志
 		unsigned char setup_packet_out :1;	   //setup包输出标志
 		unsigned char set_addr         :1;	   //设置地址标志 ,如果为1,表明USB的地址已经设置,为0,则没有设置
 		unsigned char usb_endp0_in     :1;	   //端点0输入标志
		unsigned char usb_endp2_in     :1;	   //端点2输入标志
 		unsigned char usb_endp2_out    :1;	   //端点2输出标志
	}flags;
}usb_flags;									   //定义USB标志寄存器

union                                    //端点最后处理状态
{
 unsigned char Register;
 struct
 {
  unsigned char successful          :1;
  unsigned char error_code          :4;

  unsigned char setup_packet        :1;
  unsigned char data_1              :1;
  unsigned char prestatus_not_read  :1;
 }Status;
}Last_Status;

union 
{
 unsigned char Register;
 struct
  {
   unsigned char Command                :1;	   //命令
   unsigned char Data                   :1;	   //数据
  }Status;
}SCSI;				 //定义SCSI状态寄存器





//*****************   延时x毫秒函数 ***********
void Delay(unsigned int x)                
{
 unsigned int i;
 unsigned int j;
 for(i=0;i<x;i++)
 for(j=0;j<230;j++);
}
//********************************************


/********************************************************************************/

unsigned int SWAP(unsigned int temp)                                //高低字节交换
{
 unsigned int i;
 i=temp;
 i<<=8;
 temp>>=8;
 i|=temp;
 return i;
}

void error(unsigned char number)             //出错处理
{
// unsigned char Error[]={"ERROR: "};
// prints(Error);
// printc(number);
 number=0;
}

unsigned char Get_MSB(unsigned int temp)	 //取高8位
{
	return (unsigned char)(temp>>8);	
}
unsigned char Get_LSB(unsigned int temp)	//取低8位
{
	return (unsigned char)(temp);	
}


void Write_Usb_CMD(unsigned char  CMD)			 //写USB命令
{
	 USB_A0		= USB_COMMAND_ADD;
	 USB_DATA	=	CMD;
	 USB_WR		=	0;
	 USB_WR		=	1;
	 USB_DATA=0XFF;
}

void Write_A_Usb_DAT(unsigned char  DAT)			 //写一个USB数据
{
	 USB_A0		= USB_DATA_ADD;
	 USB_DATA	=	DAT;
	 USB_WR		=	0;
	 USB_WR		=	1;
	 USB_DATA=0XFF;
}

unsigned char Read_A_Usb_DAT(void)				 //读一个USB数据
{
	unsigned char temp;
	USB_A0	= USB_DATA_ADD;
	USB_RD	=	0;
	temp	=	USB_DATA;
	USB_RD	=	1;
	return	temp;	
}
/****************************************************************************
函数名称:void Read_Intrrupt_Register(void)
函数作用:读D12	中断寄存器,并将读出的值存到中断标志全局共用体变量Intrrupt_Register中
改变全局变量:Intrrupt_Register

说明:外部设备读取D12的	中断寄存器之后,回根据Intrrupt_Register中相应的值,做相应的
响应,比如:如果此时读取的值中,bus_reset =1,则说明USB主机发送的是一个总线复位命令,
那么USB设备就必须进行总线复位,换句话说,主机要求你做什么,你就得做什么,不然主机可能不会识别你
*****************************************************************************/
void Read_Interrupt_Register(void)			//读中断寄存器
{
	Write_Usb_CMD(READ_INTERRUPT_REGISTER);
	Interrupt_Register.Register[0]	=	Read_A_Usb_DAT();
	Interrupt_Register.Register[1]	=	Read_A_Usb_DAT();
}



void Set_Usb_Addr(unsigned char addr)		//设置D12地址
{
	Write_Usb_CMD(SET_ADDR);
	Write_A_Usb_DAT(0X80|addr);	   //最高位为1,则使地址有效
}

/***************
void Set_Usb_DMA()
{}

*****************/



/***********8以下是一些关于端点操作的函数*********************************/

void Set_Endp_Enable(void)
{
	Write_Usb_CMD(SET_ENDPOINT_ENABLE );
	Write_A_Usb_DAT(0X01);	   //1为普通,0为同步	
}

/*************************************************************************8*****
函数名称:unsigned char Chioce_Endpoint(unsigned char endp)
函数功能:端点选择,并返回端点状态(空、满)
传递参数:端点 endp
返回数据:端点状态
*******************************************************************************/
unsigned char Chioce_Endp(unsigned char endp)	 //端点选择
{
	 Write_Usb_CMD(SELECT_ENDPOINT+endp );
	 return	Read_A_Usb_DAT();					//读出数据为0,则该缓冲区空,为1,满
}

unsigned char Read_Endp_Status(unsigned char endp)	 //读端点状态
{
	 Write_Usb_CMD(READ_ENDPOINT_STATUS+endp );
	 return	Read_A_Usb_DAT();					   //返回端点状态字,根据状态做响应处理
}


unsigned char Read_Endp_Last_Status(unsigned char endp)	//读端点最后状态,同时复位中断寄存器相应位。
{
	 Write_Usb_CMD(READ_LAST_STATUS+endp );
	 return	Read_A_Usb_DAT();						 //返回最后处理状态
}

void Set_Endp_Status(unsigned char endp,	unsigned char	status)		  //设置端点状态
{
	Write_Usb_CMD(0x40+endp );
	Write_A_Usb_DAT(!status );
}
/***********************以下是一些关于buffer缓冲区的操作函数***********************/

void Clear_Buffer(void)		 //清端点缓冲区
{
	  Write_Usb_CMD(CLEAR_BUFFER);
}

void Validate_Buffer(void)	   //使缓冲区合法。
{
	 Write_Usb_CMD(VALIDATE_BUFFER );
}

void Ack_Setup(unsigned char endp)	   //建立应答包
{
	Chioce_Endp(endp);	   //选择端点
	Write_Usb_CMD(ACK_SETUP );	//设置应答
}

/******************************************************************************************
函数名称:unsigned char Read_Endp_Buffer(unsigned char endp,	unsigned char len,	unsigned char *buff)
函数功能:读取指定端点的缓冲区数据且长度指定,数据放入buff中
传递参数:endp:端点	
		  len :数据长度
		  *buff	:缓冲区首地址
返回参数:实际读取数据长度
********************************************************************************************/
unsigned char Read_Endp_Buffer(unsigned char endp,	unsigned char len,	unsigned char *buff)
{
	unsigned char	i,buflen;
	Read_Endp_Last_Status(endp);	// 读端点最后状态:作用不是很清楚,估计是清除某些位。可删除试试
	if(!Chioce_Endp(endp)&0x01){return 0;}//如果缓冲区为空,则返回 0;
	Read_Endp_Status(endp);	 //为什么这里要读/???
	Write_Usb_CMD(READ_BUFFER);	
	Read_A_Usb_DAT(); 				//读取的第一个字节为任意值,因此不要;
	buflen=Read_A_Usb_DAT(); 		//第二字节为缓冲区数据长度
	if(buflen>len)buflen=len;		//需要读取的数据长度可能小于实际要求的数据长度,但是在读的时候是把数据读完。
	for(i=0;i<buflen;i++)			//读取数据
	{
		USB_RD=0;
		*(buff+i)=USB_DATA; 
		USB_RD=1;
	}
    Clear_Buffer();	 //数据读完之后,清缓冲区
	return	buflen;	//如果成功读取,则返回读取数据的实际长度
}


unsigned char Write_Endp_Buffer(unsigned char endp,	unsigned char len,	unsigned char *buff)
{
	unsigned char i;
	Read_Endp_Last_Status(endp);	 //清除中断某些标志
	Chioce_Endp(endp);	//	Read_Endp_Status(endp);就是这句话,使得每局过程出错
	Write_Usb_CMD(WRITE_BUFFER);
	Write_A_Usb_DAT(0);
	Write_A_Usb_DAT(len);
	for(i=0;i<len;i++)
	{
		USB_DATA=*(buff+i);
		USB_WR=0;
		USB_WR=1; 		
	}
	USB_DATA=0XFF;
	Validate_Buffer();
	return	len;	
}

/********************************************************************************
以下两个函数是USB的连接、断开及初始化函数。详细注释见下面
*********************************************************************************/
void Disconnect_Usb(void)
{
	Write_Usb_CMD(0XF3);		//设置USB—D12的模式命令;连续写两个字节。第一个为配置信息,第二个为分频系数。
    Write_A_Usb_DAT(0x0E);		//7-6=00:模式0,非同步模式;5=0:保留,写0;4=0;不连接;3=1:所有都报告,2=1;1=0;0=0。
	Write_A_Usb_DAT(0x47);		//分频系数计算公式:48/((3:0)+1),那么这里就是48/(7+1)=6MHz

⌨️ 快捷键说明

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