请教:我用单片机和CH375连的,因为我用的是瑞萨的片子,没有找到对应的子程序库,所以是自己写的读写程序 用的是并口,中断方式,5V 写文件:1 写目录。 在U盘已经被格式化之后,依次读出FDT的各个扇区,FDT表中找到空的位置,写入目录,再把这个扇区写回到U盘。但是写回去的时候,只收到要求写数据的中断两次,协力第二个64字节后,就再也等不到中断了。 这是我写的测试程序: //写扇区 char WriteSector(unsigned long iLbaStart) { unsigned char j,mBlockCount; unsigned char Status; LBA_NO = 0; CH375_WR_CMD_PORT( CMD_DISK_WRITE ); // 向USB存储器发送写数据块命令 CH375_WR_DAT_PORT( iLbaStart ); CH375_WR_DAT_PORT( iLbaStart >> 8 ); CH375_WR_DAT_PORT( iLbaStart >> 16); CH375_WR_DAT_PORT( iLbaStart >> 24); CH375_WR_DAT_PORT( 0x01 ); for ( mBlockCount = 0; mBlockCount < 8; mBlockCount++ ) { while(1) { if( Init_Status ) { Init_Status = 0; if( INT_Status == USB_INT_DISK_WRITE ) //收到请求写375缓冲的中断 { CH375_WR_CMD_PORT( CMD_WR_USB_DATA7 ); //向375缓冲区写如数据 CH375_WR_DAT_PORT( 0x40 ); //先写数据个数,64个 for(j=0;j<0x40;j++) { CH375_WR_DAT_PORT( USB_DEVICE_DATA[LBA_NO] ); //写数据 LBA_NO++; } CH375_WR_CMD_PORT( CMD_DISK_WR_GO ); //继续读操作 } break; } } if ( mBlockCount == 7 ) { while(1) { if( Init_Status ) { Init_Status = 0; if( INT_Status == USB_INT_SUCCESS ) { return 0; } else // 返回错误状态 { Status = INT_Status; return Status; } } } } } } //写目录 char Write_File(unsigned char Clush_Doc) { unsigned short Status,l; unsigned char Sign; FDTCur = FDTStart; FDT_NO = 2; Sign = 0; while(1) { for(temp=FDTCur;temp { ReadSector( temp,1 ); //读目录表 for(Clush_NO=0;Clush_NO<0x1FF;Clush_NO+=0x20) { if((USB_DEVICE_DATA[Clush_NO]==0x00)||(USB_DEVICE_DATA[Clush_NO]==0xE5)) //找可用目录项 { if(!Sign) { USB_DEVICE_DATA[Clush_NO]=0x32; //文件名 USB_DEVICE_DATA[Clush_NO+1]=0x32; USB_DEVICE_DATA[Clush_NO+2]=0x32; USB_DEVICE_DATA[Clush_NO+3]=0x32; USB_DEVICE_DATA[Clush_NO+4]=0x32; USB_DEVICE_DATA[Clush_NO+5]=0x32; USB_DEVICE_DATA[Clush_NO+6]=0x32; USB_DEVICE_DATA[Clush_NO+7]=0x32; USB_DEVICE_DATA[Clush_NO+8]=0x54; //文件扩展名第一字节 USB_DEVICE_DATA[Clush_NO+9]=0x58; //文件扩展名第2字节 USB_DEVICE_DATA[Clush_NO+10]=0x54; //文件扩展名第三字节 USB_DEVICE_DATA[Clush_NO+11]=0x20; //固定值 USB_DEVICE_DATA[Clush_NO+12]=0; USB_DEVICE_DATA[Clush_NO+13]=0; CreatTime = Hour<<11 + Minute<<5 + Sec; //文件创建时间 USB_DEVICE_DATA[Clush_NO+14]=CreatTime>>8; USB_DEVICE_DATA[Clush_NO+15]=CreatTime; CreatDate = Year<<9 + Mouth<<5 + Date; //文件创建日期 USB_DEVICE_DATA[Clush_NO+16]=CreatDate>>8; USB_DEVICE_DATA[Clush_NO+17]=CreatDate; USB_DEVICE_DATA[Clush_NO+18]=CreatDate>>8; //最后访问日期 USB_DEVICE_DATA[Clush_NO+19]=CreatDate; USB_DEVICE_DATA[Clush_NO+20]=StartClush>>16; //簇号高位字 USB_DEVICE_DATA[Clush_NO+21]=StartClush>>24; USB_DEVICE_DATA[Clush_NO+22]=CreatTime>>8; //最后写的时间 USB_DEVICE_DATA[Clush_NO+23]=CreatTime; USB_DEVICE_DATA[Clush_NO+24]=CreatDate>>8; //最后写的日期 USB_DEVICE_DATA[Clush_NO+25]=CreatDate; USB_DEVICE_DATA[Clush_NO+26]=StartClush; //簇号低位字 USB_DEVICE_DATA[Clush_NO+27]=StartClush>>8; USB_DEVICE_DATA[Clush_NO+28]=Clush_Doc*0x400; //文件大小 USB_DEVICE_DATA[Clush_NO+29]=(Clush_Doc*0x400)>>8; USB_DEVICE_DATA[Clush_NO+30]=0; USB_DEVICE_DATA[Clush_NO+31]=0; Sign = 1; } for(l=Clush_NO+32;l<512;l+=32) { USB_DEVICE_DATA[l]=0xE5; } return 0; } } } ReadSector(DiskStart + RsvdSecCnt+FDT_NO/0x80,1); //继续查找合适的目录项 ClushStatus = USB_DEVICE_DATA[(FDT_NO%0x80)*4]+USB_DEVICE_DATA[(FDT_NO%0x80)*4+1]<<8+USB_DEVICE_DATA[(FDT_NO%0x80)*4+2]<<16+USB_DEVICE_DATA[(FDT_NO%0x80)*4+3]<<24; if( ClushStatus != 0xFFFFFFF) { FDT_NO = ClushStatus; //目录的下一个簇号 FDTCur = FDTStart+(ClushStatus-2)*2; //下一簇目录数据的实际扇区号 } else { Status = FreeClush(); //找到未用的簇 if(Status==0) { USB_DEVICE_DATA[Clush_NO]=0x0FF; USB_DEVICE_DATA[Clush_NO+1]=0x0FF; USB_DEVICE_DATA[Clush_NO+2]=0x0FF; USB_DEVICE_DATA[Clush_NO+3]=0x0F; WriteSector(DiskStart + RsvdSecCnt+temp); NewFile = temp*0x80 + Clush_NO/4; //新建目录项的簇号 ReadSector(DiskStart + RsvdSecCnt+FDT_NO/0x80,1); //修改FAT表 USB_DEVICE_DATA[(FDT_NO%0x80)*4] = NewFile; USB_DEVICE_DATA[(FDT_NO%0x80)*4+1] = NewFile>>8; USB_DEVICE_DATA[(FDT_NO%0x80)*4+2] = NewFile>>16; USB_DEVICE_DATA[(FDT_NO%0x80)*4+3] = NewFile>>24; WriteSector(DiskStart + RsvdSecCnt+FDT_NO/0x80); FDTCur = FDTStart+(NewFile-2)*2; //下一簇目录数据的实际扇区号 LeisureClush = temp*0x80 + Clush_NO/4; //记录最后使用的簇号 Free_Clush-=1; } else return 1; } } }
后来发现了一个理解不了的方法,把这个扇区里的空的目录项首字节都写0xE5就可以写了。
写文件内容是可以直接写的
最后写FAT表 和写FDT是一样的问题,也是写第二个64字节到375缓冲区后,等不到中断了。 程序: //创建文件 char WriteDoc(unsigned char ClushperDoc) { unsigned long DocClushCur,c; //写文件当前的簇号 unsigned char j,k,Status; unsigned short m; ReadSector( DiskStart+1,1 ); Free_Clush = USB_DEVICE_DATA[488]|USB_DEVICE_DATA[489]<<8|USB_DEVICE_DATA[490]<<16|USB_DEVICE_DATA[491]<<24; //剩余空闲簇数 if( Free_Clush >= ClushperDoc) { LeisureClush = (USB_DEVICE_DATA[492]|USB_DEVICE_DATA[493]<<8|USB_DEVICE_DATA[494]<<16|USB_DEVICE_DATA[495]<<24); //最后使用的簇 Status = FreeClush(); /*找到未用的簇*/ if(Status==0) { StartClush = temp*0x80 + Clush_NO/4; //记录空簇号,为文件开始簇 LeisureClush = temp*0x80 + Clush_NO/4; //纪录最后使用的簇号 } else return 1; //未找到控簇,返回1 /*写目录*/ Status = Write_File( ClushperDoc ); if(Status==0) { WriteSector(temp); } else { return 1; //写目录失败,返回1 } /*写文件*/ DocClushCur = StartClush; for(j=0;j { for(k=0;k<2;k++) { for(m=0;m<512;m++) { USB_DEVICE_DATA[m] = 0x47; //文件内容 } WriteSector( FDTStart+(DocClushCur-2)*2+k ); //文件写入相应的扇区 } /*修改FAT表*/ if(j { Status = FreeClush(); /*找到未用的簇*/ if(Status==0) { ReadSector( DiskStart + RsvdSecCnt+DocClushCur/0x80,1); USB_DEVICE_DATA[(DocClushCur%0x80)*4]=temp*0x80 + Clush_NO/4; USB_DEVICE_DATA[(DocClushCur%0x80)*4+1]=(temp*0x80 + Clush_NO/4)>>8; USB_DEVICE_DATA[(DocClushCur%0x80)*4+2]=(temp*0x