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

📄 mainusb.c

📁 usb代码
💻 C
字号:
#include<reg52.h>
#include<Absacc.h>
#include <intrins.h>
//#include <stdio.h>
//#include <string.h>

#define ENABLE 	EA=1
#define DISABLE EA=0
#define Cmdaddr 0x1000
#define Dataddr 0x0000
#define	Setup_flag	0x01
#define Trans_flag	0x02
#define Uchar unsigned char
#define Uint unsigned int
#define SWAP(x)   ((((x) & 0xFF) << 8) | (((x) >> 8) & 0xFF))

#define EP0_OUT 	0x01
#define EP0_IN 		0x02
#define EP1_OUT 	0x04
#define EP1_IN 		0x08
#define EP2_OUT 	0x10
#define EP2_IN	 	0x20
#define BUS_RESET 	0x40
#define SUSPCH		0x80

/******************************      Declare      *************************************/

void InitSys();
void Delay(int);
void Disconnect();
void Connect();
void InitSerial();
void InitINT0();
void Readintregister(char *ir1,char *ir2);

void Ep0out();
void Ep0in();
void Ep1out();
void Ep1in();
void Ep2out();
void Ep2in();
void Busreset();
void Suspch();

void Dosetup();
void Readep(char,char);
void Writeep(char n, char len, char *p);
void Answerep(char);
void Prints(char *p);
void Printn(Uchar);

void Ep1trans(Uchar *p);

sbit CSUSB=P1^7;
sbit SUSP=P1^0;
sbit TestL=P1^4;

//Uchar Flagint;						//中断标志,便于主程序区分中断类型
Uchar Flag;						//系统的操作标志
Uchar Ep1leftsize=0;
Uchar *TestP;
Uchar *transp,translen;					//发送长数据时用的临时变量

struct DEVICE_REQUEST					//记录设备请求的结构体缓冲区
{
	Uchar bmrequesttype;
	Uchar brequest;
	Uint wvalue;
	Uint windex;
	Uint wlength;
}Device_request;

struct DEVICE_DESCRIPTOR				//固件_设备描述表的结构体
{
	Uchar blength;
	Uchar bdecriptortype;
	Uint  bcdusb;
	Uchar bdeviceclass;
	Uchar bdevicesubclass;
	Uchar bdeviceportocol;
	Uchar bmaxpacketsize0;
	Uint  idvendor;
	Uint  idproduct;
	Uint  bcddevice;
	Uchar imanufacturer;
	Uchar iproduct;
	Uchar iserialnumber;
	Uchar bnumconfigurations;
};

code struct DESCRIPTORS					//固件_各类描述表(存储于ROM中)
{
	struct DEVICE_DESCRIPTOR Device_descriptor;
}Descriptors=
{
	0x12,
	0x01,
	SWAP(0x0110),
	0xFF,
	0xFF,
	0,
	16,
	SWAP(0x0471),
	SWAP(0x0666),
	SWAP(0x0100),
	0,
	0,
	0,
	1
};



/******************************      Main()      *************************************/

main()
{
	Uchar i;
	
	i=0;
	
	InitSys();
	
	Prints("\nOK!    Let's begin:---> \n");
	Prints("step_1\n");
	
	while(1)
	{
		Delay(100);
		Prints("step_");
		Printn(i ++);
		Prints("\n");
		
		if(Flag&Setup_flag)				//如果有Setup包进入
		{
			DISABLE;
			Flag^=Setup_flag;			//setup标志清除
			ENABLE;
			
			Dosetup();				//响应setup包
		}
		
	}
}

/******************************      Function      *************************************/

void Prints(char *p)
{
	
	while(*p!='\0')
	{
		if(*p == '\n')
		{
			SBUF = '\r';
		}
		Delay(7);
		SBUF=*p++;
		Delay(7);
	}
}

void Printn(Uchar n)
{
	Uchar m;
	m=n/0x10;						//高位
	if(m<0x0A) SBUF=0x30+m;
	else SBUF=0x41+m-0x0A;
	Delay(7);
	
	m=n%0x10;						//低位
	if(m<0x0A) SBUF=0x30+m;
	else SBUF=0x41+m-0x0A;
	Delay(3);
	
}

void InitSys(void)
{
	/*
	CSUSB=0;					//片选D12
	SUSP=0;						//取消挂起,唤醒D12
	TestL=1;
	*/
	P0 = 0xFF;
	P1 = 0xFF;
	P2 = 0xFF;
	P3 = 0xFF;
	CSUSB = 0x0;
	SUSP = 0;
	CSUSB=1;
	CSUSB=0;
	
	InitSerial();
	InitINT0();
	
	
	
	SUSP = 0;
	Disconnect();
	Delay(500);
	Connect();
	
	ENABLE;						//使能中断
}

void InitSerial()
{
	IE=IE|0x90;					//初始化串口
	SCON=0x50;
	TMOD=TMOD|0x20;					//Timer1工作在方式2下
	TH1=0xFD;					// 波特率 9600
	TL1=0xFD;
	TR1=1;
	TI=0;
	RI=0;
}

void InitINT0()
{
	IE|=0x81;
	IT0=0;						//外部中断设置为电平触发
}



void Readintregister(char *ir1,char *ir2)
{
	XBYTE[Cmdaddr]=0xF4;
	*ir1=XBYTE[Dataddr];
	*ir2=XBYTE[Dataddr];
	
	return ;
}

void Dosetup()
{
	Uchar type,req;
	Uchar i;
	
	type=Device_request.bmrequesttype;
	req=Device_request.brequest;
	
	Printn(req);
	if(req==6)					//如果设备请求为Get_Descriptor
	{
		//Prints("gd\t");
		if(Device_request.wvalue==1)			//如果要求获取的是设备描述符
		{
			transp=&Descriptors.Device_descriptor;	//*transp指向设备描述符开头
			//Flag|=Trans_flag;			//传输标志置1,表示当前处于传输状态
			//translen=sizeof(struct DEVICE_DESCRIPTOR);
			//Printn(translen);
			Writeep(1,16,transp);
			//transp+=16;
			//translen-=16;
			translen=0;
		}
	}
	else if(req==5)					//如果设备请求为Set_address
	{
		XBYTE[Cmdaddr]=0xD0;
		XBYTE[Dataddr]=(Uchar)(Device_request.wvalue/0x100);
		Printn((Uchar)(Device_request.wvalue/0x100));
		//for(transp=&Device_request,i=0;i<16;i++,transp++)
		//Printn(*transp);
		Writeep(1,0,0);
	}
}

void Readep(char n,char *p)
{
	char len,i;

	XBYTE[Cmdaddr]=n;				//选择端点
	if(XBYTE[Dataddr]&0x01==0)			//如果缓冲区为空
	{
		return;
	}
							//若不为空
	XBYTE[Cmdaddr]=0xF0;				//读缓冲区
	len=XBYTE[Dataddr];
	len=XBYTE[Dataddr];
	if(len==0) return;
	
	for(i=0;i<len;i++)
	{
		*p=XBYTE[Dataddr];
		//Printn(*p);
		p++;
	}
	
	XBYTE[Cmdaddr]=0xF2;				//清空缓冲区
}

void Writeep(char n, char len, char *p)
{
	char i;
	XBYTE[Cmdaddr]=n;				//选择端点
	i=XBYTE[Dataddr];				//选读一个字节
	
	XBYTE[Cmdaddr]=0xF0;				//写缓冲区的命令
	XBYTE[Dataddr]=0;
	XBYTE[Dataddr]=len;
	for(i=0;i<len;i++)
	{
		XBYTE[Dataddr]=*p;
		//SBUF=*p;Delay(10);
		p++;
	}
	
	XBYTE[Cmdaddr]=0xFA;				//使能缓冲区
	
}

void Answerep(char n)
{
	XBYTE[Cmdaddr]=n;
	XBYTE[Cmdaddr]=0xF1;
	if(n==0)						//若0收到setup包,writeep中的清除缓冲区命令是无效的;
		XBYTE[Cmdaddr]=0xF2;				   //在此,应答了setup之后的清除命令才是有效的。
}

void Ep0out()
{
	char epstate,lastreg;					//端点状态 和 最后处理状态寄存器
	
	XBYTE[Cmdaddr]=0x80;
	epstate=XBYTE[Dataddr];						//读端点状态
	//Printn(epstate);
	
	XBYTE[Cmdaddr]=0x40;
	lastreg=XBYTE[Dataddr];						//读最后处理状态
	//Printn(lastreg);
	
	
	if(lastreg&0x20)					//如果收到的有Setup包
	{
		
		Flag|=Setup_flag;					//Setup包的标志置1,表示有Setup包进入
		Readep(0,&Device_request);				//读端点0
		
		Answerep(0);
		Answerep(1);						//应答Setup包,使得可以清除缓冲区(F2)和使能缓冲区(FA)
		//SUSP=1;
	}
	
	
}

void Ep0in()
{
	Uchar lastreg;
	
	XBYTE[Cmdaddr]=0x41;
	lastreg=XBYTE[Dataddr];						//读最后处理状态,清除中断
	//Printn(lastreg);
	
	if(translen==0) Writeep(1,0,0);
	/*if(Flag&Trans_flag)
		return;
	
	if(translen>16)
	{
		Writeep(1,16,transp);
		translen-=16;
		transp+=16;
	}
	else if(translen!=0)
	{
		Writeep(1,translen,transp);
		translen=0;
	}
	else	
	{
		Writeep(1,0,0);
		Flag^=Trans_flag;
	}*/
}

void Ep1out()
{
	
}
void Ep1in()
{
	
}
void Ep2out()
{
	
}
void Ep2in()
{
	
}
void Busreset()
{
	TestL=0;Delay(1);TestL=1;
	//SUSP=1;
}
void Suspch()
{
	
}



void Connect()
{
	XBYTE[Cmdaddr]=0xF3;
	XBYTE[Dataddr]=0x12;
	XBYTE[Dataddr]=0x80;
}

void Disconnect()
{
	XBYTE[Cmdaddr]=0xF3;
	XBYTE[Dataddr]=0x02;
	XBYTE[Dataddr]=0x80;
}

void Delay(int n)
{
	int i;
	
	for(;n>0;n--)
	 for(i=0;i<100;i++)
	 {;}
}

/******************************      INT      *************************************/

void Serial() interrupt 4
{
	char c;
	
	DISABLE;
	if(TI==1)
	{
		TI=0;
		
	}

	if(RI==1)
	{
		c=SBUF;
		RI=0;
		
	}
	
	ENABLE;
}

void int0() interrupt 0
{
	unsigned char ir1,ir2;
	
	DISABLE;
	
	Readintregister(&ir1,&ir2);
	
	if(ir1&EP0_OUT)						//假如端点0输出中断发生
	{
		Prints("0o\t");
		Ep0out();
	}
	
	if(ir1&EP0_IN)						//假如端点0输入中断发生
	{
		Prints("0i\t");
		Ep0in();
	}
	
	if(ir1&EP1_OUT)						//假如端点0输入中断发生
	{
		Prints("1o\t");
		Ep1out();
	}
	
	if(ir1&EP1_IN)						//假如端点0输入中断发生
	{
		Prints("1i\t");
		Ep1in();
	}
	
	if(ir1&EP2_OUT)						//假如端点0输入中断发生
	{
		Prints("2o\t");
		Ep2out();
	}
	
	if(ir1&EP2_IN)						//假如端点0输入中断发生
	{
		Prints("2i\t");
		Ep2in();
	}
	
	if(ir1&BUS_RESET)					//假如总线复位中断发生
	{
		Prints("br\t");
		Busreset();
	}
	
	if(ir1&SUSPCH)						//假如端点0输入中断发生
	{
		Prints("sc\t");
		Suspch();
	}
	
	ENABLE;
}

⌨️ 快捷键说明

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