CH375A做主机,插SUN键盘后,取配置描述符时总是返超时(0x20),后来无意中随便按住了一个键,令我惊讶的是竟可以正确得到配置描述符了,道理真是想不通。大伙有谁碰上过??
接键盘或者鼠标的话,由于是低速设备,所以在硬件连线的时候,要将UD+和375的UD-相接,UD-和UD+相连接,同时在设置好模式之后,要将375的主频降到1。5M才可以正常的工作,否则是无法工作的
我的硬件除了上面提到的这个键盘有上述现象外,接其他键盘和鼠标目前为止都能正常工作。
那你接到计算机上面去,你用BUSHOUNG这个软件来看下计算机是怎么操作这个设备的,个别的低速设备是用单片机模拟出来的,并不是真正意义上面的符合USB的HID的类规范,导致了375芯片不能操作。
以下是bus hound的枚举过程,应该没有什么问题,硬件是按上面说的方法接的。 bus Hound 5.00 capture. Complements of www.perisoft.net
Device - Device ID (followed by the endpoint for USB devices) (16) USB 人体学输入设备 (17) HID Keyboard Device Phase - Phase Type CTL USB control transfer DI Data in DO Data out NSTS NT status Data - Hex dump of the data transferred Descr - Description of the phase Cmd... - Position in the captured data
Device Phase Data Description Cmd.Phase.Ofs(rep) ------ ----- ------------------------ ---------------- ------------------ 16.1 DI 00 00 00 00 07 00 00 00 ........ 1.1.0 16.1 NSTS 20 01 00 c0 cancelled 1.2.0 16.0 CTL 80 06 00 01 00 00 12 00 GET DESCRIPTOR 2.1.0 16.0 DI 12 01 10 01 00 00 00 08 ........ 2.2.0 30 04 05 00 00 02 00 00 0....... 2.2.8 00 01 .. 2.2.16 16.0 CTL 80 06 00 02 00 00 09 00 GET DESCRIPTOR 3.1.0 16.0 DI 09 02 22 00 01 01 00 a0 .."..... 3.2.0 32 2 3.2.8 16.0 CTL 80 06 00 02 00 00 22 00 GET DESCRIPTOR 4.1.0 16.0 DI 09 02 22 00 01 01 00 a0 .."..... 4.2.0 32 09 04 00 00 01 03 01 2....... 4.2.8 01 00 09 21 00 01 21 01 ...!..!. 4.2.16 22 40 00 07 05 81 03 08 "@...... 4.2.24 16.0 CTL 00 09 01 00 00 00 00 00 SET CONFIG 5.1.0 16.0 CTL 21 0a 00 00 00 00 00 00 SET IDLE 6.1.0 16.0 CTL 81 06 00 22 00 00 80 00 GET DESCRIPTOR 7.1.0 16.0 DI 05 01 09 06 a1 01 05 07 ........ 7.2.0 19 e0 29 e7 15 00 25 01 ..)...%. 7.2.8 75 01 95 08 81 02 95 01 u....... 7.2.16 75 08 81 01 95 05 75 01 u.....u. 7.2.24 16.1 DI 00 00 00 00 00 00 00 00 ........ 8.1.0 16.0 CTL 21 09 00 02 00 00 01 00 SET REPORT 9.1.0 16.0 DO 01 . 9.2.0 17 DO 00 01 .. 10.1.0
如果是用单片机模拟USB,那么对它是否设置地址是无所谓的(是否可以这样理解?)。 接此键盘时,还有一个现象:如果不对它进行设置地址操作,是可以正确得到配置描述符的;否则,无论地址是什么,甚至是地址0,设备均返回超时(0x20).
描述符应该是正常的,按USB规定设置地址之后要有2ms的恢复时间,有些设备可能更长,你将设置地址之后的延时加长看看。
谢谢luoye268268,我试过了,没有成功。 不过我找了一个折衷的办法,就是不设置地址,任何设备都工作于默认地址0。放心,应用上ch375每个时刻只会接一个设备,不会产生地址上的冲突。
这样是不可以的,因为在你不设置地址的话,配置描述符是可以获取到的,但是到后面的设置配置之类的操作就会出现问题,这个问题应该是你的设置地址的命令没有发送成功。
请帮忙分析下下面程序的时序是否符合要求,此方法我就没有成功。硬件环境:at89c52+12.000晶振 GET_DEVICE_DESC: MOV A,#SET_ENDP7 MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A NOP NOP MOV A,#80H MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A ;设置主机端点的同步触发标志为0,发送data0 NOP NOP MOV A,#WR_USB_DATA7 MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A NOP NOP MOV A,#08H ;8个数据 MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A NOP NOP MOV A,#80H NOP MOVX @DPTR,A ;80H MOV A,#06H NOP MOVX @DPTR,A ;06H MOV A,#00H NOP MOVX @DPTR,A ;00H MOV A,#01H NOP MOVX @DPTR,A ;01H MOV A,#00H NOP MOVX @DPTR,A ;00H NOP NOP MOVX @DPTR,A ;00H MOV A,#12H NOP MOVX @DPTR,A ;12H MOV A,#00H NOP MOVX @DPTR,A ;00H NOP NOP MOV A,#ISSUE_TOKEN MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A NOP NOP MOV A,#0DH MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A ;发送setup令牌包 NOP NOP ret
这是全部的程序,有助于理解。 INTO1 BIT P3.3 CS1 BIT P1.3
;52 STACK EQU 6FH USB1_CFG_VALUE EQU 6EH ;临时变量 CONT1 EQU 08H CONT2 EQU 09H CONT3 EQU 0AH ; T2CON EQU 0C8H TL2 EQU 0CCH TH2 EQU 0CDH RCAP2L EQU 0CAH RCAP2H EQU 0CBH ;USB变量 SET_SYS_FRQE SET 04H RESET_ALL SET 05H CHECK_EXIST SET 06H SET_RETRY SET 0BH DELAY_100US SET 0FH SET_USB_ADDR SET 13H SET_USB_MODE SET 15H TEST_CONNECT SET 16H ABORT_NAK SET 17H SET_ENDP6 SET 1CH SET_ENDP7 SET 1DH ; GET_STATUS SET 22H RD_USB_DATA0 SET 27H RD_USB_DATA SET 28H WR_USB_DATA7 SET 2BH ; CLR_STALL SET 41H SET_ADDRESS SET 45H GET_DESCR SET 46H SET_CONFIG SET 49H AUTO_SETUP SET 4DH ISSUE_TKN_X SET 4EH ISSUE_TOKEN SET 4FH ; USB_INT_SUCCESS SET 14H USB_INT_CONNECT SET 15H USB_INT_DISCONNECT SET 16H CMD_RET_SUCCESS SET 51H CMD_RET_ABORT SET 5FH ; USB1_CMD_ADDR SET 0FF00H USB1_DAT_ADDR SET 0FD00H USB2_CMD_ADDR SET 4100H USB2_DAT_ADDR SET 0100H ; DMABUFFERLEN EQU 80h
ORG 0000H AJMP START ORG 0003H LJMP ERROR ORG 000BH LJMP ERROR ORG 0013H LJMP ERROR ORG 001BH LJMP ERROR ORG 0023H LJMP ERROR ORG 002BH LJMP ERROR ; ERROR: RETI
START: LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS MOV SP,#STACK CLR EA ;禁止所有中断 LCALL INIT_UART START1: CLR CS1 MOV A,#RESET_ALL MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A ;RESET CH375A(HARD RESET) LCALL DELAY_40MS LCALL DELAY_40MS MOV A,#06H MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A ;CHECK EXIST NOP NOP MOV A,#55H MOV DPTR,#USB1_DAT_ADDR MOVX @DPTR,A NOP NOP NOP MOVX A,@DPTR ;DATA LCALL UART_SEND ;AAH CJNE A,#0AAH,START1 ;CH375A ;==================ch375a工作正常========================== MOV A,#SET_USB_MODE MOV DPTR,#USB1_CMD_ADDR ;设置ch375的工作模式 NOP MOVX @DPTR,A NOP NOP NOP MOV A,#06H ;已启用的USB主机模式 06H MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A MOV P0,#0FFH START2: MOV A,#14H LCALL DELAY_A ;延时20us等待ch375a完成设置模式命令 MOV DPTR,#USB1_DAT_ADDR NOP MOVX A,@DPTR LCALL UART_SEND ;51H, ;==========以上设置USB1为主机模式=============== MOV A,#SET_RETRY ;设置重试次数 MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A NOP NOP MOV A,#25H MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A nop nop nop MOV A,#0BFH MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A NOP NOP NOP MOV A,#SET_SYS_FRQE ;设置系统时钟 MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A nop nop nop MOV A,#01H ;系统工作频率1.5MHz MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A TASK_LOOP: LCALL DELAY_5MS LCALL DELAY_5MS MOV C,INTO1 ;等待设备插入 JC TASK_LOOP LCALL GET_INT_STAT1 LCALL UART_SEND ;15H OR 16H CJNE A,#USB_INT_CONNECT,TASK_LOOP1 LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS JMP TASK_LOOP2 TASK_LOOP1: CJNE A,#USB_INT_DISCONNECT,TASK_LOOP3 JMP TASK_LOOP TASK_LOOP2: LCALL EMU_DEV JNZ TASK_LOOP ;A=0 枚举出错;A=FF 枚举成功 JMP START1 TASK_LOOP3: JMP START1 ;========================================================================= ; ; 设备枚举子程序 ; ;========================================================================== EMU_DEV: MOV A,#SET_USB_MODE MOV DPTR,#USB1_CMD_ADDR ;复位USB总线 NOP MOVX @DPTR,A nop nop nop MOV A,#07H ;MODE 07 MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A MOV R1,#40H ;将复位信号保持10ms EMU_1: MOV A,#0F0H LCALL DELAY_A DJNZ R1,EMU_1 NOP MOV A,#SET_USB_MODE ;再把模式设回06H MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A nop nop nop MOV A,#06H ;MODE 06 MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A ; MOV R1,#50 EMU_DEV1: MOV A,#22H LCALL UART_SEND DJNZ R1,EMU_2 JMP EMU_ERROR_RET EMU_2: MOV C,INTO1 JC EMU_DEV1 LCALL GET_INT_STAT1 LCALL UART_SEND ;15H,等待复位后设备再次连接上来 CJNE A,#USB_INT_CONNECT,EMU_3 LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS LCALL DELAY_40MS JMP GET_DEVICE_DESC EMU_3: JMP EMU_ERROR_RET ;=================USB设备已经正确连接================= GET_DEVICE_DESC: MOV A,#SET_ENDP7 MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A NOP NOP MOV A,#80H MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A ;设置主机端点的同步触发标志为0,发送data0 NOP NOP MOV A,#WR_USB_DATA7 MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A NOP NOP MOV A,#08H ;8个数据 MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A NOP NOP MOV A,#80H NOP MOVX @DPTR,A ;80H MOV A,#06H NOP MOVX @DPTR,A ;06H MOV A,#00H NOP MOVX @DPTR,A ;00H MOV A,#01H NOP MOVX @DPTR,A ;01H MOV A,#00H NOP MOVX @DPTR,A ;00H NOP NOP MOVX @DPTR,A ;00H MOV A,#12H NOP MOVX @DPTR,A ;12H MOV A,#00H NOP MOVX @DPTR,A ;00H NOP NOP MOV A,#ISSUE_TOKEN MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A NOP NOP MOV A,#0DH MOV DPTR,#USB1_DAT_ADDR NOP MOVX @DPTR,A ;发送setup令牌包 NOP NOP MOV R1,#50 GET_DEVICE_DESC1: MOV A,#44H LCALL UART_SEND DJNZ R1,GET_DEV_DESCR10 JMP EMU_ERROR_RET GET_DEV_DESCR10: MOV C,INTO1 JC GET_DEVICE_DESC1 LCALL GET_INT_STAT1 LCALL UART_SEND ;14H CJNE A,#USB_INT_SUCCESS,GET_DEVICE_DESC2 JMP GET_DEVICE_DESC4 GET_DEVICE_DESC2: CJNE A,#USB_INT_CONNECT,GET_DEVICE_DESC3 ;15H JMP TASK_LOOP2 GET_DEVICE_DESC3: CJNE A,#USB_INT_DISCONNECT,GET_DEVICE_DESC31 ;16H GET_DEVICE_DESC31: JMP EMU_ERROR_RET ;复位设备 GET_DEVICE_DESC4: MOV R0,#DMABUFFERLEN MOV A,#RD_USB_DATA MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A MOV A,#06H LCALL DELAY_A MOV DPTR,#USB1_DAT_ADDR NOP MOVX A,@DPTR ;读出数据个数 MOV CONT1,A MOV @R0,A GET_DEVICE_DESC5: NOP NOP MOVX A,@DPTR ;读描述符 INC R0 MOV @R0,A ;读出设备返回的设备描述符并保存 DJNZ CONT1,GET_DEVICE_DESC5 ;==============把缓存中的设备描述符通过串口发送========================== MOV R0,#DMABUFFERLEN MOV A,@R0 MOV CONT1,A GET_DEVICE_DESC6: INC R0 MOV A,@R0 LCALL UART_SEND DJNZ CONT1,GET_DEVICE_DESC6 ;===============设备描述符发送完========================================= MOV R0,#DMABUFFERLEN INC R0 MOV A,@R0 CJNE A,#12H,GET_DEVICE_DESC7 JMP GET_DEVICE_DESC8 GET_DEVICE_DESC7: JMP EMU_ERROR_RET GET_DEVICE_DESC8: INC R0 MOV A,@R0 CJNE A,#01H,GET_DEVICE_DESC9 JMP GET_DEVICE_DESC10 GET_DEVICE_DESC9: JMP EMU_ERROR_RET GET_DEVICE_DESC10: MOV A,R0 ADD A,#06H MOV R0,A MOV A,@R0 CJNE A,#08H,GET_DEVICE_DESC11 JMP GET_DEVICE_DESC12 GET_DEVICE_DESC11: JMP EMU_ERROR_RET GET_DEVICE_DESC12: MOV A,R0 ADD A,#0AH MOV R0,A MOV A,@R0 MOV USB1_CFG_VALUE,A JMP EMU_OK_RET EMU_ERROR_RET: MOV A,#00H RET EMU_OK_RET: MOV A,#0FFH EMU_DEV_EXIT: RET GET_INT_STAT1: MOV A,#GET_STATUS MOV DPTR,#USB1_CMD_ADDR NOP MOVX @DPTR,A nop nop nop MOV DPTR,#USB1_DAT_ADDR NOP MOVX A,@DPTR RET INIT_UART: mov TL2,#0D9H ;9600,12.000MHz MOV TH2,#0FFH MOV RCAP2L,#0D9H MOV RCAP2H,#0FFH MOV T2CON,#34H MOV PCON,#00H MOV SCON,#50H
; MOV TL1,#0FDH ;9600,11.059MHz ; MOV TH1,#0FDH ; MOV TMOD,#20H ; MOV PCON,#00H ; MOV SCON,#50H SETB TR1
RET UART_SEND: CLR TI MOV SBUF,A JNB TI,$ CLR TI RET
DELAY_5MS: MOV CONT2,#0AH DELAY_5s_2: MOV CONT3,#0F0H DELAY_5s_1: DJNZ CONT3,DELAY_5s_1 DJNZ CONT2,DELAY_5s_2 RET DELAY_40ms: MOV CONT2,#50H DELAY_40ms_2: MOV CONT3,#0F0H DELAY_40ms_1: DJNZ CONT3,DELAY_40ms_1 DJNZ CONT2,DELAY_40ms_2 RET DELAY_A: MOV CONT1,A DELAY_A_1: DJNZ CONT1,DELAY_