📄 com-to-usb.c
字号:
5 代码清单
//功能:延时20MS
#define USB_Port 0 //USB通讯端口
static void DelayUsb20000(void)
{ unsigned int i;
for(i=0;i<100;i++)
{ delay(100);
Meet_Co_AckNOP();
}
}
//函数功能:发送命令到USB模块。
//入口参数:cmd 命令字(见Ch375hm.h) len 发送缓冲区的数据长度
//全局变量:发送缓冲区unsigned char * SendDate_USB 最大50BYTE
// 接收缓冲区unsigned char * ResData_USB 最大50BYTE
//返回:==CHAOSHI 超时 其他都是USB模块的返回,见Ch375hm.h
#define Erro_Usb_TimeOver_UsbRead 0x16000//0x16000 55秒
#define Error_Com_Data_Receive 0x1000 //2秒
#define CHAOSHI 0xf1 //连接超时
static unsigned char USB_Command(unsigned char cmd,unsigned char len) //发送命令到USB模块
{ unsigned char status,i;
unsigned char Buf[4];
unsigned char OldByteLen=0;
unsigned long int ComOverTime=0,ComDataError=Erro_Usb_TimeOver_UsbRead;
ResData_USB[1]=0;
REC_CNT=0;
Buf[0]=0x57;
Buf[1]=0xab; //两个字节的同步头
Buf[2]=cmd; //命令字
Buf[3]=len; //数据长度
UsbInt(); //USB端口初始化
SendData(4,USB_Port,Buf); //发送命令头
SendData(len,USB_Port,SendDate_USB);//发送命令参数
for(;;) //处理数据传输,直到操作完成才退出 //
{
Meet_Co_AckNOP(); //通知CI等待
ComOverTime++;
if(ComOverTime>ComDataError) //超时
{ status = CHAOSHI;
break;
}
if(REC_CNT>0) //已经接收到字符
{ ComDataError=Error_Com_Data_Receive;
if(OldByteLen<REC_CNT)//又有字节过来
{ ComOverTime=0;
OldByteLen=REC_CNT; //本次已经接收到的字符长度
}
status=ResData_USB[0]; // 模块返回的操作状态
if(status!=ERR_SUCCESS) //第一个接收到的字符错误
{ REC_CNT=0; //将接收到的错误字符丢掉
OldByteLen=0;
ComOverTime=0;
if ((status== ERR_DISK_DISCON)||(status == ERR_USB_CONNECT))
{ DelayUsb20000(); // U盘刚刚连接或者断开,应该延时几十毫秒再操作
}
continue;
}
if(REC_CNT>1)
{ i=ResData_USB[1]+2; //返回结果数据的长度 //
if(i==REC_CNT) //已经接收完毕
{ delay(2000);//等待看后面是否还有中断过来,波特率最低4800
if(i<REC_CNT) //有错误数据发送到串口
{ REC_CNT=0;//串口接收到的是错误的数据
OldByteLen=0;
ComOverTime=0;
continue;
}
break; // 操作成功返回
}
}
}
}
_DINT(); //关中断
return status; //返回USB运行结果。
}
//函数功能:检查模块和U盘是否已经准备好了
//返回:ERR_SUCCESS -- U盘已经准备好了 其他错误代码见(Ch375hm.h)
static unsigned char DiskReady(void)
{ unsigned char ret,i;
stStatus * USB=(stStatus * )(ResData_USB+2);
UsbInt();
for(i=0;i<3;i++) /* 使用查询方式看U盘是否连接 */
{ ret=USB_Command(CMD_QueryStatus,0); /* 查询当前模块的状态 */
if((ret==0)&&(USB->mDiskStatus>=DISK_CONNECT))
break; /* U盘已经连接 */
Meet_Co_AckNOP();
DelayUsb20000(); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */
}
ret=USB->mDiskStatus;
if((ret>=DISK_CONNECT)||(i==3)) //连续3次没有检测到U盘状态或检测到U盘连接错误
{ for(i=0;i<3;i++)
{ ret=USB_Command(CMD_DiskReady,0); //
if(ret==ERR_SUCCESS)
break; /* 查询磁盘是否准备好 */
DelayUsb20000(); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */
Meet_Co_AckNOP();
}
}
return ret;
}
//功能 读磁盘信息
//磁盘满返回 0
//不可识别的文件系统返回 1
//返回磁盘的可用空间(字节数) >=512 个字节时返回
static unsigned long int DiskQuery(void)
{ stQuery *p=(stQuery *)(ResData_USB+2);
unsigned long int Size;
unsigned char i;
for(i=0;i<3;i++)
{ if(USB_Command(CMD_DiskQuery,0)==0) //读磁盘容量
break;
}
if((p->mDiskFat<1)||(i==3)) //连续3此错误,或者为不支持的文件格式
return 1;
Size=p->mFreeSector*512; //由扇区数转成字节数
return Size;
}
//功能:按文件名FileName查找文件,找到返回ERR_SUCCESS,且文件长度通过FileLen返回
//入口参数:FileName 文件名
//出口参数:FileLen 文件的长度
//返回:找到文件返回ERR_SUCCESS 没有找到文件返回 ERR_MISS_FILE
static unsigned char SearchFileLen(unsigned char *FileName,unsigned long int *FileLen)
{ unsigned char ret,i;
stStatus * USB=(stStatus * )(ResData_USB+2);
UsbInt();
FileLen[0]=0;
ret=OperateFile(CMD_FileEnumer,FileName); //搜索文件
if(ret!=ERR_SUCCESS)
return ret; //没有找到指定文件,或输入的文件名错误 ERR_MISS_FILE
for(i=0;i<3;i++)
{ ret=USB_Command(CMD_QueryStatus,0); /* 查询当前模块的状态 */
if((ret==0)&&(USB->mDiskStatus>=DISK_CONNECT)) //模块连接正确
{ FileLen[0]=USB->mFileSize; //传递文件长度
return ERR_SUCCESS; //返回正确
}
Meet_Co_AckNOP();
}
return ret; //模块的错误状态
}
//函数功能:对文件和目录的操作的操作。
//入口参数:Command 命令字 (对文件的操作)
// CMD_FileCreate 创建文件
// CMD_FileOpen 打开文件
// CMD_FileErase 删除文件
// CMD_FileEnumer 查找文件
// (对目录的操作)
// CMD_DirCreate 创建目录
// CMD_FileErase 删除目录
//入口参数:文件名:FileName 文件格式:文件名8个字节扩展名3个字节,文件名必须全是大写。中间用 . 分隔。ASCII码以/0结束。文件名的合法性由上层控制。
//函数返回:操作状态返回,成功:ERR_SUCCESS 错误:见Ch375hm.h
static unsigned char OperateFile(unsigned char Command,unsigned char *FileName)
{ unsigned char NameLen,result;
UsbInt();
NameLen=Strsize(FileName); //文件名的长度
SendDate_USB[0]='/'; //根目录标识符。
MoveByte((SendDate_USB+1),FileName,(NameLen+1));//文件名以/0结束
result=USB_Command(Command,NameLen+2); //发送命令到USB模块
return result;
}
//函数功能:关闭当前已经被打开的文件
//入口参数:Modify ==0 仅关闭文件不修改文件长度 Modify==1修改文件长度然后关闭文件
//返回:操作状态返回,成功:ERR_SUCCESS 错误:见Ch375hm.h
static unsigned char CloseFile(unsigned char Modify)//关闭当前文件
{ unsigned char Date=0,result;
if(Modify==1) //要修改文件长度
{ SendDate_USB[0]=0; //数据为0
result=USB_Command(CMD_ByteWrite,1); //写0数据修改文件长度,因为USB模块CMD_FileClose命令有BUG
if(result!=ERR_SUCCESS) //
return result;
}
SendDate_USB[0]=0; //不修改文件长度
result=USB_Command(CMD_FileClose,1); //关闭指定文件
return result;
}
//函数功能:按字节写函数。将数据Date,分40个字节/次,向U盘中写入。
//入口参数:Date 要写入的数据 DateLen 写入的总字节数
//函数返回:写成功:ERR_SUCCESS 错误:见Ch375hm.h
static unsigned char ByteWrite(unsigned char *Date,unsigned long int DateLen)
{ unsigned char result;
unsigned char *buf;
unsigned int Addr;
unsigned long int i,len;
for(buf=Date,i=DateLen;i<=DateLen;buf=buf+40,i=i-40) //一次最多写入40个字节
{ len=i;
if(i>40)
len=40;
SendDate_USB[0]=(unsigned char)len; //每次写入的字符长度
if(buf<(unsigned char *)0xA00) //写入的原文件在内部RAM
MoveByte((SendDate_USB+1),buf,(unsigned int)len);
else
{ Addr=(unsigned int)buf; //写入的原文件在外部RAM
ReadMem(Addr,(unsigned int)len,(SendDate_USB+1));
}
result=USB_Command(CMD_ByteWrite,((unsigned char)len)+1); //写入U盘
if(result!=ERR_SUCCESS)
break;
Meet_Co_AckNOP();
}
return result;
}
//函数功能:将文件中的数据按40个字节/次的原则读到Date中
//入口参数:DateLen 读的总字节数
//出口参数:Date 读出的数据
//函数返回:读成功:ERR_SUCCESS 错误:见Ch375hm.h //
static unsigned char ByteRead(unsigned char *Date,unsigned long int DateLen)
{ unsigned char result;
unsigned char *buf;
unsigned int Addr;
unsigned long int i,len;
for(buf=Date,i=DateLen;i<=DateLen;buf=buf+40,i=i-40) //一次最多读40个字节
{ len=i;
if(i>40)
len=40;
SendDate_USB[0]=(unsigned char)len; //本次读的字节数
result=USB_Command(CMD_ByteRead,1); //发送读命令
if(result!=ERR_SUCCESS) //读失败
break;
if(buf<(unsigned char *)0xA00) //把文件读到内部RAM中
MoveByte(buf,ResData_USB+3,ResData_USB[2]);
else
{ Addr=(unsigned int )buf; //文件读到外部RAM
WriteMem(Addr,(unsigned int)len,(SendDate_USB+1));
}
if(ResData_USB[2]<len) //文件读结束了
break;
Meet_Co_AckNOP();
}
return result;
}
//函数功能:从第SectorOffset个字节开始写数据
//入口参数:FileName(ASC码) -- 文件名 命名规则同函数OperateFile()
//Date -- 需要写入文件的数据
//DateLen -- 写入数据的长度
//SectorOffset -- 文件指针,写入文件的起始地址。按字节计算 (SectorOffset==0Xffffffff)在文件的尾部追加
//函数返回:成功:ERR_SUCCESS 错误:见Ch375hm.h
static unsigned char FileWrite(unsigned char *FileName,unsigned char *Date,unsigned long int DateLen,unsigned long SectorOffset)
{ unsigned char result;
unsigned long *Date_USB=(unsigned long *)SendDate_USB;
UsbInt();
result=OperateFile(CMD_FileOpen,FileName); //打开文件
if(result!=ERR_SUCCESS)
{ return result;
}
Date_USB[0]=SectorOffset;
USB_Command(CMD_ByteLocate,4); //移动文件指针
result=ByteWrite(Date,DateLen); //向文件中添加数据
if(result!=ERR_SUCCESS)
{ CloseFile(0); //写数据失败,关闭文件,不修改文件长度
return result;
}
result=CloseFile(1); //写数据成功,关闭文件,修改文件长度
ModifyInfo(FileName,1); //对文件的操作是修改。
return result;
}
//函数功能:修改文件基本信息。记录文件的创建时间、修改时间和最近一次的访问时间。
//入口参数:type==0 仅对文件访问
// type==1 改写文件
// type==2 创建文件
// FileName 文件名,命名规则同函数OperateFile()
//函数返回:成功:ERR_SUCCESS 错误:见Ch375hm.h
static unsigned char ModifyInfo(unsigned char *FileName,unsigned char type)
{ stFileDirInfo * p=(stFileDirInfo *)(ResData_USB+2);
unsigned char ret;
unsigned char time[6],i;
unsigned int modifytime[6],date,Time;
ret=OperateFile(CMD_FileOpen,FileName); //打开文件
if(ret!=ERR_SUCCESS)
{ return ret;
}
MoveByte(time,CUR_TIME+1,6); //记录当前时间
BCDDaoHEX(time,6);
for(i=0;i<6;i++)
{ modifytime[i]=time[i];
}
SendDate_USB[0]=0;
USB_Command(CMD_FileDirInfo,1); //读文件的属性
MoveByte(SendDate_USB,ResData_USB+2,sizeof(stFileDirInfo));
p=(stFileDirInfo *)(SendDate_USB);
Time=(modifytime[3]<<11)+(modifytime[4]<<5)+(modifytime[5]>>1); //转换当前时间
date=((modifytime[0]+20)<<9)+(modifytime[1]<<5)+modifytime[2]; //转换当前日期
if(type>0) //创建和修改文件
{ if(type>1) //创建文件
{ p->mDir.DIR_CrtTime=Time; //创建时间
p->mDir.DIR_CrtDate=date;
}
p->mDir.DIR_WrtTime=Time; //修改时间
p->mDir.DIR_WrtDate=date;
}
p->mDir.DIR_LstAccDate=date; //最近一次的访问日期
p->mAccessMode=0xf0; //写入/更新文件目录信息
ret=USB_Command(CMD_FileDirInfo,sizeof(stFileDirInfo)); //修改文件属性
CloseFile(0); //关闭文件
return ret;
}
//函数功能:读文件,从SectorOffset个字节开始。
//入口参数:FileName(ASC码) -- 文件名 命名规则同函数OperateFile()
//Date -- 从文件FileName中读出的数据
//DateLen -- 读数据的长度
//SectorOffset -- 文件指针,读文件的起始地址。按字节计算
//函数返回:成功:ERR_SUCCESS 错误:见Ch375hm.h
static unsigned char FileRead(unsigned char *FileName,unsigned char *Date,unsigned long int DateLen,unsigned long SectorOffset)
{ unsigned char result;
unsigned long *Date_USB=(unsigned long *)SendDate_USB;
UsbInt();
result=OperateFile(CMD_FileOpen,FileName); //打开文件
if(result!=ERR_SUCCESS)
{ return result;
}
Date_USB[0]=SectorOffset; //指针的偏移量
USB_Command(CMD_ByteLocate,4); //移动文件指针
result=ByteRead(Date,DateLen); //按字节读文件
CloseFile(0); //关闭文件
ModifyInfo(FileName,0); // 修改文件操作时间 包括对文件打开和关闭
return result;
}
/*
功能: USB串口初始化
入口参数:
返回值:
变量:
*/
static unsigned int UsbInt(void)
{ REC_CNT=0;
Comm_SysIniUART0(Full_X_BUF+384,9600,50); //初始化U1口
SendDate_USB=Full_X_BUF+256;
ResData_USB=Full_X_BUF+384;
commbuf=ResData_USB;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -