CH375和CH372常见问题的解决[讨论]

CH375和CH372常见问题的解决 1:问:U盘插在板子上,然后上电,工作正常。板子先上电,然后插U盘,板子检测不到U盘插上和拔除。 答:该问题是由于U盘插上时,电源对U盘供电,电源电压产生波动,导致CH375复位,不产生中断引起的。可以在USB口上的电源和地之间接一个大于200UF的电解电容。 2:若要使用3.3V电压对CH375供电,要求VCC和V3引脚接3.3V,与CH375相连的处理器的电压也要是3.3V,除USB口的D+、D- 外,任何与CH375相连的引脚都必须是3.3V的。 3:问:当在我没启动CH375设备模式时居然插在算计上能找到USB设备,不过不能装驱动。 答:如果这种情况属实则是CH375没有正常复位。 4:问:我用LPC的单片机作模拟IO口时做输入时不正确。 答:用模拟IO时序要掌握好,IO口作输入时要往口上写入1。 5:问:C8051F单片机可不可以用你们的U盘读写的库函数, 答:可以,不过C8051F大部分是单周期指令,所以要考虑速度,应用的时候要注意MOVX指令的时间周期,(61就可以了);或者用我们的第5个库,读写CH375靠用户自己设定。 6:问:是不是可以用CH375作主机CH372作从机进行通讯,并且不处理描述符? 答:可以。 7:问:直接写入U盘的数据为何不能格式化掉? 答:这牵扯到文件格式,对于现代格式化都是高级格式化(软盘除外),格式化就是将引导区的文件信息删除,对于存在存储器的具体文件可能还在原处。用一些工具是可以看到文件的存在的。 所以对于直接写入的数据计算机就有可能不理会。这就是你所说的删除不掉。这不会对使用U盘有影响。如果想格式化掉可能需要重新分区。 8:问:我的U盘插上为什麽出现错误91? 答:这是因为库不支持你的U盘格式建议你重新格式化。格成FAT16或者FAT12。 9:问:我的U盘写入时为什麽在写入64K是可以,写入90K时长度变成20多K呢, 答:我们定义的长度是16位的,当自动修改长度时只能识别64K之内,当长度超过64K时要手动修该长度,或者重新定义长度为32位。 10:问:下位机每次通过端点2上传4字节,为什麽上位机有时候会收到一串其他数据? 答:这要看你写的具体程序。下位机每次发过一组数据后,没有查看上位机是否接收就发第2组。假如第一次还没被上传就写入了第二组,数据被覆盖掉。 11:问:为什麽我在用CH375直接读取U盘设备描述符时会读取不成功,而其他向U盘初始化等命令能成功。 答:第一是否设置模式。第二是否设备插上来延时充分。第三在给U盘操作时要对U盘复位一次,再操作。因为有的USB设备自己没有复位功能,要依靠外界各其复位后才能工作。PC机给所有刚插上来的USB设备都是先复位总线再操作的。CH375中的初始化U盘命令也是先复位总线再操作的。 12:问:在用CH375做HOST时,使用内部U盘读写固件操作U盘进行扇区操作均正常,但是当用程序进行SETUP过程时出现问题,程序执行过程: a.初始化CH375芯片:复位芯片,发送测试命令,发送设置工作模式(0x06)命令,等待USB设备连接。 b.USB设备连接产生中断后,发送获取设备描述符命令,此时CH375返回中断状态字为0x20,无论USB设备是U盘还是摄像头均出现此错误,运行环境:CPU:89S52 ,11.0592Mhz,附源程序。 答:错误码20H说明目标USB设备应答超时,可能原因有: a、目标设备尚未正常工作,例如未连接,或者已连接但未初始化好 解决方法,确认连接后再延时数百毫秒 b、通讯错误,例如,晶振频率不准(电容不符),非标准USB信号线 解决方法,1、调整硬件,2、用SET-RETRY命令带参数25H、8FH增加重试次数 c、目标USB设备连接时瞬时电流太大(降低了电源电压),导致CH375不正常, 解决方法:分开供电,或者为USB设备串入限流电阻或者电感 d、CH375操作时序不佳,导致数据不稳定,例如CMD与DATA之间不足2.5uS等 另外,您若是用I/O引脚模拟并口读写的,要考虑在模拟到一半时出现中断的情况, 如果关中断,又会影响速度。如果是51单片机,想省点I/O引脚,可以用 MOVX @R0,A 和 MOVX A,@R0,这样P2口只用两个:CS和A0,其它随便用。 顺便unsigned char u1_read_data(void) { unsigned char ch; U1_A0 = 0 ; U1_CS = 0 ; P0 = 0xff ; // 放在RD=0之前更安全,否则如果之前P0输出0,CH375输出1会短路 RD = 0 ; // CH375开始输出数据 P0 = 0xff ; // 原来的这一行就当延时吧,因为RD=0到CH375输出数据要20纳秒 ch = P0 ; RD = 1 ; U1_CS = 1; return ch ; } 13:问:341可以单独控制外部设备吗? 答:341的开发就是考虑在没有处理器使用的,假如要控制剧电器或者发光管,只要用CH341+74HC273就可以了。

谢谢板主。波特率配制问题得到解决。[Emot]6[/Emot][Emot]6[/Emot][Emot]6[/Emot]


多谢,很有价值


很好,收藏!


收益匪浅!


以下是我部分程序,前面执行都可以,就是read_sector中返回err=0x1f.请问是为什么?

write_command(CMD_CHECK_EXIST); /* 1. 测试工作状态是否正常? */ write_data(0x5a); /* 测试数据 */ c = read_data(); for(j=0;j<100;j++) /* 延时等待U盘进入正常工作状态 */ for(i=0; i<10000; i++); for(j=0;j<100;j++) for(i=0; i<10000; i++);

write_command(CMD_SET_USB_MODE);/* 2. 设置USB工作模式 */ write_data(6); for (i=50000; i!= 0; i--) /* 等待操作成功,等待10uS-20uS */ { c = read_data(); if ( c == CMD_RET_SUCCESS ) break; }

while(1) {  c = wait_interrupt( );    /* 3. 等待U盘连接 */  if( c == USB_INT_CONNECT ); break; }

write_command(CMD_SET_USB_MODE);  /* 4. 复位 */ write_data(7); for (i=50000; i!= 0; i--)   /* 等待操作成功,等待10uS-20uS*/ {    c = read_data();    if ( c == CMD_RET_SUCCESS ) break; }

write_command(CMD_SET_USB_MODE);  /* 5. 设置USB工作模式 */ write_data(6); for (i=50000; i!= 0; i--)   /* 等待操作成功,待10uS-20uS */ {    c = read_data();    if ( c == CMD_RET_SUCCESS ) break; } while(1) { /* 6. 等待U盘连接 */ c = wait_interrupt( ); if( c == USB_INT_CONNECT ); break; }

for(i=0;i<10000; i++) { write_command(CMD_SET_USB_MODE); /* 4. 复位 */ write_data(7); for (j=50000; j!= 0; j--) /* 等待操作成功,等待10uS-20uS */ { c = read_data(); if ( c == CMD_RET_SUCCESS ) break; }

c = init_disk(); if(c) continue; c = read_sector( 0,1); if(c) continue; }

unsigned char init_disk() { unsigned char c;

write_command( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ c = read_data(); if ( c == USB_INT_DISCONNECT ) return( c ); /* USB设备断开 */ write_command( CMD_DISK_INIT ); /* 初始化USB存储器 */ c = wait_interrupt(); /* 等待中断并获取状态 */ if ( c == USB_INT_SUCCESS ) return( 0 ); /* U盘已经成功初始化 */ else return( c ); /* 出现错误 */ }

unsigned char read_sector( unsigned long start, unsigned char count ) { /* iLbaStart 是准备读取的线性起始扇区号, count 是准备读取的扇区数 */

unsigned char err; unsigned char *ptr; unsigned char len; unsigned int i; unsigned char buf[1024];

write_command( CMD_DISK_READ ); /* 从USB存储器读数据块 */ write_data( (unsigned char)start ); /* LBA的最低8位 */ write_data( (unsigned char)( start >> 8 ) ); write_data( (unsigned char)( start >> 16 ) ); write_data( (unsigned char)( start >> 24 ) ); /* LBA的最高8位 */ write_data( count ); /* 扇区数 */ ptr = &buf[0]; for ( i = count * CH375_BLK_PER_SEC; i != 0; i -- ) /* 数据块计数 */ { err = wait_interrupt( ); /* 等待中断并获取状态 */ if ( err == USB_INT_DISK_READ ) /* USB存储器读数据块,请求数据读出 */ { write_command( CMD_RD_USB_DATA ); /* 从CH375缓冲区读取数据块 */ len = read_data( ); /* 后续数据的长度 */ while ( len ) /* 根据长度读取数据 */ { *ptr = read_data( ); /* 读出数据并保存 */ ptr ++; len --; } return ( 0 ); //write_command( CMD_DISK_RD_GO ); /* 继续执行USB存储器的读操作 */ } else break; } if ( i == 0 ) err = wait_interrupt( ); if ( err == USB_INT_SUCCESS ) return( 0 ); else return( err ); }


楼上和我的情况差不多,我用的U盘是天朗A10 64M。读扇区内容的时候,写地址,扇区数成功,能读出头一段64个字节,读第二段的64字节时,返回只能读0字节,在强行读时就返回错误码1FH。不知道是哪个地方出问题?


上面贴的程序中多了一个return,提前返回了。不过,估计还有其它问题存在。 通常能读第一个64字节,那么也能读第二个64字节,如果不能,通常是循环程序有问题。 另外,在读写U盘程序中,不宜用单步跟踪,有些U盘一跟踪就会不工作。 如果要跟踪,那么只能在命令与命令之间停顿,单个命令执行时间不能超过2mS。 各家做U盘的处理有差别,有些U盘在初始化后还需要发些其它命令才能工作。 最好用WCH的文件级子程序库试试,里面针对这些兼容性问题做了很多处理,可能会好些。


读天朗A10U盘的问题解决了。下面部分源代码 /******************************************************************/ /*名称: ReadSector(ulong Sectors,uchar xdata *pr) */ /*描述: 读扇区内容 每次读1个扇区 */ /*输入参数:扇区地址,接收缓冲区指针 */ /*输出参数:1:读成功 0:读失败 */ /*******************************************************************/ uchar ReadSector(ulong Sectors,uchar xdata *pr) {union longEx Secaddr; uchar n,mBlockCount,mLength; Secaddr.lng=Sectors; CH375_CMD_PORT=CMD_DISK_READ; _nop_(); _nop_(); CH375_DAT_PORT=Secaddr.bytes[3]; CH375_DAT_PORT=Secaddr.bytes[2]; CH375_DAT_PORT=Secaddr.bytes[1]; CH375_DAT_PORT=Secaddr.bytes[0]; CH375_DAT_PORT=1;/*扇区数*/ n=Wait_Interrupt(); if(n!=USB_INT_DISK_READ) return FALSE; for(mBlockCount=0;mBlockCount<8;mBlockCount++) { CH375_CMD_PORT=CMD_RD_USB_DATA; _nop_(); _nop_(); mLength=CH375_DAT_PORT; while(mLength) { *pr++=CH375_DAT_PORT; n=CH375_DAT_PORT; mLength--; } wait_1mS(10);/*这里延时是关键*/ CH375_CMD_PORT=CMD_DISK_RD_GO;/*继续执行读操作*/ n=Wait_Interrupt(); if(n!=USB_INT_DISK_READ) break; } if(n==USB_INT_SUCCESS) return TRUE; else return FALSE; }


n=CH375_DAT_PORT;是调试用,忘了删掉。


fat文件的读写有没有库函数啊?


各位好! 我想问一下ch372和51单片机如何USB通讯?单片机用汇编如何初始化ch372?片选 总线 中断都有,就是通不起来! 如蒙指教,不胜感谢!


大家好! 我想问一下 用ch375作为usb设备芯片开发usb设备都需要哪些工具? 请各位赐教,在此表示感谢!


大家好?请问那位大侠做过USB芯片和单片机连接通信,读取数据的工程,比如说PIC单片机,上位机电脑要读取单片机测试来的数据,刚上电要监测单片机工作与否,发送测试命令,单片机回复信息在电脑上是怎么显示的,是不是有软件?读去数据像不像U盘,如果单片机的数据是一些纯数值数据?


网上下载关于CH372评估板的资料,通过USB将下位机(单片机)和PC机进行数据上下传输.


各位大虾,请问我用弹片机往ch375缓冲区里写数,为什么写不进呢.会有什么容易出现的错误呢?


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