我用ch375与51单片机用并口查询方式通讯,功能是将存储于存储器中的数据以文件方式进行导出。主要程序如下: #include #include #include
//关于中断的宏定义 #define LIB_CFG_INT_EN 0 //CH375为查询方式
//文件的读写方式设定 #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 0x3800 //外部RAM的磁盘数据缓冲区的起始地址,从该单元开始的缓冲区长度为SECTOR_SIZE #define FILE_DATA_BUF_ADDR 0x4000 //外部RAM的文件数据缓冲区的起始地址,缓冲区长度不小于一次读写的数据长度 #define FILE_DATA_BUF_LEN 0x4000 //外部RAM的文件数据缓冲区
#define NO_DEFAULT_CH375_F_ENUM 1 /* 未调用CH375FileEnumer程序故禁止以节约代码 */ #define NO_DEFAULT_CH375_F_QUERY 1/* 未调用CH375FileQuery程序故禁止以节约代码 */
#define NO_DEFAULT_CH375_INT 1
#include"CH375HF4.H"
//声明外部变量ERROR; bit USB_ERROR;//ERROR的第6位表示USB错;
sbit P3_5=P3^5; #define CH375_INT_WIRE P3_5 sbit reset=P3^1;
//UINT8 fstate,state=1,a=0; UINT32 xdata FILESIZE=0x2000;//文件中的字节数,文件较大时(大于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;
UINT8 fstate,state,a=0;
//出错处理,置位出错标志 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]=1; }
void xQueryInterrupt( void ) /* 查询CH375中断并更新中断状态 */ { while ( P3_5==1 ); /* 如果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设备连接事件 */ }
void main()
{ UINT8 temp=0; UINT8 ready_wait,seccount;//写入的扇区数 UINT32 addsize;//增加的文件长度 UINT32 newsize;//新文件长度
YEAR=2007; MONTH=7; DAY=8;
USB_ERROR=0; addsize=0; datainbuf();
delay100ms();
reset=1;//硬件复位 delay100ms(); reset=0; delay100ms(); state=CH375LibInit( );//初始化 erusb(state);//状态是否出错
while(1) { addsize=0;
while(CH375DiskStatus!=DISK_CONNECT) xQueryInterrupt( ); delay100ms();
while ( CH375DiskStatus < DISK_CONNECT ) { /* 查询CH375中断并更新中断状态,等待U盘插入 */ if ( CH375DiskConnect( ) == ERR_SUCCESS ) break; /* 有设备连接则返回成功,CH375DiskConnect同时会更新全局变量CH375DiskStatus */ delay100ms(); //delay100ms(); //delay100ms(); } delay100ms(); delay100ms(); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */ for(ready_wait=10;ready_wait!=0;ready_wait--) { delay100ms(); state=CH375DiskReady(); if(state==ERR_SUCCESS) break;}
//状态位USB_DISK_DISCONNECT置1,U盘没连上
//打开文件
strcpy( mCmdParam.Open.mPathName, "\\LODA.DAT" ); //文件名,该文件在根目录下 fstate=CH375FileOpen(); //打开文件 //找到文件.文件MDADTA.TXT尾部定位 if(fstate==0) // 找到文件 { newsize=CH375vFileSize; mCmdParam.Locate.mSectorOffset = 0xffffffff; //移动文件指针到文件末尾 CH375FileLocate(); }//移动文件指针,以便在原文件的末尾追加数据
//没找到文件,创建新文件并写入数据 else if(fstate==ERR_MISS_FILE)//没找到文件,创建新文件并写入数据 { newsize=0; strcpy( mCmdParam.Create.mPathName, "\\LODA.DAT" ); //创建新文件,在根目录下 state=CH375FileCreate( ); //新建文件并打开,如果文件已经存在则先删除后再新建 erusb(state);}
//定扇区数,写入数据 while(FILESIZE>=FILE_DATA_BUF_LEN) { seccount=FILE_DATA_BUF_LEN/512;//写入31整扇区 write(seccount); FILESIZE-=FILE_DATA_BUF_LEN; addsize=addsize+FILE_DATA_BUF_LEN;}
seccount=(FILESIZE+ 511)>>9;//不足31个扇区 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 ( CH375DiskStatus != DISK_DISCONNECT ) xQueryInterrupt( ); delay100ms();
}
现在CH375用测试命令测试没问题,插入U盘后也能够识别。但执行到state=CH375DiskReady()这一步时总返回0x28或0x20,下面的写操作后返回0xb4,听人说0x28是中断等待超时,不知哪位高手知道这个问题怎么解决,感激不尽。