logo

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机进行数据上下传输.
no excuse!
各位大虾,请问我用弹片机往ch375缓冲区里写数,为什么写不进呢.会有什么容易出现的错误呢?
这人很懒,什么都没留下
只有登录才能回复,可以选择微信和github账号登录