求助CH375B做 Host读U盘

小弟先谢过了!!! 我有个地方不知道怎么处理:就是我用CH375的串口方式去读U盘。在读的例程中每次读取1个扇区就是512 字节的数据。  同时我的程序中有一处要使用一个外部中断处理一个IIC的通信的任务,于是我发现如果当CH375正在读U盘的时候 产生中断,那么 回来的话CH375就像死掉了一样不能继续读数据了。 请问这该如何处理才能让CH375尽快恢复状态?我试过重新初始化U盘,但并不是每次都能成功。这个应该是ch375 的问题吧??? 求助~~~

1,如果在读取512字节过程中来中断的话,那么中断打断时间不能超过2MS左右,如果时间过长可能会出现U盘挂起的现象。如果重新初始化还不成功的话,那么,你需要看下CH375给你返回的错误码是多少?或者你把你的初始化的程序帖出来看下,看下有没有需要修改的地方。


我贴出来阿,麻烦帮我分析下阿~~: 代码在几个函数里,我把弄出来了;

usb_state = USB_DISCONNECT ; #if DEBUG_PRINTF sea_printf("...begin to init CH375... "); #endif CH375_INT_FLAG = 1 ;

Status = mSetBaudrate( 1 ); //修改串口的 波特率 mStopIfError( Status ) ;

#if TEST_CH375_PORT unsigned char c ; CH375_WR_CMD( CMD_CHECK_EXIST ); /* ²âÊÔ¹¤×÷״̬ */ DelayMs(1); CH375_WR_DAT( 0x55 ); /* ²âÊÔÊý¾Ý 55->aa,*/ DelayMs(1); c = CH375_RD_DAT( ); c=c+1; #endif //TEST_CH375_PORT

/* 初始化 */ CH375_WR_CMD( CMD_SET_USB_MODE ); DelayMs(0x01); CH375_WR_DAT( 6 ); DelayMs(0x01);

if ( CH375_RD_DAT( ) == CMD_RET_SUCCESS ) { #if DEBUG_PRINTF sea_printf("CH375 initialize ok.\n"); #endif

usb_state = USB_CH375_OK ; return( 0x00 ); } else { usb_state = USB_DISCONNECT ; return( USB_TIMEOUT ); }

//下面是等待U盘的中断 void wait_usb() { int mIntStatus ; do { mIntStatus = mWaitInterrupt(); // DelayMs(0x10); } while (mIntStatus != USB_INT_CONNECT); // usb_state = USB_CONNECT ; }

// /* 初始化U盘 */ CH375_WR_CMD( CMD_DISK_INIT ); DelayMs( 0x10 ); //ÕâÀïµÄÑÓʱҲҪµ÷Õû£¿£¿£¿ mIntStatus = mWaitInterrupt( ); if ( mIntStatus != USB_INT_SUCCESS ) /* ·µ»ØUSB_INT_SUCCESS±êʶ²Ù×÷³É¹¦ */ { usb_state = USB_DISCONNECT ; return( USB_TIMEOUT ); }


另外出现问题时是:一直在初始化CH375,也就是发送CH375_WR_CMD( CMD_SET_USB_MODE ); 这条命令不成功,即发送后没有响应。。。可是把U盘拔下来再插上去就可以了。。。 但是这个做成产品怎么可以呢??总不能让用户不停的拔插U盘吧 ??? 求助阿~~


检测到设备拔除之后,是不需要设置CH375的模式的,还有就是初始化函数可以进行修改下,请拿这部分代码去测试下看你的U盘可以不可以初始化: UINT8 mInitDisk( void ) { /* 初始化磁盘 */ UINT8 Status,i,j=0; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ Status = CH375_RD_DAT_PORT( ); if ( Status == USB_INT_DISCONNECT ) return( Status ); /* USB设备断开 */ CH375_WR_CMD_PORT( CMD_DISK_INIT ); /* 初始化USB存储器 */ Status = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( Status != USB_INT_SUCCESS ) return( Status ); /* 出现错误 */ while(1){j++; CH375_WR_CMD_PORT( CMD_DISK_SIZE ); /* 获取USB存储器的容量 */ Status = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( Status == USB_INT_SUCCESS ) break; /* 出现错误 */ /*这里需要加上这个之后才可以,正确的做法也是这样*/ CH375_WR_CMD_PORT( CMD_DISK_R_SENSE ); /* 获取USB存储器的容量 */ mDelaymS( 250 ); if(j==5) return(Status); } Status = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( Status == USB_INT_SUCCESS ){ /* 出现错误 */ for(i=0;i!=5;i++){ printf("Ready\n"); CH375_WR_CMD_PORT( CMD_DISK_READY ); /* 获取USB存储器的容量 */ Status = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( Status == USB_INT_SUCCESS ) break; /* 出现错误 */ CH375_WR_CMD_PORT( CMD_DISK_R_SENSE ); /* 获取USB存储器的容量 */ mDelaymS( 250 ); } } return( 0 ); /* U盘已经成功初始化 */ }


(1)如果单片机具备10K以上程序空间、600字节以上RAM,那么可以建议使用子程序库,即使这些资源不具备,我们另有一款内置文件系统的CH376芯片,这两种方式对U盘的兼容都很高 (2)这样子肯定不行,不过问题基本都是程序上的,CH375的命令和数据之间的延时都微秒级的,如果是刚接触操作U盘,建议先用我们的例程去调试,熟悉后再根据需要修改移植。下载CH375EVT.ZIP,参看MISCELL下的例程,这些例程仅需要修改CH375的地址、中断线及根据单片机主要调整微/毫秒级延时即可,其余部分不要修改


上面的大哥你的程序是不是有问题阿??? CH375_WR_CMD_PORT( CMD_DISK_READY ); /* 获取USB存储器的容量 */ 获取容量是CMD_DISK_READY ? 还有你不用设置SET_USB_MODE的吗? 能给个经过测试的代码吗??? 拜谢!!!


后面注释没改,参考CH375EVT.ZIP中MISCELL下的例程吧


上面的注释没去掉不好意思,你说说的模式是在你程序一上来延时50MS之后就需要设置的,然后在检测U盘连接,完成之后在去初始化U盘,上面这部分只做了初始化U盘的部分,没有把全部程序帖出来,因为前面的程序和你的基本是类似的,所以就没有帖,你应该去看下命令代码,因为写程序的时候可能直接就是复制的,所以后面的注释没有去掉。还有你上面的程序如果仅仅做一个DISK_INIT的话,可能很多U盘都不会支持的。上面给你帖的程序是为了提高你U盘的兼容性。并且在这里说一下,我们帖出的程序都是经过测试的,如果有任何问题你可以电话或者BBS来咨询。


“还有你上面的程序如果仅仅做一个DISK_INIT的话,可能很多U盘都不会支持的。“

-----那应该怎么样才能支持更多的优盘阿大哥???


前面已经说了,用我们的子程序库或CH376


还有个问题请教。。。 我想实现一个功能,就是在读取U盘 的过程中能准确地得知U盘被拔出这一操作。也就是说在U盘操作过程中如果他被拔出要能马上知道。请问CH375 是如何实现这一功能的?我试了很久不知道怎么处理 谢谢先!!!


在操作U盘的任何时候,只要插拔U盘的话都会产生中断。中断状态为0X16。


中断状态要自己读取是吗?那我是不是要在中断中判断状态 才知道是不是这个事件呢?


中断状态需要自己来读取,只有判断出这个状态才知道U盘拔出事件。


再请教各位大哥个问题:谢谢先!!! U盘正在被高速读取中,此时断开电源再 接通电源 ,程序无法正常初始化CH375和U盘,也即发送CMD_SET_USB_MODE命令无响应,任何操作无反应,请问该如何处理???是不是要RESET ch375?? 救命阿~~


只有登录才能回复,可以选择微信账号登录