这完全是你的程序的问题,在Main.C中定义:#define extern,相当于用空代替extern,即定义变量时有没有关键字extern,效果都是一样,造成库头文件中的变量重定义了。 建议修改程序时边修改边编译,以免出现问题时无法回溯
谢谢,我再继续调试,对C51的伪指令使用不大熟悉。
main( ) { UINT8 i, j, k, SecCount; UINT32 NewSize; /* 因为演示板的RAM容量只有32KB,所以NewSize限制为16位,实际上如果文件大于32256字节,应该分几次读写并且将NewSize改为UINT32以便累计 */ UINT16 WriteSizeCount; mDelay100mS( ); /* 延时100毫秒 */
i = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */
while ( 1 ) { while ( CH375DiskStatus < DISK_CONNECT ) { /* 查询CH375中断并更新中断状态,等待U盘插入 */ if ( CH375DiskConnect( ) == ERR_SUCCESS ) break; /* 有设备连接则返回成功,CH375DiskConnect同时会更新全局变量CH375DiskStatus */ mDelay100mS( ); } mDelay100mS( ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */ mDelay100mS( );
/* 检查U盘是否准备好,但是某些U盘必须要执行这一步才能工作 */ for ( i = 0; i < 5; i ++ ) { /* 有的U盘总是返回未准备好,不过可以被忽略 */ mDelay100mS( ); if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查询磁盘是否准备好 */ }
//文件名20090803.txt mCmdParam.Open.mPathName[0] = 0x5c; mCmdParam.Open.mPathName[1] = 0x32; mCmdParam.Open.mPathName[2] = 0x30; mCmdParam.Open.mPathName[3] = 0x30; mCmdParam.Open.mPathName[4] = 0x39; mCmdParam.Open.mPathName[5] = 0x30; mCmdParam.Open.mPathName[6] = 0x38; mCmdParam.Open.mPathName[7] = 0x30; mCmdParam.Open.mPathName[8] = 0x37; mCmdParam.Open.mPathName[9] = 0x2e; mCmdParam.Open.mPathName[10] = 0x54; mCmdParam.Open.mPathName[11] = 0x58; mCmdParam.Open.mPathName[12] = 0x54;
i = CH375FileCreate( ); /* 新建文件并打开,如果文件已经存在则先删除后再新建 */
NewSize = 0x19000; /* 新文件的长度 */ SecCount = (NewSize+CH375vSectorSize-1)/CH375vSectorSize; /* (NewSize+CH375vSectorSize-1)/CH375vSectorSize, 计算文件的扇区数,因为读写是以扇区为单位的 */
mCmdParam.Write.mSectorCount = SecCount; /* 写入所有扇区的数据 */
WriteSizeCount = 0; for(j = 0; j < 16; j++) //4k数据 { FILE_DATA_BUF[WriteSizeCount] = (j&0x0f) + 0x41; WriteSizeCount++; FILE_DATA_BUF[WriteSizeCount] = 0x20; WriteSizeCount++; for(i = 2; i < 254; i++) { FILE_DATA_BUF[WriteSizeCount] = (i&0x0f) + 0x41; WriteSizeCount++; } FILE_DATA_BUF[WriteSizeCount] = 0x0d; WriteSizeCount++; FILE_DATA_BUF[WriteSizeCount] = 0x0a; WriteSizeCount++; } i = CH375FileWrite( ); /* 向文件写入数据 */ WriteSizeCount = 0;
for(k = 0; k < 12; k++) //12*(4+4)=96k数据 { for(j = 0; j < 16; j++) //4k数据 { FILE_DATA_BUF[WriteSizeCount] = (0x0f-(j&0x0f)) + 0x61; WriteSizeCount++; FILE_DATA_BUF[WriteSizeCount] = 0x20; WriteSizeCount++; for(i = 2; i < 254; i++) { FILE_DATA_BUF[WriteSizeCount] = (i&0x0f) + 0x61; WriteSizeCount++; } FILE_DATA_BUF[WriteSizeCount] = 0x0d; WriteSizeCount++; FILE_DATA_BUF[WriteSizeCount] = 0x0a; WriteSizeCount++; } i = CH375FileWrite(); WriteSizeCount = 0; for(j = 0; j < 16; j++) //4k数据 { FILE_DATA_BUF[WriteSizeCount] = (j&0x0f) + 0x41; WriteSizeCount++; FILE_DATA_BUF[WriteSizeCount] = 0x20; WriteSizeCount++; for(i = 2; i < 254; i++) { FILE_DATA_BUF[WriteSizeCount] = (i&0x0f) + 0x41; WriteSizeCount++; } FILE_DATA_BUF[WriteSizeCount] = 0x0d; WriteSizeCount++; FILE_DATA_BUF[WriteSizeCount] = 0x0a; WriteSizeCount++; } i = CH375FileWrite(); } mCmdParam.Modify.mFileAttr = ATTR_ARCHIVE; /* 输入参数: 新的文件属性,为0FFH则不修改 */ mCmdParam.Modify.mFileTime = MAKE_FILE_TIME(11,0,0); /* 输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间 */ mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2009,8,7 ); /* 输入参数: 新的文件日期: 2004.05.18 */ mCmdParam.Modify.mFileSize = NewSize; /* 输入参数: 如果原文件较小,那么新的文件长度与原文件一样长,否则被RAM所限,如果文件长度大于64KB,那么NewSize必须为UINT32 */ i = CH375FileModify( ); /* 修改当前文件的信息,修改日期和长度 */
mCmdParam.Close.mUpdateLen = 0; /* 不要自动计算文件长度,如果自动计算,那么该长度总是CH375vSectorSize的倍数 */ i = CH375FileClose( ); } }
我想尝试写100k的数据到U盘,可是U盘得一直闪烁,不能跳过写100k数据部分,麻烦哪位指教一下。
刚才尝试在每次写数据前更新mCmdParam.Write.mSectorCount数据,我想mCmdParam.Write.mSectorCount对应的是每次实际写入的扇区数,而不是总写入的扇区总数,一开始以为是总写入的扇区总数。
可是写到最后,在PC查看会有絮乱的数据,能帮忙分析一下吗?
刚数了一下数据,最后4k数据出现乱码,哪位指教指教,谢谢。
呵呵,写数据之间做了延时就好了,都解决了。 我想请问每次写扇区大约需要隔多长时间?
只要写成功的话应该就不会出现下一次写出错的现象的。也就是说不存在写数据的时候有写延时的说法。
好的,我后续会继续研究调试。
有人能提供一个写零星数据的例子吗?我刚才尝试在1个扇区只写入16字节的数据,在PC显示的结果又异常。
不可以写零碎数据的,因为在U盘低层操作的话最少操作为1个扇区为基本单位。如果每次写16个字节的话你可以调用我们字节方式读写,或者你把多个16字节组合起来满足512字节在写数据进去就可以了。
我想请问,我用Create函数创建文件时无法将同名文件名先删除再重建,请问是什么原因?谢谢
你首先要确定你的文件名是一样的这样的话是肯定可以先删除在创建的。还有就是你创建的时候有没有给你报错呢?
不好意思,白天有事,我刚调试了一下,CH375FileCreate()后的返回值为0x00;文件名是相同的,奇怪的是我生成文件后,再重新CH375FileCreate()同名的文件及写入不同的数据就无法覆盖原文件,可是在电脑里将文件删了再重新生成就是新的文件数据,麻烦帮忙分析一下。
你所说的无法覆盖原文件是什么意思?我们的库创建文件之后会自动更新文件长度为1个字节的。
不知道你程序的流程是怎样的,下述流程验证过,重新创建可以覆盖先前的数据: printf( "Create\n" ); mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "\\NEWFILE.TXT" ); /* 新文件名,在根目录下 */ i = CH375FileCreate( ); /* 新建文件并打开,如果文件已经存在则先删除后再新建 */ mStopIfError( i ); pCodeStr = "12345\xd\n"; for ( i = 0; i != 255; i ++ ) { if ( ( FILE_DATA_BUF[i] = *pCodeStr ) == 0 ) break; pCodeStr++; } NewSize = i; /* 新文件的长度 */ SecCount = 1; /* (NewSize+CH375vSectorSize-1)/CH375vSectorSize, 计算文件的扇区数,因为读写是以扇区为单位的 */ printf( "Write\n" ); mCmdParam.Write.mSectorCount = SecCount; /* 写入所有扇区的数据 */ i = CH375FileWrite( ); /* 向文件写入数据 */ mStopIfError( i );
printf( "Create\n" ); mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "\\NEWFILE.TXT" ); /* 新文件名,在根目录下 */ i = CH375FileCreate( ); /* 新建文件并打开,如果文件已经存在则先删除后再新建 */ mStopIfError( i );
pCodeStr = "56789\xd\n"; for ( i = 0; i != 255; i ++ ) { if ( ( FILE_DATA_BUF[i] = *pCodeStr ) == 0 ) break; pCodeStr++; }
NewSize = i; /* 新文件的长度 */ SecCount = 1; /* (NewSize+CH375vSectorSize-1)/CH375vSectorSize, 计算文件的扇区数,因为读写是以扇区为单位的 */
printf( "Write\n" ); mCmdParam.Write.mSectorCount = SecCount; /* 写入所有扇区的数据 */
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; /* 不要自动计算文件长度,如果自动计算,那么该长度总是CH375vSectorSize的倍数 */ i = CH375FileClose( ); mStopIfError( i );
我指的覆盖是删除文件后重新创立,早上想到问题所在了,因为我RAM区不够,我在其他场合也将mCmdParam复用为数据缓冲区了,现在每次写U盘前将那一部分RAM清空,现在可以先删除再生成文件了,谢谢各位的帮忙。