hcn您好: 我的USB设备是扫描枪,对它的初始化程序,我参考了打印机例程那部分。不同的是,例子里是把数据传送给打印机,而我这里是从扫描枪接收采集的数据,所以对于USB初始化这部分要作修改。 但对于例程里的该部分程序有的地方看不明白,修改起来挺费劲的,而且也出了很多错误,请hcn帮忙看一下我修改的,给出指正,谢谢! 其实,我基本没修改什么地方,因为有的地方本身就不明白。
下面是打印机例程里USB初始化部分: /* 初始化USB设备,完成设备枚举 */ unsigned char init_USB_device(void) { unsigned char address; unsigned char status; unsigned char length;
status = get_descr(1); /* 获取设备描述符(1表示设备,2表示配置) */ if( status == USB_INT_SUCCESS ) { length = rd_usb_data( RECV_BUFFER ); /* 将获取的描述符数据从CH375中读出到单片机的RAM缓冲区中,返回描述符长度 */ if( length<18 || p_dev_descr->bDescriptorType!=1 ) return( UNKNOWN_USB_DEVICE ); /* 意外错误:描述符长度错误或者类型错误;0XF1 */ if( p_dev_descr->bDeviceClass!=0 ) return( UNKNOWN_USB_DEVICE ); /* 连接的USB设备不符合USB规范 */ status = set_addr(2); /* 设置USB设备的USB地址;1到128都可以,常用2到20 */ if( status == USB_INT_SUCCESS ) { status = get_descr(2); /* 获取配置描述符 */ if( status == USB_INT_SUCCESS ) /* 操作成功则读出描述符并分析 */ { length = rd_usb_data( RECV_BUFFER ); /* 将获取的描述符数据从CH375中读出到单片机的RAM缓冲区中,返回描述符长度 */ if( p_cfg_descr->itf_descr.bInterfaceClass!=7 || p_cfg_descr->itf_descr.bInterfaceSubClass!=1 ) return( UNKNOWN_USB_DEVICE ); /* 不符合USB规范 */ endp_out_addr=endp_in_addr=0; /* USB数据接收端点地址与USB状态发送端点的端点地址(单向) */ address = p_cfg_descr->endp_descr[0].bEndpointAddress; /* 第一个端点的地址 */ if( address&0x80 ) endp_in_addr = address&0x0f; /* IN端点的地址 */ else { /* OUT端点 */ endp_out_addr = address&0x0f; endp_out_size = p_cfg_descr->endp_descr[0].wMaxPacketSize; /* 数据接收端点的最大包长度 */ if( endp_out_size == 0 || endp_out_size > 64 ) endp_out_size = 64; } if( p_cfg_descr->itf_descr.bNumEndpoints>=2 ) /* 接口有两个以上的端点 */ { if( p_cfg_descr->endp_descr[1].bDescriptorType==5 ) /* 端点描述符 */ { address = p_cfg_descr->endp_descr[1].bEndpointAddress; /* 第二个端点的地址 */ if( address&0x80 ) endp_in_addr = address&0x0f; /* IN端点 */ else {/* OUT端点 */ endp_out_addr = address&0x0f; endp_out_size = p_cfg_descr->endp_descr[1].wMaxPacketSize; if( endp_out_size == 0 || endp_out_size > 64 ) endp_out_size = 64; } } } if( p_cfg_descr->itf_descr.bInterfaceProtocol==1 ) endp_in_addr=0; /* 单向接口不需要IN端点 */ if( endp_out_addr==0 ) return( UNKNOWN_USB_DEVICE ); /* 不符合USB规范 */ status = set_config( p_cfg_descr- >cfg_descr.bConfigurationValue ); /* 加载USB配置值 */ if( status == USB_INT_SUCCESS ) { /* 如果单片机在USB设备忙时并无事可做,建议设置位7为1,使CH375在收到NAK时自动重试直到操作成功或者失败 */ /* 如果希望单片机在USB设备忙时能够做其它事,那么应该设置位7为0,使CH375在收到NAK时不重试, 所以在下面的USB通讯过程中,如果USB设备正忙,issue_token等子程序将得到状态码USB_INT_RET_NAK */ CH375_WR_CMD_PORT( CMD_SET_RETRY ); // 设置USB事务操作的重试次数 CH375_WR_DAT_PORT( 0x25 ); CH375_WR_DAT_PORT( 0x85 ); // 位7为1则收到NAK时无限重试, 位3~位0为超时后的重试次数 } } } } return(status); }
下面是针对我的开发修改后的:
unsigned char buffer[64]; /* 公用缓冲区 */ #define UNKNOWN_USB_DEVICE 0xF1 #define p_dev_descr ((PUSB_DEV_DESCR)buffer) // 强制类型转换,把buffer变成_USB_DEVICE_DESCRIPTOR结构体类型 #define p_cfg_descr ((PUSB_CFG_DESCR_LONG)buffer) unsigned char status1=0,status2=0,status3=0,status4=0; unsigned char length1=0,length2=0; unsigned char address1=0,address2=0; unsigned char init_USB_device() { status1=get_descr(1); if(status1==USB_INT_SUCCESS) { length1=rd_usb_data(buffer); //if(length1<18||p_dev_descr->bDescriptorType!=1) return(UNKNOWN_USB_DEVICE); status2=set_addr(2); if(status2==USB_INT_SUCCESS) { status3=get_descr(2); if(status3==USB_INT_SUCCESS) { length2=rd_usb_data(buffer); endp_out_addr=endp_in_addr=0; address1=p_cfg_descr->endp_descr[0].bEndpointAddress; if(address1&0x80) endp_in_addr=address1&0x0f; else { endp_out_addr=address1&0x0f; endp_out_size=p_cfg_descr->endp_descr[0].wMaxPacketSize; } if(p_cfg_descr->itf_descr.bNumEndpoints>=2) { if(p_cfg_descr->endp_descr[1].bDescriptorType==5) { address2=p_cfg_descr->endp_descr[1].bEndpointAddress; if(address2&0x80) endp_in_addr=address2&0x0f; else { endp_out_addr=address2&0x0f; endp_out_size=p_cfg_descr->endp_descr[1].wMaxPacketSize; } } } if(p_cfg_descr->itf_descr.bInterfaceProtocol==1) endp_out_addr=0; if(endp_in_addr==0) return(UNKNOWN_USB_DEVICE); status4=set_config(p_cfg_descr->cfg_descr.bConfigurationValue); } } } return(status4); }
请帮忙批评指正,谢谢!