hcn您好: 我的USB設(shè)備是掃描槍,對(duì)它的初始化程序,我參考了打印機(jī)例程那部分。不同的是,例子里是把數(shù)據(jù)傳送給打印機(jī),而我這里是從掃描槍接收采集的數(shù)據(jù),所以對(duì)于USB初始化這部分要作修改。 但對(duì)于例程里的該部分程序有的地方看不明白,修改起來挺費(fèi)勁的,而且也出了很多錯(cuò)誤,請(qǐng)hcn幫忙看一下我修改的,給出指正,謝謝! 其實(shí),我基本沒修改什么地方,因?yàn)橛械牡胤奖旧砭筒幻靼住?/p>
下面是打印機(jī)例程里USB初始化部分: /* 初始化USB設(shè)備,完成設(shè)備枚舉 */ unsigned char init_USB_device(void) { unsigned char address; unsigned char status; unsigned char length;
status = get_descr(1); /* 獲取設(shè)備描述符(1表示設(shè)備,2表示配置) */ if( status == USB_INT_SUCCESS ) { length = rd_usb_data( RECV_BUFFER ); /* 將獲取的描述符數(shù)據(jù)從CH375中讀出到單片機(jī)的RAM緩沖區(qū)中,返回描述符長(zhǎng)度 */ if( length<18 || p_dev_descr->bDescriptorType!=1 ) return( UNKNOWN_USB_DEVICE ); /* 意外錯(cuò)誤:描述符長(zhǎng)度錯(cuò)誤或者類型錯(cuò)誤;0XF1 */ if( p_dev_descr->bDeviceClass!=0 ) return( UNKNOWN_USB_DEVICE ); /* 連接的USB設(shè)備不符合USB規(guī)范 */ status = set_addr(2); /* 設(shè)置USB設(shè)備的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 ); /* 將獲取的描述符數(shù)據(jù)從CH375中讀出到單片機(jī)的RAM緩沖區(qū)中,返回描述符長(zhǎng)度 */ if( p_cfg_descr->itf_descr.bInterfaceClass!=7 || p_cfg_descr->itf_descr.bInterfaceSubClass!=1 ) return( UNKNOWN_USB_DEVICE ); /* 不符合USB規(guī)范 */ endp_out_addr=endp_in_addr=0; /* USB數(shù)據(jù)接收端點(diǎn)地址與USB狀態(tài)發(fā)送端點(diǎn)的端點(diǎn)地址(單向) */ address = p_cfg_descr->endp_descr[0].bEndpointAddress; /* 第一個(gè)端點(diǎn)的地址 */ if( address&0x80 ) endp_in_addr = address&0x0f; /* IN端點(diǎn)的地址 */ else { /* OUT端點(diǎn) */ endp_out_addr = address&0x0f; endp_out_size = p_cfg_descr->endp_descr[0].wMaxPacketSize; /* 數(shù)據(jù)接收端點(diǎn)的最大包長(zhǎng)度 */ if( endp_out_size == 0 || endp_out_size > 64 ) endp_out_size = 64; } if( p_cfg_descr->itf_descr.bNumEndpoints>=2 ) /* 接口有兩個(gè)以上的端點(diǎn) */ { if( p_cfg_descr->endp_descr[1].bDescriptorType==5 ) /* 端點(diǎn)描述符 */ { address = p_cfg_descr->endp_descr[1].bEndpointAddress; /* 第二個(gè)端點(diǎn)的地址 */ if( address&0x80 ) endp_in_addr = address&0x0f; /* IN端點(diǎn) */ else {/* OUT端點(diǎn) */ 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端點(diǎn) */ if( endp_out_addr==0 ) return( UNKNOWN_USB_DEVICE ); /* 不符合USB規(guī)范 */ status = set_config( p_cfg_descr- >cfg_descr.bConfigurationValue ); /* 加載USB配置值 */ if( status == USB_INT_SUCCESS ) { /* 如果單片機(jī)在USB設(shè)備忙時(shí)并無事可做,建議設(shè)置位7為1,使CH375在收到NAK時(shí)自動(dòng)重試直到操作成功或者失敗 */ /* 如果希望單片機(jī)在USB設(shè)備忙時(shí)能夠做其它事,那么應(yīng)該設(shè)置位7為0,使CH375在收到NAK時(shí)不重試, 所以在下面的USB通訊過程中,如果USB設(shè)備正忙,issue_token等子程序?qū)⒌玫綘顟B(tài)碼USB_INT_RET_NAK */ CH375_WR_CMD_PORT( CMD_SET_RETRY ); // 設(shè)置USB事務(wù)操作的重試次數(shù) CH375_WR_DAT_PORT( 0x25 ); CH375_WR_DAT_PORT( 0x85 ); // 位7為1則收到NAK時(shí)無限重試, 位3~位0為超時(shí)后的重試次數(shù) } } } } return(status); }
下面是針對(duì)我的開發(fā)修改后的:
unsigned char buffer[64]; /* 公用緩沖區(qū) */ #define UNKNOWN_USB_DEVICE 0xF1 #define p_dev_descr ((PUSB_DEV_DESCR)buffer) // 強(qiáng)制類型轉(zhuǎn)換,把buffer變成_USB_DEVICE_DESCRIPTOR結(jié)構(gòu)體類型 #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); }
請(qǐng)幫忙批評(píng)指正,謝謝!