⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 com-to-usb.c

📁 由串口资源实现USB驱动的解决方案
💻 C
📖 第 1 页 / 共 2 页
字号:














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 + -