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

📄 新建 文本文档.txt

📁 一个基与usb的数据采集程序
💻 TXT
字号:
#include <at89x52.h>
//端口定义
#define D12_DATA 0
#define D12_COMMAND 1
//开关中断
#define ENABLE EA=1
#define DISABLE EA=0
//中断寄存器位定义
#define D12_INT_ENDP0OUT 0x0001
#define D12_INT_ENDP0IN 0x0002
#define D12_INT_ENDP1IN 0x0008
//读最后处理状态寄存器的设置信息包0010,0000b
#define D12_SETUPPACKET 0x20
//p0最大16byte
#define EP0_PACKET_SIZE 16
//设备请求类型,传输方向 D7 1000,0000b
#define USB_ENDPOINT_DIRECTION_MASK 0x80
//bmRequest的设置
#define USB_REQUEST_TYPE_MASK 0x30
#define USB_REQUEST_MASK 0x0f
//5,6位的定义
#define USB_STANDARD_REQUEST 0x0
#define USB_VENDOR_REQUEST 0x20
//描述符类型 设备描述符01h,配置描述符02,接口描述符04,端点描述符05
#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
//配置描述符总长度
#define CONFIG_DESCRIPTOR_LENGTH 0x002E



//事件标志
typedef union _epp_flags
{
	struct _flags
	{
		unsigned char timer:1;//计时器
		unsigned char setup:1;//setup包
		unsigned char isr:1;//中断
		unsigned char state:2;//0:Idel,1:Transmit,2:Receive --by newer
		unsigned char config:1;//配置
	}bits;
	unsigned short value;
}EPPFLAGS;static EPPFLAGS flag;
//USB设备请求寄存器和setup包数据缓冲区
typedef struct _device_request
{
	unsigned char bmRequestType;
	unsigned char bRequest;
	unsigned short wValue;
	unsigned short wIndex;
	unsigned short wLength;
}DEVICE_REQUEST;
typedef struct _control_xfer
{
	DEVICE_REQUEST DeviceRequest;
	unsigned short wLength;
	unsigned short wCount;
	unsigned char *pData;
	unsigned char dataBuffer[16];//最大16byte maybe enough?
}CONTROL_XFER;
static CONTROL_XFER ControlData;
//delayms 延迟
void delayms(int t){
	while(t-- >0);
}
//outportb 输出
void outportb(unsigned char Addr,unsigned char Data){
	WR=1;
	P1_0=Addr;
	P0=Data;
	WR=0;
	delayms(10);
	WR=1;
	delayms(10);
}
//inportb 输入
unsigned char inportb(unsigned char Addr){
	unsigned char rt;
	RD=1;
	P1_0=Addr;
	RD=0;
	delayms(10);
	rt=P0;
	RD=1;
	delayms(10);
	return rt;
}
//init_port 初始化端口
void init_port(){
	P3_6=1;//WR disable
	P3_7=1;//RD disable
}
//init_special_int初始化中断
void init_special_interrupts(void){//no need actually
	IT0=0;//中断INT0低电平触发
	EX0=1;//允许外部中断0
	PX0=1;//?优先级
}
//D12设置模式
void D12_SetMode(unsigned char bConfig,unsigned char bClkDiv){
	outportb(D12_COMMAND,0xF3);
	outportb(D12_DATA,bConfig);
	outportb(D12_DATA,bClkDiv);
}
//断开USB
void disconnect_USB(void){
D12_SetMode(0x02,0x43);//SET TO ONE? by newer
}
//连接USB
void connect_USB(void){
	D12_SetMode(0x16,0x43);
}

//reconnect_usb 重新连接USB
void reconnect_USB(void){
	disconnect_USB();
	delayms(50000);
	connect_USB();
}
//读中断寄存器
unsigned short D12_ReadInterruptRegister(void){
	unsigned char b1;
	unsigned int j;
	outportb(D12_COMMAND,0xF4);
	b1=inportb(D12_DATA);
	j=inportb(D12_DATA);
	j<<=8;
	j+=b1;
	return j;
}
//MSB 取后BYTE?
unsigned char MSB(unsigned short in){
	unsigned char out;
	unsigned short temp;
	temp=in&0xff00;
	out=temp>>8;
	return out;
}
//高低字节的转换
unsigned short SWAP(unsigned short in){
	unsigned short out;
	unsigned short ans;
	out=in&0xff00;
	out=out>>8;
	in=in<<8;
	ans=out+in;
	return ans;
}
//读端点最后处理状态
unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp){
	outportb(D12_COMMAND,0x40+bEndp);
	return inportb(D12_DATA);
}
//读端口
unsigned char D12_ReadEndpoint(unsigned char endp,unsigned char len,unsigned char *buf){
	unsigned char i,j;
	outportb(D12_COMMAND,endp);
	if((inportb(D12_DATA)&0xff)==0)//"  define D12_FULLEMPTY as 0xFF  by newer
		return 0;
	outportb(D12_COMMAND,0x80+endp);
	i=inportb(D12_DATA);
	i=i&0x60;


	outportb(D12_COMMAND,0xF0);
	j=inportb(D12_DATA);
	j=inportb(D12_DATA);
	if(j>len)
		j=len;
	for(i=0;i<j;i++)
		*(buf+i)=inportb(D12_DATA);
	outportb(D12_COMMAND,0xF2);
	return j;
}
//设置端点
void D12_SetEndpointStatus(unsigned char bEndp,unsigned char bStalled){
	outportb(D12_COMMAND,0x40+bEndp);
	outportb(D12_DATA,bStalled);
}
//应答!!!!!
void D12_AcknowledgeEndpoint(unsigned char endp){
	outportb(D12_COMMAND,endp);
	outportb(D12_COMMAND,0xF1);
	if(endp==0)
		outportb(D12_COMMAND,0xF2);
}
//?????????????????
unsigned char D12_WriteEndpoint(unsigned char endp,unsigned char len,unsigned char * buf){
	unsigned char i;
	outportb(D12_COMMAND,endp);
	inportb(D12_DATA);
	outportb(D12_COMMAND,0xF0);
	outportb(D12_DATA,0);
	outportb(D12_DATA,len);
	for(i=0;i<len;i++)
		outportb(D12_DATA,*(buf+i));
	outportb(D12_COMMAND,0xFA);
	return len;
}
////////////////////////////////////////////////////////
void ep0_out(void){
	unsigned char ep_last,i;
	ep_last=D12_ReadLastTransactionStatus(0);//interrupt symbol
	if(ep_last&D12_SETUPPACKET){ //recieved SETUP packet  ---by newer
		ControlData.wLength=0;
		ControlData.wCount=0;
		if(D12_ReadEndpoint(0,sizeof(ControlData.DeviceRequest),(unsigned char *)(&(ControlData.DeviceRequest)))!=sizeof(DEVICE_REQUEST)){
			D12_SetEndpointStatus(0,1);
			D12_SetEndpointStatus(1,1);
			flag.bits.state=0; //should define USB_IDLE first --by newer
			return;
		}

	ControlData.DeviceRequest.wValue=SWAP(ControlData.DeviceRequest.wValue);
	ControlData.DeviceRequest.wIndex=SWAP(ControlData.DeviceRequest.wIndex);
	ControlData.DeviceRequest.wLength=SWAP(ControlData.DeviceRequest.wLength);

	D12_AcknowledgeEndpoint(0);
	D12_AcknowledgeEndpoint(1);
	ControlData.wLength=ControlData.DeviceRequest.wLength;
	ControlData.wCount=0;
	if(ControlData.DeviceRequest.bmRequestType&(unsigned char)USB_ENDPOINT_DIRECTION_MASK){
												//recv from host? --by newer
		flag.bits.setup=1;
		flag.bits.state=1; //by newer
	  }
	else{
		if(ControlData.DeviceRequest.wLength==0){
			flag.bits.setup=1;
			flag.bits.state=0; //by newer
			}
		else{
				if(ControlData.DeviceRequest.wLength>16){//最大传16byte
					flag.bits.state=0; //by newer
					D12_SetEndpointStatus(0,1);
					D12_SetEndpointStatus(1,1);
				}
				else{
					flag.bits.state=2;//by newer																
				}
			}
		}
	}//1
	else if(flag.bits.state==2){
		i=D12_ReadEndpoint(0,EP0_PACKET_SIZE,ControlData.dataBuffer+ControlData.wCount);
		ControlData.wCount+=i;
		if(i!=EP0_PACKET_SIZE||ControlData.wCount>=ControlData.wLength){
			flag.bits.setup=1;
			flag.bits.state=0;
		}
	}
	else{
		flag.bits.state=0;
	}
	
}
/////////////////////
void ep0_in(void){
	short i=ControlData.wLength-ControlData.wCount;
	D12_ReadLastTransactionStatus(1);
	if(flag.bits.state!=1) return;
	if(i>=EP0_PACKET_SIZE){
		D12_WriteEndpoint(1,EP0_PACKET_SIZE,ControlData.pData+ControlData.wCount);
		ControlData.wCount+=EP0_PACKET_SIZE;
		flag.bits.state=1;
		return;
	}
	if(i!=0){
		D12_WriteEndpoint(1,i,ControlData.pData+ControlData.wCount);
		ControlData.wCount+=i;
		flag.bits.state=0;
		return;
	}
	//else if(i==0){
		D12_WriteEndpoint(1,0,0);
		flag.bits.state=0;
//	}
}
//设备描述符DeviceDescr
typedef struct _usb_device_descriptor{
	unsigned char bLength;
	unsigned char bDescriptorType;
	unsigned int bcdUSB;
	unsigned char bDeviceClass;
	unsigned char bDeviceSubClass;
	unsigned char bDeviceProtocol;
	unsigned char bMaxPacketSize0;
	unsigned int idVendor;
	unsigned int idProduct;
	unsigned int bcdDevice;
	unsigned char iManufacturer;
	unsigned char iProduct;
	unsigned char iSerialNumber;
	unsigned char bNumConfiguations;
}USB_DEVICE_DESCRIPTOR;
code USB_DEVICE_DESCRIPTOR DeviceDescr=
{
	0x12,//sizeof(USB_DEVICE_DESCRIPTOR),
	0x01,//USB_DEVICE_DESCRIPTOR_TYPE,
	0x0001,//swap
	0xdc,//USB_CLASS_CODE_TEST_CLASS_DEVICE,
	0,0,
	0x10,//EP0_PACKET_SIZE,
	0xffff,//swap
	0xffff,//swap
	0x0001,//swap
	0,0,0,
	0x19
};
//配置描述符
typedef struct _usb_configuration_descriptor{
	unsigned char bLength[0x2e];
}USB_CONFIGURATION_DESCRIPTOR; 
code USB_CONFIGURATION_DESCRIPTOR ConfigDescr=
{
	0x09,0x02,0x2e,0x00,0x01,0x01,0x00,0xa0,0x32,
	0x09,0x04,0x00,0x00,0x04,0xdc,0xa0,0xb0,0x00,
	0x07,0x05,0x81,0x03,0x02,0x00,0x0a,
	0x07,0x05,0x01,0x03,0x02,0x00,0x0a,
	0x07,0x05,0x82,0x02,0x40,0x00,0x0a,
	0x07,0x05,0x02,0x02,0x40,0x00,0x0a
};
//code_tramsit
void code_transmit(unsigned char code *pRomData,unsigned short len){
	ControlData.wCount=0;
	if(ControlData.wLength>len)
		ControlData.wLength=len;
	ControlData.pData=pRomData;
	if(ControlData.wLength>=EP0_PACKET_SIZE){
		D12_WriteEndpoint(1,EP0_PACKET_SIZE,ControlData.pData);
		ControlData.wCount+=EP0_PACKET_SIZE;
		DISABLE;
		flag.bits.state=1;
		ENABLE;
	}
	else{
		D12_WriteEndpoint(1,ControlData.wLength,pRomData);
		ControlData.wCount+=ControlData.wLength;
		DISABLE;
		flag.bits.state=0;
		ENABLE;
	}
}
//获取描述符
void get_descriptor(void){
	unsigned char bDescriptor=MSB(ControlData.DeviceRequest.wValue);//msb? 0x11 is a shit!,should be by newer :MSB(ControlData.DeviceRequest.wValue);	
	if(bDescriptor==USB_DEVICE_DESCRIPTOR_TYPE){
		code_transmit((unsigned char code*)&DeviceDescr,sizeof(USB_DEVICE_DESCRIPTOR));
		return;
	}
	if(bDescriptor==USB_CONFIGURATION_DESCRIPTOR_TYPE){	
		if(ControlData.DeviceRequest.wLength>CONFIG_DESCRIPTOR_LENGTH){
			ControlData.DeviceRequest.wLength=CONFIG_DESCRIPTOR_LENGTH;
			//标识符总大小2E byte,第二次请求时wlength=0x00ff
		}
		//这里的ConfigDescr其实应该包括其他标识符!
		code_transmit((unsigned char code*)&ConfigDescr,ControlData.DeviceRequest.wLength);
		return;
	}

}
//设置地址使能
void D12_SetAddressEnable(unsigned char bAddress,unsigned char bEnable){
	outportb(D12_COMMAND,0xd0);
	if(bEnable) bAddress |= 0x80;
	outportb(D12_DATA,bAddress);
}
//single transmit
void single_transmit(unsigned char *buf,unsigned char len){
	if(len<=EP0_PACKET_SIZE){
		D12_WriteEndpoint(1,len,buf);
	}
}
//设置地址
void set_address(void){
	D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue&0xff),1);
	//比如wValue是"02 00" 应该得到02
	single_transmit(0,0);
}
//设置端点使能
void D12_SetEndpointEnable(unsigned char bEnable){
	outportb(D12_COMMAND,0xD8);
	if(bEnable)
		outportb(D12_DATA,1);
	else
		outportb(D12_DATA,0);
}
//设置配置
void set_configuration(void){
	if(ControlData.DeviceRequest.wValue==0){
		single_transmit(0,0);
		flag.bits.config=0;
		D12_SetEndpointEnable(0);
	}
	else if(ControlData.DeviceRequest.wValue==1){
		single_transmit(0,0);
		D12_SetEndpointEnable(0);
		D12_SetEndpointEnable(1);
		flag.bits.config=1;
	}
}
//读取配置
void get_configuration(void){
	unsigned char c=flag.bits.config;  
	single_transmit(&c,1);
}
//读取设备接口信息
void get_interface(void){
	unsigned char txdat=0;
	single_transmit(&txdat,1);
}
////////////////////////////////////////////////////////
static code void (*StandardDeviceRequest[])(void)=
{ 0,0,0,0,
  0,set_address,get_descriptor,0,
  get_configuration,set_configuration,get_interface,0,
  0,0,0,0
};
static code void (*VendorDeviceRequest[])(void)=
{ 0,0,0,0,
  0,0,0,0,
  0,0,0,0,
  0,0,0,0
};
/////////////////////






void control_handler(){
	unsigned char type,req;
	type=ControlData.DeviceRequest.bmRequestType&USB_REQUEST_TYPE_MASK;//0011,0000b
	req=ControlData.DeviceRequest.bRequest&USB_REQUEST_MASK;//0000,1111b
	if(type==USB_STANDARD_REQUEST)
		(*StandardDeviceRequest[req])();
	else if(type==USB_VENDOR_REQUEST)
		(*VendorDeviceRequest[req])();
}




void init_timer1(void){
	TMOD&=0xf0;
	TMOD|=0x01;

	ET0=1;//;
	TR0=1;
	PT0=0;

}

//定时器中断
timer_isr() interrupt 1{
unsigned long a=0xabcdef01;
	DISABLE;
	flag.bits.timer=1;
	


	ENABLE;
}

ep1_in(){
	D12_ReadLastTransactionStatus(3);
}

//中断函数
usb_isr() interrupt 0{

	unsigned int i_st;
	DISABLE;
	flag.bits.isr=1;
	i_st=D12_ReadInterruptRegister();
	if(i_st!=0) {
		if(i_st&D12_INT_ENDP0OUT) ep0_out();//endp0 out
		if(i_st&D12_INT_ENDP0IN) ep0_in();//endp0 in
		if(i_st&D12_INT_ENDP1IN) ep1_in();
	}
	flag.bits.isr=0;
	ENABLE;
}
static int counter=0;


void sensor(){//从传感器取数据发送
	unsigned long a=0xabcdef01;
		D12_WriteEndpoint(3,2,(unsigned char *)&a);
	
}


void main(void)
{
	delayms(100);
	DISABLE;
	init_port();
	init_timer1();
	init_special_interrupts();
	reconnect_USB();
	flag.value=0;//清除事件标志寄存器
	ENABLE;
	while(1){
				//
				if(flag.bits.timer){
					DISABLE;
					flag.bits.timer=0;
					ENABLE;
					if(flag.bits.config){
					sensor();
						//从传感器读数据
					}
				}

				if(flag.bits.setup){
					DISABLE;
					flag.bits.setup=0;
					control_handler();
					ENABLE;
				}
	}


}

⌨️ 快捷键说明

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