CH375A写U盘的问题,帮帮我

大家好,采用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);}}

自己补充一下state=CH375DiskReady();有时还返回0x2c,0x82,


你的程序上面没什么问题,按照你说的现象的话,在DISK-READY会出现0X82或者0X2C的情况的话,这个好象是你给U盘的供电是不是够?还有就是你单片机的晶振是多少?速度太慢的话也会出现你说的这种问题的


我测了电压,接上盘后4.9v ,单片机晶振12m


你用的是哪一个库?将单片机速度调快点试下,USB接口上面加一个电解电容,大小为100U左右


hcn,谢谢你,我用的是CH375HF4.lib,怎么才能将单片机的速度调快啊,12M晶振挺快了吧,是在USB的电源接口接个电容吗


用24M试试,是的,在电源端口


电源端口已有47uf电容,是否还有可能是其他原因,375的时钟是否一定要单独接,现在是从单片机上引下来。


你的USB口有没有串电阻?如果有串的话,那么串的是多少欧姆的?建议串的电阻在0-5欧姆之间


单片机的具体型号是什么,当读出来状态不正确时,看下晶振有没有起振,25脚26脚电压. 或者可以用例子程序试下看硬件有没有问题.


USB口无电阻,现在的问题是,下面这个函数有中断,但CH375DiskStatus 不等于DISK_CONNECT;,始终在这循环 void xQueryInterrupt( void ) /* 查询CH375中断并更新中断状态 */ { while ( CH375_INT_WIRE ); /* 如果CH375的中断引脚输出高电平则等待 */ CH375_CMD_PORT = CMD_GET_STATUS; /* 获取当前中断状态 */ CH375IntStatus &= 0x80; if ( CH375IntStatus ) CH375IntStatus = 0; /* 操作无意义,用于至少延时2uS */ CH375IntStatus = CH375_DAT_PORT; /* 获取中断状态 */ if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT; /* 检测到USB设备断开事件 */ else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT; /* 检测到USB设备连接事件 */ }


USB口无电阻,现在的问题是,下面这个函数有中断,但CH375DiskStatus 不等于DISK_CONNECT;,始终在这循环 void xQueryInterrupt( void ) /* 查询CH375中断并更新中断状态 */ { while ( CH375_INT_WIRE ); /* 如果CH375的中断引脚输出高电平则等待 */ CH375_CMD_PORT = CMD_GET_STATUS; /* 获取当前中断状态 */ CH375IntStatus &= 0x80; if ( CH375IntStatus ) CH375IntStatus = 0; /* 操作无意义,用于至少延时2uS */ CH375IntStatus = CH375_DAT_PORT; /* 获取中断状态 */ if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT; /* 检测到USB设备断开事件 */ else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT; /* 检测到USB设备连接事件 */ }


那CH375DiskStatus等于什么值,还有你看下CH375模式可设置成功了


这个文件是WINHEX读出数据的截图。


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