大家好,采用51单片机,采用CH375A,往U盘中写,在计算机上读文件,时而好使,时而不好使,采用P3.5进行查询方式 U盘为FAT格式化的。 问题: state=CH375DiskReady();state值不一定是啥,有时0xff,有时0x28,有时是0x20,还有其他情况,有时CH375DiskReady没问题, 软件如下,有问题吗,还是硬件问题,reseti=p3.4,有时好使,有时不好使为啥啊,不好使的时候多,换过许多盘,都是这样, 还有时写进去,文件打不开,大家帮忙啊,谢谢,我正烦着 #include #include #include
//关于中断的宏定义 #define LIB_CFG_INT_EN 0 //CH375为查询方式 #define CH375_INT_WIRE T1
//文件的读写方式设定 #define LIB_CFG_DISK_IO 3 //磁盘读写的数据的复制方式,3为"单DPTR和P2+R0复制" #define LIB_CFG_FILE_IO 3 // 文件读写的数据的复制方式,3为"单DPTR和P2+R0复制"
//命令口和数据口 #define CH375_CMD_PORT_ADDR 0xB001 //CH375命令端口的地址为B001 #define CH375_DAT_PORT_ADDR 0xB000 //CH375数据端口的地址为B000
//缓冲区定位,62256为32K,定0000H-3FFFH为全局变量,定4000H-41FFH为DISK-BASE-BUF(512字节) // 定4200H-7FFFH为FILE-DATA-BUF(共15872字节,31个扇区)
#define DISK_BASE_BUF_ADDR 0x4000 //外部RAM的磁盘数据缓冲区的起始地址,从该单元开始的缓冲区长度为SECTOR_SIZE #define FILE_DATA_BUF_ADDR 0x4200 //外部RAM的文件数据缓冲区的起始地址,缓冲区长度不小于一次读写的数据长度 #define FILE_DATA_BUF_LEN 0x3E00 //外部RAM的文件数据缓冲区,缓冲区长度为31个扇区,15872个字节
//为节省代码,禁止程序中不用的函数 #define NO_DEFAULT_CH375_F_ENUM 1 //未调用枚举函数CH375FileEnumer程序 #define NO_DEFAULT_CH375_F_QUERY 1 // 未调用询问函数CH375FileQuery程序
#include"CH375HF4.H"
//声明外部变量ERROR; bit USB_ERROR;//ERROR的第6位表示USB错;
sbit reset=P3^4;
UINT32 xdata FILESIZE=4000;//文件中的字节数,文件较大时(大于15872个字节),一次写入的扇区数为31,写入长度为FILE_DATA_BUF_LEN, //共需调用FILESIZE/FILE_DATA_BUF_LEN次,每次文件长度为15872个字节,最后不满31个扇区的数据,共有FILESIZE%FILE_DATA_BUF_LEN字节, //最后写入的扇区数为((FILESIZE%FILE_DATA_BUF_LEN)+511)/512扇区,文件长度为(UINT16 )FILESIZE%FILE_DATA_BUF_LEN //文件长度较小时(小于15872个字节),只需调用一次,写入的扇区数为(FILESIZE+511)/512扇区文件长度为(UINT16 ) //FILESIZE%FILE_DATA_BUF_LEN UINT16 xdata YEAR,MONTH,DAY;
//出错处理,置位出错标志 void erusb(UINT8 i) {if(i!=0) USB_ERROR=1; else return; }
void delay100ms(){ UINT8 i,j,k; for(i=0;i<200;i++) for(j=0;j<200;j++) k+=3;}
//向新文件中写入数据(多次调用) void write(UINT8 seccount) { mCmdParam.WriteX.mSectorCount = seccount; //写入扇区数 mCmdParam.WriteX.mDataBuffer=&FILE_DATA_BUF[0];//缓冲区启始地址 CH375FileWriteX( ); //以扇区为单位向文件写入数据 }
void datainbuf() {UINT16 i; for(i=0;i FILE_DATA_BUF[i]='o'; FILE_DATA_BUF[FILESIZE]='\0';}
void main()
{ UINT8 fstate,state=1,a=0; UINT8 ready_wait,seccount;//写入的扇区数 UINT32 addsize;//增加的文件长度 UINT32 newsize; YEAR=2007; MONTH=5; DAY=29;
USB_ERROR=0; addsize=0; datainbuf();
/* reset=1; delay100ms(); reset=0; delay100ms(); state=CH375LibInit( ); erusb(state);*/ while(state!=0){reset=1; delay100ms(); reset=0; delay100ms(); state=CH375LibInit( ); erusb(state); while(CH375DiskStatus!=DISK_CONNECT) xQueryInterrupt( ); delay100ms(); //查询磁盘是否准备好 for(ready_wait=10;ready_wait!=0;ready_wait--) { state=CH375DiskReady(); delay100ms(); delay100ms(); if(state==ERR_SUCCESS) break;} //状态位USB_DISK_DISCONNECT置1,U盘没连上
//打开文件 strcpy( mCmdParam.Open.mPathName, "\\DATA1.DOC" ); //文件名,该文件在根目录下 fstate=CH375FileOpen(); //打开文件 //找到文件.文件MDADTA.TXT尾部定位 if(fstate==0) // 找到文件 { newsize= CH375vFileSize; mCmdParam.Locate.mSectorOffset = 0xffffffff; //移动文件指针到文件末尾 CH375FileLocate(); }//移动文件指针,以便在原文件的末尾追加数据
//没找到文件,创建新文件并写入数据 else if(fstate==ERR_MISS_FILE)//没找到文件,创建新文件并写入数据 { strcpy( mCmdParam.Create.mPathName, "\\DATA1.DOC" ); //创建新文件,在根目录下 state=CH375FileCreate( ); //新建文件并打开,如果文件已经存在则先删除后再新建 erusb(state);} //定扇区数,写入数据 while(FILESIZE>=FILE_DATA_BUF_LEN) {seccount=FILE_DATA_BUF_LEN/512; delay100ms(); write(seccount); FILESIZE-=FILE_DATA_BUF_LEN; addsize=addsize+FILE_DATA_BUF_LEN;}
seccount=(FILESIZE+ 511 )>>9; addsize=addsize+FILESIZE; write(seccount) ; //最后写入的扇区数为seccount,写入的长度为newsize; //修改文件长度,文件时间等 newsize=newsize+addsize; mCmdParam.Modify.mFileAttr = 0xff; //输入参数: 新的文件属性,为0FFH则不修改 mCmdParam.Modify.mFileTime = 0xffff; //输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时? mCmdParam.Modify.mFileDate = MAKE_FILE_DATE(YEAR,MONTH,DAY); //输入参数: 新的文件日期 mCmdParam.Modify.mFileSize = newsize; // 输入参数: 如果原文件较小,那么新的文件长度与原文件一样长,否则被RAM所限,如果文件长度大于64KB,那么NewSize必须为UINT32 state= CH375FileModify(); //修改当前文件的信息,修改日期和长度 erusb(state); mCmdParam.Close.mUpdateLen = 0; // 不要自动计算文件长度,如果自动计算,那么该长度总是512的倍数 state=CH375FileClose( );//长度更新 erusb(state); while(1);}}