请问,我发了ISSUE_TOKEN令牌,为什么没有回应啊,没有中断,是什么原因呢?? 我给u盘发了修改地址的命令,然后读出来的u盘描述符的端口地址不变,是不是不能修改那个地址啊。SET_USB_ADDR和SET_ADDRESS,有人这样用过吗? 谢谢
操作USB设备枚举设备的过程实际上是这个样子的,首先获取设备描述符,在获取到之后在设置设备地址,接下来在获取配置描述符,至于发送令牌没有响应的话,可能是你的同步没有做好,还有就是你发下去的端点号是不是你获取到的端点号,这个都有可能导致获取描述符失败的。
/* 对目标USB设备执行控制传输: 设置USB地址 */ unsigned char mCtrlSetAddress( unsigned char addr ) { unsigned char c; CH375_WR_CMD_PORT( CMD_SET_ADDRESS ); /* 控制传输-设置USB地址 */ CH375_WR_DAT_PORT( addr ); /* 1 - 7eh */ c = mWaitInterrupt( ); /* 等待操作完成 */ if ( c != USB_INT_SUCCESS ) return( c ); /* 操作失败 */ /* 当目标USB设备的地址成功修改后,应该同步修改CH375的USB地址,否则CH375将无法与目标设备通讯 */ CH375_WR_CMD_PORT( CMD_SET_USB_ADDR ); /* 设置CH375的USB地址 */ CH375_WR_DAT_PORT( addr ); /* 修改CH375的USB设备能够立即完成,不会产生中断通知 */ return( c ); }
to hcn: 我的操作跟你说的一样,就是先得到设备描述符,然后设置地址,设置就是usbxf兄的这一段,但是后来我获取的配置描述符,在配置描述符中看到的端口号不是我设置的,比如我吧地址设置为5,但是我看到的配置符之中的端口地址还是0x01和0x82,这个地址是不是说是u盘固定的,不能改的吧,但是改的地址是哪个呢??? 怎么看改的那个是哪个地址呢??
你可能理解上面有点误差,我们的设置地址,实际是主机通过设备的地址来区分不同的设备,相当于是总线上面的设备的标识,地址的范围为0-127,而你所读取到的端点描述符中的0X01和0X82实际上是表示USB设备和主机通信的时候是通过哪些端点进行通信的,而不是设置设备地址中的地址,详细的介绍你可以参考USB协议
那个发令牌之后没有中断,是什么原因呢,我发下去的就是获取的端点号,这个我看了。就是,我的u盘的端点号。
toggle_recv(); /* 设置主机接收的同步标志 */ status = issue_token( ( endp_in_addr << 4 ) | DEF_USB_PID_IN );
/* 主机操作 */ unsigned char issue_token( unsigned char endp_and_pid ) /* 执行USB事务 */ { unsigned char status;
/* 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功 */ write_ch375_cmd( CMD_ISSUE_TOKEN ); write_ch375_data( endp_and_pid ); /* 高4位目的端点号, 低4位令牌PID */ status = get_interrupt_status(); /* 等待CH375操作完成 */ return( status ); }
void toggle_recv(void) /* 主机接收成功后,切换DATA0和DATA1实现数据同步 */ { write_ch375_cmd( CMD_SET_ENDP6 ); write_ch375_data( endp6_mode ); endp6_mode^=0x40; delay2us(); }
注:endp6_mode = 0x80
按照USB协议,对USB设备进行枚举,首先是获取设备描述符,接下来是设置地址,在接下来就是获取配置描述符,在获取完配置描述符之后还需要设置一下配置,在做完这些之后,对于一些类设备,例如U盘,鼠标,键盘等,还有一些类请求,只有在这些类请求完成之后才可以进行你下面所说的发送数据,下面的设备会给你返回数据,至于U盘的操作你可以参考海量存储的协议。(一个简单的方法就是将计算机操作U盘的步骤记录下来,然后单片机按照计算机操作U盘的步骤来操作U盘就可以了,但是在有些操作步骤上面不完全相同)