U盘是FAT格式的,前几天用CH375V来读能不能读出容量大小,但是打不开指定的文件,运行到这儿i = CH375FileOpen();死了. 今天我再去试,发送连容量大小都读不出来了,可能是那方面的原因?
你说的容量大小读取不了,那前面的CH375LibInit(库初始化)和 CH375DiskReady( 查询磁盘是否准备好)能正常通过吗?操作不成功时,你得查看一下返回的是什么错误代码。
可以正常通过,返回值是0X00,而且写一个字节,读出来是反的也正确
你用的是什么单片机??(速度是多少??)还有就是 CH375DiskReady()这个函数你确定可以通过??
确定可以通过,返回是OXOO,我特意看了一下 用的是S3C44BOX,库文件是CH375HF9.DLL,和CH375HF9.H
那你可以不可以将你的延时子程序(延时1US的函数)以及三个读写子函数帖出来看下。
void xWriteCH375Cmd(U8 mCmd) /* 外部定义的被CH375程序库调用的子程序,向CH375写命令 */ { Delay(2); CH375Cmd = mCmd; Delay(2); }
void xWriteCH375Data(U8 mData) /* 外部定义的被CH375程序库调用的子程序,向CH375写数据 */ { CH375Dat = mData ; Delay(2); }
U8 xReadCH375Data(void) /* 外部定义的被CH375程序库调用的子程序,从CH375读数据 */ { U8 mData; Delay(2); mData = (U8)CH375Dat; return(mData); }
/**************************************************************************** 【功能说明】通用延时函数,延时time个100us time=0: adjust the Delay function by WatchDog timer. time>0: the number of loop time 100us resolution. ****************************************************************************/ static int delayLoopCount=400; void Delay(int time) { int i,adjust=0;
if(time==0) { time=200; adjust=1; delayLoopCount=400; rWTCON=((MCLK/1000000-1)<<8)|(2<<3); //MCLK/1M,Watch-dog disable,1/64,interrupt disable,reset disable rWTDAT=0xffff;//for first update rWTCNT=0xffff;//resolution=64us @any MCLK rWTCON=((MCLK/1000000-1)<<8)|(2<<3)|(1<<5); //Watch-dog timer start }
for(;time>0;time--)
for(i=0;i if(adjust==1) { rWTCON=((MCLK/1000000-1)<<8)|(2<<3);//Watch-dog timer stop i=0xffff-rWTCNT; //1count->64us, 200*400 cycle runtime = 64*i us delayLoopCount=8000000/(i*64); //200*400:64*i=1*x:100 -> x=80000*100/(64*i) } } //*************************************************************************** 是这些吧?
很奇怪,几天前还能读出容量大小的,今天只读出来OMB
void USBInit(void) { U8 i; CH375Reset(); Delay(500 ); /* 延时50ms */ i = CH375LibInit(); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */ mStopIfError(i); xWriteCH375Cmd(CMD_CHECK_EXIST); xWriteCH375Data(0x5A); i=xReadCH375Data(); if(i==0xA5) DebugPrintf("\nUSB Port is right!"); else DebugPrintf("\nUSB Port isn't exist!"); DebugPrintf("\nUSB initialized."); }
void USBMain(void) { U8 i, c, SecCount; U16 NewSize, count; /* 因为RAM容量有限,所以NewSize限制为16位,实际上如果文件较大,应该分几次读写并且将NewSize改为UINT32以便累计 */ U8 *pCodeStr; while(1) { /* 查询CH375中断并更新中断状态,等待U盘插入 */ while(CH375DiskStatus!=DISK_CONNECT) Delay(200); OSIntEnter(); /* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */ /* 有的U盘总是返回未准备好,不过可以被忽略 */ for (i=0; i<10; i++) { DebugPrintf("\nReady ?"); if(CH375DiskReady() == ERR_SUCCESS) break; /* 查询磁盘是否准备好 */ } /* 查询磁盘物理容量 */ DebugPrintf("\nDiskSize"); i = CH375DiskSize(); mStopIfError(i); DebugPrintf("\nTotalSize = %d MB ", (unsigned int)(mCmdParam.DiskSize.mDiskSizeSec >> 11));
/* 读取原文件 */ DebugPrintf("\nOpen"); strcpy((char *)mCmdParam.Open.mPathName, "\\C51\\CH375HFT.C"); /* 文件名,该文件在C51子目录下 */ i = CH375FileOpen(); /* 打开文件 */ if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) { /* 没有找到文件,列出文件 */ if (i == ERR_MISS_DIR) pCodeStr = (U8 *)"\\*"; /* C51子目录不存在则列出根目录下的文件 */ else pCodeStr = (U8 *)"\\C51\\CH375*"; /* CH375HFT.C文件不存在则列出\C51子目录下的以CH375开头的文件 */ DebugPrintf("\nList file %s", pCodeStr); /* 最多搜索前255个文件 */ for (c=0;c<255;c++) { strcpy( (char *)mCmdParam.Open.mPathName, (char *)pCodeStr); /* 搜索文件名,*为通配符,适用于所有文件或者子目录 */ i = strlen((char const *)mCmdParam.Open.mPathName); /* 计算文件名长度,以处理文件名结束符 */ mCmdParam.Open.mPathName[i] = c; /* 根据字符串长度将结束符替换为搜索的序号,从0到255 */ i = CH375FileOpen(); /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */ if (i == ERR_MISS_FILE) break; /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */ /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */ if (i == ERR_FOUND_NAME) { DebugPrintf("\n match file %03d#: %s", (unsigned int)c, mCmdParam.Open.mPathName); /* 显示序号和搜索到的匹配文件名或者子目录名 */ continue; /* 继续搜索下一个匹配的文件名,下次搜索时序号会加1 */ } else { mStopIfError(i); break; } } pCodeStr = (U8 *)"找不到/C51/CH375HFT.C文件\xd\n"; for (i = 0;i != 255;i++) { if((FILE_DATA_BUF[i] = *pCodeStr)== 0) break; pCodeStr++; } NewSize = i; /* 新文件的长度 */ SecCount = 1; /* (NewSize+511)/512, 计算文件的扇区数,因为读写是以扇区为单位的 */ } else { /* 找到文件或者出错 */ mStopIfError(i); /*printf( "Query\n" ); i = CH375FileQuery( ); mStopIfError( i );*/ DebugPrintf("\nRead"); if ( CH375vFileSize > FILE_DATA_BUF_LEN ) { SecCount = FILE_DATA_BUF_LEN / 512; /* 由于演示板用的62256只有32K字节,其中CH375子程序用512字节,所以只读取不超过63个扇区,也就是不超过32256字节 */ NewSize = FILE_DATA_BUF_LEN; } else { /* 如果原文件较小,那么使用原长度 */ SecCount = (CH375vFileSize + 511) >> 9; /* (CH375vFileSize+511)/512, 计算文件的扇区数,因为读写是以扇区为单位的,先加511是为了读出文件尾部不足1个扇区的部分 */ NewSize = (U16)CH375vFileSize; /* 原文件的长度 */ } DebugPrintf( "\nSize=%ld, Len=%d, Sec=%d", CH375vFileSize, NewSize, (U16)SecCount ); mCmdParam.Read.mSectorCount = SecCount; /* 读取全部数据,如果超过60个扇区则只读取60个扇区 */ /*current_buffer = & FILE_DATA_BUF[0]; 如果文件读写的数据的复制方式为"外部子程序",那么需要设置存放数据的缓冲区的起始地址 */ CH375vFileSize += 511; /* 默认情况下,以扇区方式读取数据时,无法读出文件尾部不足1个扇区的部分,所以必须临时加大文件长度以读取尾部零头 */ i = CH375FileRead(); /* 从文件读取数据 */ CH375vFileSize -= 511; /* 恢复原文件长度 */ mStopIfError(i); /*如果文件比较大,一次读不完,可以再调用CH375FileRead继续读取,文件指针自动向后移动 while ( 1 ) { c = 32; 每次读取32个扇区 mCmdParam.Read.mSectorCount = c; 指定读取的扇区数 CH375FileRead(); 读完后文件指针自动后移 处理数据 if ( mCmdParam.Read.mSectorCount < c ) break; 实际读出的扇区数较小则说明文件已经结束 }
如果希望从指定位置开始读写,可以移动文件指针 mCmdParam.Locate.mSectorOffset = 3; 跳过文件的前3个扇区开始读写 i = CH375FileLocate( ); mCmdParam.Read.mSectorCount = 10; CH375FileRead(); 直接读取从文件的第(512*3)个字节开始的数据,前3个扇区被跳过
如果希望将新数据添加到原文件的尾部,可以移动文件指针 i = CH375FileOpen( ); mCmdParam.Locate.mSectorOffset = 0xffffffff; 移到文件的尾部,以扇区为单位,如果原文件是3字节,则从512字节开始添加 i = CH375FileLocate( ); mCmdParam.Write.mSectorCount = 10; CH375FileWrite(); 在原文件的后面添加数据 */ DebugPrintf("\nClose"); i = CH375FileClose(); /* 关闭文件 */ mStopIfError(i);
i = FILE_DATA_BUF[100]; FILE_DATA_BUF[100] = 0; /* 置字符串结束标志,最多显示500个字符 */ DebugPrintf("\nLine 1: %s", FILE_DATA_BUF); FILE_DATA_BUF[100] = i; /* 恢复原字符 */ for(count=0; count { /* 将文件中的小写字符转换为大写 */ c = FILE_DATA_BUF[ count ]; if (c >= 'a' && c <= 'z') FILE_DATA_BUF[count] = c - ('a' - 'A'); } }
//#ifdef EN_DISK_WRITE /* 子程序库支持写操作 */ /* 产生新文件 */ // printf( "Create\n" ); // strcpy( (char *)mCmdParam.Create.mPathName, "\\NEWFILE.TXT" ); /* 新文件名,在根目录下 */ // i = CH375FileCreate( ); /* 新建文件并打开,如果文件已经存在则先删除后再新建 */ // mStopIfError( i ); // printf( "Write\n" ); // mCmdParam.Write.mSectorCount = SecCount; /* 写入所有扇区的数据 */ /* current_buffer = & FILE_DATA_BUF[0]; 如果文件读写的数据的复制方式为"外部子程序",那么需要设置存放数据的缓冲区的起始地址 */ // i = CH375FileWrite( ); /* 向文件写入数据 */ // mStopIfError( i ); // printf( "Modify\n" ); // mCmdParam.Modify.mFileAttr = 0xff; /* 输入参数: 新的文件属性,为0FFH则不修改 */ // mCmdParam.Modify.mFileTime = 0xffff; /* 输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间 */ // mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2004, 5, 18 ); /* 输入参数: 新的文件日期: 2004.05.18 */ // mCmdParam.Modify.mFileSize = NewSize; /* 输入参数: 如果原文件较小,那么新的文件长度与原文件一样长,否则被RAM所限,如果文件长度大于64KB,那么NewSize必须为UINT32 */ // i = CH375FileModify( ); /* 修改当前文件的信息,修改日期和长度 */ // mStopIfError( i ); // printf( "Close\n" ); // mCmdParam.Close.mUpdateLen = 0; /* 不要自动计算文件长度,如果自动计算,那么该长度总是512的倍数 */ // i = CH375FileClose( ); // mStopIfError( i );
/* 删除某文件 */ /* printf( "Erase\n" ); strcpy( (char *)mCmdParam.Create.mPathName, "\\OLD" ); 将被删除的文件名,在根目录下 i = CH375FileErase( ); 删除文件并关闭 if ( i != ERR_SUCCESS ) printf( "Error: %02X\n", (UINT16)i ); 显示错误 *//* 查询磁盘信息 */ // printf( "Disk\n" ); // i = CH375DiskQuery( ); // mStopIfError( i ); // printf( "Fat=%d, Total=%ld, Free=%ld\n", (UINT16)mCmdParam.Query.mDiskFat, mCmdParam.Query.mTotalSector, mCmdParam.Query.mFreeSector ); //#endif OSIntExit(); Delay(200); DebugPrintf("\n请拔出U盘!"); while (CH375DiskStatus != DISK_DISCONNECT) xQueryInterrupt(); /* 查询CH375中断并更新中断状态,等待U盘拔出 */ Delay(200); }
}
延时如果准确的话,那么读写子函数应该没有什么问题,那么在打开文件的时候死在库里面还是返回了错误代码?如果返回,那么请看下返回的错误代码是多少?
是死在库里面了
库文件能不能给源码来调试看看
CH375V会不会有问题?
再帮忙分析一下,同过反汇编看是一直在循环这个函数里了 void xQueryInterrupt( void ) /* 查询中断状态,等待硬件中断 */ { while ( CH375IntStatus == 0 ); /* 子程序库调用该子程序之前CH375IntStatus=0,硬件中断后,由中断服务程序置为非0的实际中断状态后返回 */ }
实际在操作的时候,DISK_READY()函数和FILE_OPEN函数的差别就在于多用了一个DISK_BASE_BUF这个缓冲区,所以建议你先检查下你的RAM会不会有问题,最简单的方法就是往DISK_BASE_BUF缓冲区里面写随即的数,在读出来进行比较看会不会出错,还有就是你的使用ADS1。2编译的时候,是使用小端模式编译的吧
是的,小端模式