ch375收到很多USB_INT_EP0_OUT中断,但是数据长度为0

用ch375作为USB设备的外部固件模式,在枚举阶段就收到USB_INT_EP0_OUT中断,读出的数据长度为0,这是怎么回事?现在枚举也过不了呀

这个主要是获取设备描述符,获取配置描述符之类的控制传输,在完成一次传输之后会返回一个0长度的包做为响应。枚举不过需要看下你首先有没有获取到设备描述符的命令。你可以借助BUSHOUND这个软件看下数据在分析原因。


我的程序大概是这样的:中断处理函数在收到USB_INT_EP0_SETUP中断后,就向ch372任务发一条消息,ch372任务被唤醒后处理相关事宜(这时处于开中断状态),如读取usb请求,返回描述符等。这样就会收到很多USB_INT_EP0_OUT中断,并且读出的数据长度为0。

我看你们的例子程序中断处理完全都是在中断处理函数中进行的,改成你们那种方式后就不会出现这种现象了。

我前面那种方式会导致时序不正确还是什么原因?


按照你的描述可能是丢中断了。建议你按照我们的操作流程来操作。


新手求解,程序运行到”检测U盘是否插入的地方”就重新单片机了 #include #include #include

#define EN_DISK_QUERY 1 /* 启用磁盘查询 */

#include "HAL.H" #include "DEBUG.H" #include "FILE_SYS.H" #include "CH376INC.H"

UINT8 xdata buf[64];

void main(void) { UINT8 i, s; UINT16 len; P_FAT_DIR_INFO pDir; UINT8 xdata SrcName[64]; UINT8 xdata TarName[64]; mDelaymS( 100 ); /* 延时100毫秒 */ mInitSTDIO( ); /* 为了让计算机通过串口监控演示过程 */ printf( "系统启动---Start\n" );

s = mInitCH376Host( ); /* 初始化CH376 */ ; mStopIfError( s ); /* 其它电路初始化 */

while ( 1 ) { printf( "等待U盘或者SD卡插入---Wait Udisk/SD\n" );

while ( CH376DiskConnect( ) != USB_INT_SUCCESS ) { /* 检查U盘是否连接,等待U盘插入,对于SD卡,可以由单片机直接查询SD卡座的插拔状态引脚 */ mDelaymS( 100 ); }

mDelaymS( 200 ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */

/* 对于检测到USB设备的,最多等待100*50mS,主要针对有些MP3太慢,对于检测到USB设备并且连接DISK_MOUNTED的,最多等待5*50mS,主要针对DiskReady不过的 */ for ( i = 0; i < 100; i ++ ) { /* 最长等待时间,100*50mS */ mDelaymS( 50 ); printf( "准备好了? ---- Ready ?\n" ); s = CH376DiskMount( ); /* 初始化磁盘并测试磁盘是否就绪 */ if ( s == USB_INT_SUCCESS ) break; /* 准备好 */ else if ( s == ERR_DISK_DISCON ) break; /* 检测到断开,重新检测并计时 */ if ( CH376GetDiskStatus( ) >= DEF_DISK_MOUNTED && i >= 5 ) break; /* 有的U盘总是返回未准备好,不过可以忽略,只要其建立连接MOUNTED且尝试5*50mS */ }

if ( s == ERR_DISK_DISCON ) { /* 检测到断开,重新检测并计时 */ printf( "设备已断开---Device gone\n" ); continue; }

if ( CH376GetDiskStatus( ) < DEF_DISK_MOUNTED ) { /* 未知USB设备,例如USB键盘、打印机等 */ printf( "Unknown device\n" ); goto UnknownUsbDevice; } i = CH376ReadBlock( buf ); /* 如果需要,可以读取数据块CH376_CMD_DATA.DiskMountInq,返回长度 */ if ( i == sizeof( INQUIRY_DATA ) ) { /* U盘的厂商和产品信息 */ buf[ i ] = 0; printf( "U盘厂商---UdiskInfo: %s\n", ((P_INQUIRY_DATA)buf) -> VendorIdStr ); }

/* 读取文件 */ strcpy( SrcName, "\\C51\\CH376HFT.C" ); /* 源文件名,多级目录下的文件名和路径名必须复制到RAM中再处理,而根目录或者当前目录下的文件名可以在RAM或者ROM中 */ strcpy( TarName, "\\NEWFILE.TXT" ); /* 目标文件名 */ printf( "打开文件 --- Open\n" ); s = CH376FileOpenPath( SrcName ); /* 打开文件,该文件在C51子目录下 */ if ( s == ERR_MISS_DIR || s == ERR_MISS_FILE ) { /* 没有找到目录或者没有找到文件 */ /* 列出文件,完整枚举可以参考EXAM13全盘枚举 */ if ( s == ERR_MISS_DIR ) strcpy( buf, "\\*" ); /* C51子目录不存在则列出根目录下的文件 */ else strcpy( buf, "\\C51\\CH376*" ); /* CH376HFT.C文件不存在则列出\C51子目录下的以CH376开头的文件 */ printf( "列举所有文件---List file %s\n", buf ); s = CH376FileOpenPath( buf ); /* 枚举多级目录下的文件或者目录,输入缓冲区必须在RAM中 */ while ( s == USB_INT_DISK_READ ) { /* 枚举到匹配的文件 */ CH376ReadBlock( buf ); /* 读取枚举到的文件的FAT_DIR_INFO结构,返回长度总是sizeof( FAT_DIR_INFO ) */ pDir = (P_FAT_DIR_INFO)buf; /* 当前文件目录信息 */ if ( pDir -> DIR_Name[0] != '.' ) { /* 不是本级或者上级目录名则继续,否则必须丢弃不处理 */ if ( pDir -> DIR_Name[0] == 0x05 ) pDir -> DIR_Name[0] = 0xE5; /* 特殊字符替换 */ pDir -> DIR_Attr = 0; /* 强制文件名字符串结束以便打印输出 */

/* 打印名称,原始8+3格式,未整理成含小数点分隔符 */ printf( "*** EnumName: %s\n", pDir -> DIR_Name ); } xWriteCH376Cmd( CMD0H_FILE_ENUM_GO ); /* 继续枚举文件和目录 */ xEndCH376Cmd( ); s = Wait376Interrupt( ); } if ( s != ERR_MISS_FILE ) mStopIfError( s ); /* 操作出错 */

/*--- 新建一个文件 ---*/ printf( "新文件被创建---Create\n" ); s = CH376FileCreatePath( TarName ); /* 新建多级目录下的文件,支持多级目录路径,输入缓冲区必须在RAM中 */ mStopIfError( s ); printf( "新文件被写入---Write\n" ); strcpy( buf, "找不到/C51/CH376HFT.C文件,欢迎使用一鸣电子模块!\xd\n" ); s = CH376ByteWrite( buf, strlen(buf), NULL ); /* 以字节为单位向当前位置写入数据块 */ mStopIfError( s ); printf( "新文件被关闭---Close\n" ); s = CH376FileClose( TRUE ); /* 关闭文件,对于字节读写建议自动更新文件长度 */ mStopIfError( s );

printf("\n"); strcpy( TarName, "\\YI.TXT" ); /* 目标文件名 */ /*--- 新建另外一个文件;文件名:yimingtest.txt ---*/ printf( "创建另外一个文件---Create\n" ); s = CH376FileCreatePath( TarName ); mStopIfError( s ); printf( "新文件被写入----Write\n" ); strcpy( buf, "恭喜发财了!\xd\n" ); s = CH376ByteWrite( buf, strlen(buf) , NULL); mStopIfError ( s ); printf( "文件被关闭 --- Close\n" ); s = CH376FileClose(TRUE); mStopIfError( s );

/*--- 追加文件数据的例子 ---*/ printf( "\n" ); strcpy( SrcName, "\\YI.TXT" ); s = CH376FileOpenPath( SrcName ); printf( "Error: %02X\n", (UINT16)s ); if( s == USB_INT_SUCCESS ) { //成功打开文件 strcpy( buf, "是不是要请哥们吃饭了呢?\xd\n" ); CH376ByteLocate(0xFFFFFFFF); s = CH376ByteWrite( buf, strlen(buf) , NULL); mStopIfError ( s ); printf( "文件被关闭 --- Close\n" ); s = CH376FileClose(TRUE); mStopIfError( s ); } else mStopIfError( s ); /*--- 读取文件数据的例子 ---*/ printf( "\n" ); printf( "读取文件数据的例子:\n" ); strcpy( SrcName, "\\YI.TXT" ); s = CH376FileOpenPath( SrcName ); printf( "Error: %02X\n", (UINT16)s ); if( s == USB_INT_SUCCESS ) { len = CH376GetFileSize(); CH376ByteLocate( 0 ); CH376ByteRead(buf,len,NULL); printf( "%s \n", buf);

mStopIfError ( s ); printf( "文件被关闭 --- Close\n" ); s = CH376FileClose(TRUE); mStopIfError( s ); } else mStopIfError( s ); } else { /* 找到文件或者出错 */ mStopIfError( s ); }

UnknownUsbDevice: printf( "设备拔出 --- Take out\n" ); while ( CH376DiskConnect( ) == USB_INT_SUCCESS ) { /* 检查U盘是否连接,等待U盘拔出 */ mDelaymS( 100 ); } mDelaymS( 200 ); }


你把原理图发到我邮箱。正常连接的情况下,我们芯片不对导致你单片机复位的,单片机复位因素主要有电源不稳定,复位引脚有复位信号,看门狗复位,你检测下是什么情况导致你单片机复位的


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