这是两种方式,第一种是采用CH375内置固件模式,第二种是外置固件模式,功能是一样的,返回0x2e说明命令错误,或者端点地址错误。
第一种是外部固件方式,也可以用这种方式,因为后面要获取HID报表描述符,长度比较大。 内部固件模式只能获取不超过64字节的描述符。超过64字节则返回缓冲区溢出,需要用外部固件模式来做。
谢谢楼上各位的解答,但是我还是不明白为什么会出现返回错误!得到外设描述符的子程序如下: /************************************* //函数名称:Get_Descr_Ex //函数功能:得到外设描述符 //入口:无 //出口:0 or 1 //备注: ***************************************/ INT8U Get_Descr_Ex(void) { INT8U descr_len; INT8U *p=Data_Buf; Endp7_Mode=0x80; Toggle_Send(); Wr_Usb_Data(8,Request.Req_buf); Issue_Token(( 0 << 4 ) | DEF_USB_PID_SETUP); Status=Wait_Interrupt(); if(Status==USB_INT_SUCCESS)// SETUP阶段操作成功 { Endp6_Mode=0xc0; Toggle_Recv(); } else return(0); Issue_Token(( 0 << 4 ) | DEF_USB_PID_IN); Status=Wait_Interrupt(); if(Status==USB_INT_SUCCESS)// DATA阶段操作成功 { if(Flag_Config_2) descr_len=Data_Buf[2]-Rd_Usb_Data(Data_Buf); else descr_len=Data_Buf[0]-Rd_Usb_Data(Data_Buf); while(descr_len>0) { Toggle_Recv(); p+=0x08; Issue_Token(( 0 << 4 ) | DEF_USB_PID_IN); Status=Wait_Interrupt(); if(Status==USB_INT_SUCCESS) // DATA阶段操作成功 descr_len-=Rd_Usb_Data(p); else return(0); } } else return(0); Endp7_Mode=0xc0; Toggle_Send(); Wr_Usb_Data(0,Request.Req_buf); Issue_Token(( 0 << 4 ) | DEF_USB_PID_OUT); Status=Wait_Interrupt(); if(Status==USB_INT_SUCCESS)// 状态阶段操作成功 return(1); else return(0); }
其中请求包在开始调用此函数前被设为: Request.Req.bmRequestType=0x80; //获取设备描述符 Request.Req.bRequest=0x06; Request.Req.wValue=0x0001; Request.Req.wIndex=0x0000; Request.Req.wLength=0x1200; 我在实验的的时候,第一次发出SETUP令牌返回的是正确的,即0x14,但是接下来的数据阶段,发出IN令牌后,返回就不正确了,返回始终是0x2E,不知道这是什么原因!还望会的给予解答,先行谢过了!
你用的是什么单片机?注意大小端的问题改用下面的方式试试 GetDevDescr[8] = { 0X80,0X06,0X00,0X01,0X00,0X00,0X12,0X00 };
TO:_study_ { M } 我用的是MSP430,这个问题我考虑过,Request.Req.wLength=0x1200;我改为了Request.Req.wLength=0x0012后错误依旧!您帮我看看18楼的程序是否正确吧,其实大部分都是贵公司例程里的,我只是稍作了修改,一些基本的读写函数是没问题的,就是控制传输的数据阶段总是失败!您能帮我分析分析是什么么原因吗?另外程序中有将CH375B设为低速模式的子程序,具体如下: void Set_Freq(void) { Ch375_Wr_Cmd_Port(0x0b); // 切换使375B进入低速模式 Ch375_Wr_Dat_Port(0x17); Ch375_Wr_Dat_Port(0xd8); } 这里的几个命令和数据为什么要这样写?
操作鼠标键盘之前把CH375设置成低速模式,按照这样写就可以了,设备连接之后测试一下D+,D-上面的电压
七画 { M } 等级:3 发表:1 回复:13 注册时间:2010-4-2 发表于:2010-5-12 5:24:00,来源于:58.19.57.210 ,发贴心情: ----------------------------------------------------------------------------------------------------- TO:_study_ { M } 如果正常,电压应该是多少呢?我芯片是3.3V供电的,另外D+、D-需要反接吗?我用CH375B,谢谢
我也碰到各楼主同样的问题,D7始终都是为1,一直没找到原因,请问楼主是怎么样解决的。
如果采用的芯片是CH375B的话,只需要设置成低速模式就可以了。而对于全速设备是不需要设置低速模式的,至于怎么确认是全速设备还是低速设备,建议你把USB设备插到USB口上面去,用万用表测试下,UD+为3.3V左右,UD-在0V左右,是全速设备,反之则为低速设备。
那你看一下在读取数据的时候A0是不是为0,如果为A0为1则会出现你说的情况
谢谢!是全速设备,读数据时测得A0是为高电平
这样就不对了,读数据的时候A0一定要为0
在获取芯片及固件版本的值是为B7 发测试数据55,返回的值是AA, FF时则返回80,在设置USB模式时返回的值又是正确的0x51,为什么会这样呢?
麻烦大家看看, unsigned char CH375_Read() //读数据 { unsigned char Temp; DATA_PORT = 0xFF; //51单片机IO作输入,先置高 CH375_CS = 0; //打开片选 CH375_A0 = 0; //数据模式 CH375_RD = 0; //打开读使能 Delay(3); //稍作延时 Temp = DATA_PORT; //读取端口上的数据 CH375_RD = 1; //关闭读使能 CH375_CS = 1; //关闭片选 CH375_A0 = 1; //恢复A0为高电平 return Temp; //返回读到的值 }
unsigned char CH375_Wait_Int() //等待中断信号,即INT引脚上产生低电平,并获取中断状态码,获取后INT恢复高电平,以产生下一次中断信号 { unsigned char Temp; CH375_INT = 1; //IO作输入先置高 while(CH375_INT); //等待中断 CH375_Write_Cmd(CMD_GET_STATUS); //产生操作完成中断,获取中断状态 Temp = CH375_Read_Dat(); CH375_INT = 1; return (Temp); }
unsigned char CH375_Init() { unsigned char i=0,Test; CH375_Write_Cmd(CMD_GET_IC_VER); // 获取芯片及固件版本 正常为0xB7 UART_SendStr("CH375固件版本:"); i = CH375_Read_Dat(); // 版本 UART_SendHex(i); UART_SendEnter();
CH375_Write_Cmd(CMD_CHECK_EXIST); CH375_Write_Dat(0x55); Test = CH375_Read_Dat(); UART_SendHex(Test); UART_SendEnter();
CH375_Write_Cmd(CMD_CHECK_EXIST); CH375_Write_Dat(0xFF); Test = CH375_Read_Dat(); UART_SendHex(Test); UART_SendEnter();
CH375_Write_Cmd(CMD_SET_USB_MODE); // 设置USB工作模式 CH375_Write_Dat(6);
for(i=0;i<250;i++) { Delay(10); if(CH375_Read_Dat()==CMD_RET_SUCCESS ) { UART_SendStr("操作成功...\r\n"); return 0; // 操作成功 } }
return 1; }
unsigned char CH375_InitDisk() { unsigned char status,i,j=0; status = CH375_Wait_Int(); UART_SendStr("Wait_Int...\r\n"); UART_SendHex(status); if(status==USB_INT_DISCONNECT) return 1; // USB设备断开
while(1) { CH375_Write_Cmd(CMD_DISK_INIT); // 初始化USB存储器 status = CH375_Wait_Int(); // 等待中断并获取状态 UART_SendStr("Debug...1\r\n"); UART_SendHex(status); if(status==USB_INT_SUCCESS) break; } UART_SendStr("Debug...\r\n"); while(1) { j++; CH375_Write_Cmd(CMD_DISK_SIZE); // 获取USB存储器的容量 status=CH375_Wait_Int(); // 等待中断并获取状态 if(status==USB_INT_SUCCESS) break; else { Delay(1000); CH375_Write_Cmd(CMD_DISK_R_SENSE); // 获取USB存储器的容量 status=CH375_Wait_Int(); // 等待中断并获取状态 if(status==USB_INT_SUCCESS) // 出现错误 continue; else return 1; } if(j==5) return 1; } for(i=0;i!=5;i++) { CH375_Write_Cmd( CMD_DISK_READY ); status=CH375_Wait_Int(); if(status==USB_INT_SUCCESS) return 0; } return 1; }
还有一种可能行,就是D7数据线虚焊了。仔细检查一下。