usb

来源:互联网 发布:mac 最大化 快捷键 编辑:程序博客网 时间:2024/05/01 14:24


  • #include <main.h>   
  • #include <string.h>   
  • #include <stdio.h>   
  • #include <avr/io.h>   
  •    
  • #define usb_cmd (*(volatile unsigned char *)0xa001)   
  • #define usb_data (*(volatile unsigned char *)0xa000)   
  • #define CMD_SET_USB_MODE    0x15            /* 设置USB工作模式 */   
  • #define CMD_RET_SUCCESS     0x51            /* 命令操作成功 */   
  • #define CMD_RESET_ALL       0x05            /* 执行硬件复位 */   
  • #define CMD_CHECK_EXIST     0x06            /* 测试工作状态 */   
  • #define DISK_CONNECT            0x02    /* 磁盘已经连接,但是尚未初始化或者无法识别该磁盘 */   
  • #define CMD_GET_STATUS      0x22            /* 获取中断状态并取消中断请求 */   
  • #define USB_INT_DISCONNECT  0x16            /* 检测到USB设备断开事件 */   
  • #define USB_INT_CONNECT     0x15            /* 检测到USB设备连接事件 */   
  • #define DISK_DISCONNECT         0x01    /* 磁盘没有连接或者已经断开 */   
  • #define ERR_SUCCESS             0x00    /* 操作成功 */   
  • #define USB_INT_SUCCESS      0x14           /* USB事务或者传输操作成功 */   
  • #define CMD_DISK_INIT       0x51            /* 主机方式: 初始化USB存储器 */   
  • #define CMD_DISK_SIZE       0x53            /* 主机方式: 获取USB存储器的容量 */   
  • #define CMD_DISK_READY      0x59            /* 主机方式: 检查USB存储器就绪 */   
  • #define CMD_DiskReady           0x71    /* 查询磁盘是否准备好 */   
  • #define ERR_MISS_DIR            0xB3    /* 指定路径的某个子目录没有找到,可能是目录名称错误 */   
  • #define   CMD_FileOpen        0x10   
  • #define ERR_MISS_FILE           0x42    /* 指定路径的文件没有找到,可能是文件名称错误 */   
  • #define ERR_FOUND_NAME          0x43    /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中,如果需要使用,应该打开该文件 */   
  •    
  •  #ifndef UINT8   
  • typedef unsigned char                UINT8;   
  • #endif   
  • #ifndef UINT16   
  • typedef unsigned short               UINT16;   
  • #endif   
  • #ifndef UINT32   
  • typedef unsigned long                 UINT32;   
  • #endif   
  • #ifndef PUINT8   
  • typedef unsigned char               *PUINT8;   
  • #endif   
  •    
  •  /* 文件名 */   
  • #define PATH_WILDCARD_CHAR      0x2A    /* 路径名的通配符 '*' */   
  • #define PATH_SEPAR_CHAR1        0x5C    /* 路径名的分隔符 '\' */   
  • #define PATH_SEPAR_CHAR2        0x2F    /* 路径名的分隔符 '/' */   
  • #ifndef MAX_PATH_LEN   
  • #define MAX_PATH_LEN            30      /* 最大路径长度,含所有斜杠分隔符和小数点间隔符以及路径结束符00H */   
  • #endif   
  • #ifndef MAX_BYTE_IO   
  • #define MAX_BYTE_IO     ( MAX_PATH_LEN - 1 )    /* 以字节为单位单次读写文件时的最大长度,超过该长度可以分多次读写 */   
  • #endif   
  •    
  •   /* 外部命令参数 */   
  • typedef union _CMD_PARAM {   
  •     struct {   
  •         UINT8   mBuffer[ MAX_PATH_LEN ];   
  •     } Other;   
  •     struct {   
  •         UINT32  mDiskSizeSec;           /* 返回: 整个物理磁盘的总扇区数 */   
  •         UINT32  mTotalSector;           /* 返回: 当前逻辑盘的总扇区数 */   
  •         UINT32  mFreeSector;            /* 返回: 当前逻辑盘的剩余扇区数 */   
  •         UINT8   mDiskFat;               /* 返回: 当前逻辑盘的FAT类型 */   
  •     } Query;                            /* CMD_DiskQuery, 查询磁盘信息 */   
  •     struct {   
  •         UINT8   mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */   
  •     } Open;                             /* CMD_FileOpen, 打开文件 */   
  •     struct {   
  •         UINT8   mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名(含通配符*)...,枚举序号], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILE*",00H */   
  •     } Enumer;                           /* CMD_FileEnumer, 枚举文件,返回文件名 */   
  •     struct {   
  •         UINT8   mUpdateLen;             /* 输入参数: 是否允许更新长度: 0禁止,1允许 */   
  •     } Close;                            /* CMD_FileClose, 关闭当前文件 */   
  •     struct {   
  •         UINT8   mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */   
  •     } Create;                           /* CMD_FileCreate, 新建文件并打开,如果文件已经存在则先删除后再新建 */   
  •     struct {   
  •         UINT8   mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */   
  •     } Erase;                            /* CMD_FileErase, 删除文件并关闭 */   
  •     struct {   
  •         UINT32  mFileSize;              /* 输入参数: 新的文件长度,为0FFFFFFFFH则不修改, 返回: 原长度 */   
  •         UINT16  mFileDate;              /* 输入参数: 新的文件日期,为0FFFFH则不修改, 返回: 原日期 */   
  •         UINT16  mFileTime;              /* 输入参数: 新的文件时间,为0FFFFH则不修改, 返回: 原时间 */   
  •         UINT8   mFileAttr;              /* 输入参数: 新的文件属性,为0FFH则不修改, 返回: 原属性 */   
  •     } Modify;                           /* CMD_FileQuery, 查询当前文件的信息; CMD_FileModify, 查询或者修改当前文件的信息 */   
  •     struct {   
  •         UINT32  mSectorOffset;          /* 输入参数: 扇区偏移,0则移动到文件头,0FFFFFFFFH则移动到文件尾, 返回: 当前文件指针对应的绝对线性扇区号, 0FFFFFFFFH则已到文件尾 */   
  •     } Locate;                           /* CMD_FileLocate, 移动当前文件指针 */   
  •     struct {   
  •         UINT8   mSectorCount;           /* 输入参数: 读取扇区数, 返回: 实际读取扇区数 */   
  •     } Read;                             /* CMD_FileRead, 从当前文件读取数据 */   
  •     struct {   
  •         UINT8   mSectorCount;           /* 输入参数: 写入扇区数, 返回: 实际写入扇区数 */   
  •     } Write;                            /* CMD_FileWrite, 向当前文件写入数据 */   
  •     struct {   
  •         UINT8   mSectorCount;           /* 输入参数: 读取扇区数, 返回: 实际读取扇区数 */   
  •         UINT8   mReserved[7];   
  •         PUINT8  mDataBuffer;            /* 输入参数: 缓冲区起始地址, 返回: 缓冲区当前地址 */   
  •     } ReadX;                            /* CMD_FileReadX, 从当前文件读取数据到指定缓冲区 */   
  •     struct {   
  •         UINT8   mSectorCount;           /* 输入参数: 写入扇区数, 返回: 实际写入扇区数 */   
  •         UINT8   mReserved[7];   
  •         PUINT8  mDataBuffer;            /* 输入参数: 缓冲区起始地址, 返回: 缓冲区当前地址 */   
  •     } WriteX;                           /* CMD_FileWriteX, 向当前文件写入指定缓冲区的数据 */   
  •     struct {   
  •         UINT32  mDiskSizeSec;           /* 返回: 整个物理磁盘的总扇区数 */   
  •     } DiskSize;                         /* CMD_DiskSize, 查询磁盘容量 */   
  •     struct {   
  •         UINT32  mByteOffset;            /* 输入参数: 以字节为单位的偏移量, 以字节为单位的文件指针, 返回: 当前文件指针对应的绝对线性扇区号, 0FFFFFFFFH则已到文件尾 */   
  •     } ByteLocate;                       /* CMD_ByteLocate, 以字节为单位移动当前文件指针 */   
  •     struct {   
  •         UINT8   mByteCount;             /* 输入参数: 准备读取的字节数,不得大于MAX_BYTE_IO, 返回: 实际读出的字节数 */   
  •         UINT8   mByteBuffer[ MAX_BYTE_IO ]; /* 返回: 读出的数据块 */   
  •     } ByteRead;                         /* CMD_ByteRead, 以字节为单位从当前文件读取数据块 */   
  •     struct {   
  •         UINT8   mByteCount;             /* 输入参数: 准备写入的字节数,不得大于MAX_BYTE_IO, 返回: 实际写入的字节数 */   
  •         UINT8   mByteBuffer[ MAX_BYTE_IO ]; /* 输入参数: 准备写入的数据块 */   
  •     } ByteWrite;                        /* CMD_ByteWrite, 以字节为单位向当前文件写入数据块 */   
  •     struct {   
  •         UINT8   mSaveVariable;          /* 输入参数: 为0则恢复变量,非0值则备份/保存变量 */   
  •         UINT8   mReserved[3];   
  •         PUINT8  mBuffer;                /* 输入参数: 指向子程序库的变量的备份缓冲区,长度不小于80个字节 */   
  •     } SaveVariable;                     /* CMD_SaveVariable, 备份/保存/恢复子程序库的变量 */   
  •     union {   
  •         struct {   
  •             UINT32  mCBW_Sig;   
  •             UINT32  mCBW_Tag;   
  •             UINT8   mCBW_DataLen;       /* 输入: 数据传输长度,有效值是0到255 */   
  •             UINT8   mCBW_DataLen1;   
  •             UINT8   mCBW_DataLen2;   
  •             UINT8   mCBW_DataLen3;   
  •             UINT8   mCBW_Flag;          /* 输入: 传输方向等标志 */   
  •             UINT8   mCBW_LUN;   
  •             UINT8   mCBW_CB_Len;        /* 输入: 命令块的长度,有效值是1到16 */   
  •             UINT8   mCBW_CB_Buf[6];     /* 输入: 命令块,该缓冲区最多为16个字节 */   
  •         } mCBW;                         /* BulkOnly协议的命令块, 输入CBW结构 */   
  •         struct {   
  •             UINT32  mCSW_Sig;   
  •             UINT32  mCSW_Tag;   
  •             UINT32  mCSW_Residue;       /* 返回: 剩余数据长度 */   
  •             UINT8   mCSW_Status;        /* 返回: 命令执行结果状态 */   
  •             UINT8   mReserved;   
  •         } mCSW;                         /* BulkOnly协议的命令状态块, 输出CSW结构 */   
  •     } BOC;                              /* CMD_BulkOnlyCmd, 执行基于BulkOnly协议的命令, 如果有数据传输那么数据在DISK_BASE_BUF中 */   
  • } CMD_PARAM;   
  •    
  •    
  •   extern  UINT8   CH375DiskStatus;   
  •   extern  UINT8    CH375DiskConnect(void );   
  •   extern  UINT8      CH375IntStatus;   
  • void port_init(void)   
  •  {   
  •    DDRA=0XFF;   
  •    DDRC=0XFF;   
  •    PORTC&=~0X80;   
  •    DDRE=0X00;   
  •    DDRG=0X00;   
  •  }   
  •  void CH375_port_init(void)   
  •  {   
  •  DDRA=0X00;   
  •  DDRG=0X00;   
  •  PORTG=0X1F;   
  •  DDRC=0X00;   
  •  PORTC=0X00;   
  •  DDRE=0XFF;   
  •  }   
  •  void init_devices(void)   
  •  {   
  •  CLI();   
  •  port_init();   
  •  CH375_port_init();   
  •  MCUCR=0X80;   
  •  EICRB=0X00;   
  •  EIMSK|=0X10;   
  •  SEI();   
  •  }   
  •     
  •     
  • void delayms( UINT8  m)    
  •   {    
  •   UINT8 i,j;    
  •   while(m--)   
  •   {for ( i = 100; i != 0; i -- )   
  •   for ( j=10; j!=0; j-- );}   
  •   }   
  •      
  •  void delay2us(  UINT16  m)    
  •   {    
  •   UINT8 i;    
  •   while(m--)   
  •   {for ( i = 2; i != 0; i -- );}   
  •      
  •  }   
  •     
  •  void xWriteCH375Cmd( UINT8 mCmd )      /* 外部定义的被CH375程序库调用的子程序,向CH375写命令 */   
  • {   
  •     delay2us(1); /* 至少延时1uS */   
  •    /*   *(volatile unsigned char *)CH375_DAT_PORT_ADDR = mData;  通过并口直接读写CH375而非普通I/O模拟 */   
  •     PORTC |= 0x02;  /* 输出A0=1 ;CS=0*/   
  •     PORTA = mCmd;  /* 向CH375的并口输出数据 */   
  •     DDRA = 0xFF;  /* 并口D0-D7输出 */   
  •     PORTG=0X1E;  /* WR=0;RD=1*/   
  •     DDRA = 0xFF;  /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */   
  •     DDRA = 0x00;  /* 禁止数据输出 */   
  •     delay2us(1);  /* 至少延时2uS */   
  • }    
  •    
  •  UINT8 xReadCH375Data(void)         /* 外部定义的被CH375程序库调用的子程序,从CH375读数据 */   
  • {   
  •     UINT8   mData;   
  • /*  mData = *(volatile unsigned char *)CH375_DAT_PORT_ADDR;  通过并口直接读写CH375而非普通I/O模拟 */   
  •     delay2us(1);  /* 至少延时1.2uS */   
  •     DDRA = 0x00;  /* 数据输入 */   
  •     PORTC=0x00;  /* 输出A0=0 ;CS=0*/   
  •     PORTG=0X1C;  /* WR=1;RD=0*/   
  •     DDRA = 0x00;  /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */   
  •     mData = PINA;  /* 从CH375的并口PA输入数据 */   
  •     return( mData );   
  • }   
  •    
  •    
  • void xWriteCH375Data( UINT8 mData )     /* 外部定义的被CH375程序库调用的子程序,向CH375写数据 */   
  • {   
  • /*  *(volatile unsigned char *)CH375_DAT_PORT_ADDR = mData;  通过并口直接读写CH375而非普通I/O模拟 */   
  •     PORTA = mData;  /* 向CH375的并口输出数据 */   
  •     DDRA = 0xFF;  /* 并口D0-D7输出 */   
  •     PORTG=0X1E;  /* 输出有效写控制信号, 写CH375芯片的数据端口,WR=0;RD=1*/   
  •     PORTC=0x00;  /* 输出A0=0 ;CS=0*/   
  •     DDRA = 0xFF;  /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */   
  •     DDRA = 0x00;  /* 禁止数据输出 */   
  •     delay2us(1);  /* 至少延时2uS */   
  • }   
  •    
  •   /* 设置CH375的工作模式 */   
  •  UINT8 set_usb_mode(UINT8 mode )   
  •  {   
  •       UINT8 i;   
  •       UINT8 RD_Data;   
  •    
  •      xWriteCH375Cmd(CMD_SET_USB_MODE);   
  •      delay2us(1);   
  •    
  •      xWriteCH375Data(mode);   
  •       delay2us(1);   
  •      for ( i = 100; i != 0; i -- )  /* 等待设置模式操作完成,不超过30uS */   
  •      {   
  •       RD_Data=xReadCH375Data();   
  •      if( RD_Data == CMD_RET_SUCCESS )   
  •      return 1;   
  •      }  /* 成功 */   
  •      return 0;   
  •  }   
  •    
  •      
  •  UINT8 ch375_init(UINT8 mode)   
  • {   
  •      UINT8 i, k;   
  •         
  •      /* 测试CH375是否正常工作 */   
  •      for( k=100; k!=0; k-- )   
  •        {   
  •          xWriteCH375Cmd(CMD_CHECK_EXIST) ;  /* 测试CH375是否正常工作 */   
  •          delay2us(1);   
  •          xWriteCH375Data(0x0f); /* 写入测试数据 */   
  •          /* 返回数据应该是测试数据取反 */   
  •          delay2us(1);   
  •          i=xReadCH375Data();   
  •          if ( 0xf0!= i)   /* CH375不正常 */   
  •         {   
  •             for ( i=5; i!=0; i-- )   
  •               xWriteCH375Cmd(CMD_RESET_ALL);  /* 多次重复发命令,执行硬件复位 */   
  •                
  •              delayms(50);  /* 延时50ms */   
  •         }   
  •         else   
  •         break;   
  •      }    if( k==0 )   
  •        return 0;   
  •        /* 设置USB工作模式, 必要操作 */   
  •         set_usb_mode( 6 ); /*已启用的主机方式并且自动产生SOF  */   
  •      return set_usb_mode(mode); //内部固件模式   
  •   }   
  •     
  •    UINT8    CH375LibInit( void )  /* 初始化CH375程序库和CH375芯片,操作成功返回0 */   
  • {   
  •     CH375LibConfig = LIB_CFG_VALUE;  /* CH375程序库配置值 */   
  •     DISK_BASE_BUF[0] = 0;  /* 该操作无意义,只是为了防止编译器优化时不产生DISK_BASE_BUF缓冲区 */   
  •     if ( CH375GetVer( ) < CH375_LIB_VER ) return( 0xFF );  /* 获取当前子程序库的版本号,版本太低则返回错误 */   
  •     return( CH375Init( ) );  /* 初始化CH375 */   
  • }   
  •     
  •     
  •    
  •    
  • /* 检查操作状态,如果错误则显示错误代码并停机 */   
  • void    mStopIfError( UINT8 iError )   
  • {   
  •     if ( iError == ERR_SUCCESS ) return;  /* 操作成功 */   
  •     printf( "Error: %02X\n", (UINT16)iError );  /* 显示错误 */   
  •        
  • }   
  •    
  • #ifndef NO_DEFAULT_CH375_INT            /* 在应用程序中定义NO_DEFAULT_CH375_INT可以禁止默认的中断处理程序,然后用自行编写的程序代替它 */   
  • #if LIB_CFG_INT_EN == 0                 /* CH375的INT#引脚连接方式为"查询方式" */   
  • void xQueryInterrupt( void )            /* 查询CH375中断并更新中断状态 */   
  • {   
  •     while ( PINE&0x10 );  /* 如果CH375的中断引脚输出高电平则等待 */   
  •     xWriteCH375Cmd( CMD_GET_STATUS );  /* 获取当前中断状态,发出命令后至少延时2uS */   
  •     CH375IntStatus = xReadCH375Data( );  /* 获取中断状态 */   
  •     if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT;  /* 检测到USB设备断开事件 */   
  •     else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT;  /* 检测到USB设备连接事件 */   
  • }   
  • #else                                   /* LIB_CFG_INT_EN != 0, CH375的INT#引脚连接方式为"中断方式" */   
  • void xQueryInterrupt( void )            /* 查询中断状态,等待硬件中断 */   
  • {   
  •     while ( CH375IntStatus == 0 );      /* 子程序库调用该子程序之前CH375IntStatus=0,硬件中断后,由中断服务程序置为非0的实际中断状态后返回 */   
  • }   
  • void    CH375Interrupt( void ) __attribute__ ((signal));   
  • void    CH375Interrupt( void )          /* CH375中断服务程序,由CH375的INT#的低电平或者下降沿触发单片机中断 */   
  • {   
  •     xWriteCH375Cmd( CMD_GET_STATUS );  /* 获取中断状态并取消中断请求 */   
  •     CH375IntStatus = xReadCH375Data( );  /* 获取中断状态 */   
  •     if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT;  /* 检测到USB设备断开事件 */   
  •     else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT;  /* 检测到USB设备连接事件 */   
  • #ifdef CLEAR_INT_MARK   
  •     CLEAR_INT_MARK( );  /* 某些单片机需要由软件清除中断标志 */   
  • #endif   
  • }   
  • #endif   
  • #endif   
  •    
  •  UINT8 waitint(void)   
  • {    
  •   while(PINE&0x10);   
  •   xWriteCH375Cmd(CMD_GET_STATUS);   
  •   delay2us(2);   
  •      
  •   return xReadCH375Data( );   
  •      
  • }   
  •     
  •    UINT8  CH375DiskReady(void )    
  •    {   
  •     xWriteCH375Cmd(CMD_DiskReady);   
  •     delay2us(2);   
  •     return xReadCH375Data( );   
  •    }   
  •    
  •       
  •    UINT8 InitDisk(void)   
  •  {    
  •      UINT8    i,Status;   
  •      xWriteCH375Cmd( CMD_GET_STATUS );  /* 获取当前中断状态,发出命令后至少延时2uS */   
  •      delay2us(1);   
  •      Status = xReadCH375Data( );  /* 获取中断状态 */   
  •      if (Status==USB_INT_DISCONNECT) return Status;/*usb断开 */   
  •      delay2us(10);   
  •      /* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */   
  •      for ( i = 0; i < 10; i ++ ) {  /* 有的U盘总是返回未准备好,不过可以被忽略 */   
  •      delayms( 100) ;   
  •                
  •      if ( CH375DiskReady( ) == USB_INT_SUCCESS ) break;  /* 查询磁盘是否准备好 */   
  •         }   
  •      xWriteCH375Cmd(CMD_DISK_INIT);          /*u盘初始化*/   
  •      Status=waitint(  );   
  •      if (Status!=USB_INT_SUCCESS) return Status;   
  •      xWriteCH375Cmd(CMD_DISK_SIZE);        /* 主机方式: 获取USB存储器的容量 */   
  •      Status=waitint(  );   
  •      if (Status!=USB_INT_SUCCESS)    
  •      {   
  •       delayms(250);   
  •       xWriteCH375Cmd(CMD_DISK_SIZE);   
  •       Status=waitint(  );      
  •      }   
  •      if (Status!=USB_INT_SUCCESS) return Status;   
  •      return 1;/*u盘初始化成功  */   
  •  }   
  •     
  •     UINT8  CH375FileOpen( )   
  •     {xWriteCH375Cmd(CMD_FileOpen);   
  •      delay2us(2);   
  •      return xReadCH375Data( );   
  •     }   
  •       
  •       
  •   int main(void )   
  •  {   
  •     UINT8 i,  c;   
  •     UINT8   *pCodeStr;   
  •     UINT16  TotalCount;   
  •    
  •     port_init();   
  •     CH375_port_init();   
  •     init_devices();   
  •     delay2us(10);   
  •     CH375LibInit(  )    
  •     c=ch375_init(6);   
  •     while(c!=1)   
  •     {for( i=5; i!=0; i-- )   
  •        c=ch375_init(6);   
  •        delayms(50);  /* 延时50ms */   
  •     }   
  •      
  • while ( 1 )   
  •       {   
  • //      while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( );  /* 查询CH375中断并更新中断状态,等待U盘插入 */   
  •         while ( CH375DiskStatus < DISK_CONNECT )    
  •         {  /* 查询CH375中断并更新中断状态,等待U盘插入 */   
  •             if ( CH375DiskConnect( ) == ERR_SUCCESS ) break;  /* 有设备连接则返回成功,CH375DiskConnect同时会更新全局变量CH375DiskStatus */   
  •              delayms(100);   
  •         }   
  •            
  •          delayms(200);;  /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */   
  •           }   
  •            
  •    InitDisk(); /*u盘初始化*/   
  •       
  •    /* 读取原文件 */   
  •     printf( "Open\n" );   
  •     strcpy(CMD_PARAM.Open.mPathName, "/C51/CH375HFT.C" );  /* 文件名,该文件在C51子目录下 */   
  •          i = CH375FileOpen( );  /* 打开文件 */   
  •          if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) {  /* 没有找到文件 */   
  • /* 列出文件 */   
  •             if ( i == ERR_MISS_DIR ) pCodeStr = (UINT8 *)"/*";  /* C51子目录不存在则列出根目录下的文件 */   
  •             else pCodeStr = (UINT8 *)"/C51/CH375*";  /* CH375HFT.C文件不存在则列出\C51子目录下的以CH375开头的文件 */   
  •             printf( "List file %s\n", pCodeStr );   
  •             for ( c = 0; c < 254; c ++ ) {  /* 最多搜索前254个文件 */   
  •                 strcpy( (char *)CMD_PARAM.Open.mPathName, (char *)pCodeStr );  /* 搜索文件名,*为通配符,适用于所有文件或者子目录 */   
  •                 i = strlen( (char *)CMD_PARAM.Open.mPathName );  /* 计算文件名长度,以处理文件名结束符 */   
  •                 CMD_PARAM.Open.mPathName[ i ] = c;  /* 根据字符串长度将结束符替换为搜索的序号,从0到255 */   
  •                 i = CH375FileOpen( );  /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */   
  •                 if ( i == ERR_MISS_FILE ) break;  /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */   
  •                 if ( i == ERR_FOUND_NAME ) {  /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */   
  •                     printf( "  match file %03d#: %s\n", (unsigned int)c, CMD_PARAM.Open.mPathName );  /* 显示序号和搜索到的匹配文件名或者子目录名 */   
  •                     continue;  /* 继续搜索下一个匹配的文件名,下次搜索时序号会加1 */   
  •                 }   
  •                 else {  /* 出错 */   
  •                     mStopIfError( i );   
  •                     break;   
  •                 }   
  •             }   
  •         }   
  •         else {  /* 找到文件或者出错 */   
  •             mStopIfError( i );   
  •             TotalCount = 600;  /* 准备读取总长度 */   
  •             printf( "从文件中读出的前%d个字符是:\n",TotalCount );   
  •             while ( TotalCount ) {  /* 如果文件比较大,一次读不完,可以再调用CH375ByteRead继续读取,文件指针自动向后移动 */   
  •                 if ( TotalCount > MAX_BYTE_IO ) c = MAX_BYTE_IO;  /* 剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.ByteRead.mByteBuffer ) */   
  •                 else c = TotalCount;  /* 最后剩余的字节数 */   
  •                 CMD_PARAM.ByteRead.mByteCount = c;  /* 请求读出几十字节数据 */   
  •                 i = CH375ByteRead( );  /* 以字节为单位读取数据块,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后读 */   
  •                 mStopIfError( i );   
  •                 TotalCount -=CMD_PARAM.ByteRead.mByteCount;  /* 计数,减去当前实际已经读出的字符数 */   
  •                 for ( i=0; i!=CMD_PARAM.ByteRead.mByteCount; i++ )  {printf( "%c", CMD_PARAM.ByteRead.mByteBuffer[i] ); } /* 显示读出的字符 */   
  •                 if ( CMD_PARAM.ByteRead.mByteCount < c ) {  /* 实际读出的字符数少于要求读出的字符数,说明已经到文件的结尾 */   
  •                     printf( "\n" );   
  •                     printf( "文件已经结束\n" );   
  •                     break;   
  •                 }   
  •     
  •            }   
  •        }   
  •  }   #include <main.h>   
  • #include <string.h>   
  • #include <stdio.h>   
  • #include <avr/io.h>   
  •    
  • #define usb_cmd (*(volatile unsigned char *)0xa001)   
  • #define usb_data (*(volatile unsigned char *)0xa000)   
  • #define CMD_SET_USB_MODE    0x15            /* 设置USB工作模式 */   
  • #define CMD_RET_SUCCESS     0x51            /* 命令操作成功 */   
  • #define CMD_RESET_ALL       0x05            /* 执行硬件复位 */   
  • #define CMD_CHECK_EXIST     0x06            /* 测试工作状态 */   
  • #define DISK_CONNECT            0x02    /* 磁盘已经连接,但是尚未初始化或者无法识别该磁盘 */   
  • #define CMD_GET_STATUS      0x22            /* 获取中断状态并取消中断请求 */   
  • #define USB_INT_DISCONNECT  0x16            /* 检测到USB设备断开事件 */   
  • #define USB_INT_CONNECT     0x15            /* 检测到USB设备连接事件 */   
  • #define DISK_DISCONNECT         0x01    /* 磁盘没有连接或者已经断开 */   
  • #define ERR_SUCCESS             0x00    /* 操作成功 */   
  • #define USB_INT_SUCCESS      0x14           /* USB事务或者传输操作成功 */   
  • #define CMD_DISK_INIT       0x51            /* 主机方式: 初始化USB存储器 */   
  • #define CMD_DISK_SIZE       0x53            /* 主机方式: 获取USB存储器的容量 */   
  • #define CMD_DISK_READY      0x59            /* 主机方式: 检查USB存储器就绪 */   
  • #define CMD_DiskReady           0x71    /* 查询磁盘是否准备好 */   
  • #define ERR_MISS_DIR            0xB3    /* 指定路径的某个子目录没有找到,可能是目录名称错误 */   
  • #define   CMD_FileOpen        0x10   
  • #define ERR_MISS_FILE           0x42    /* 指定路径的文件没有找到,可能是文件名称错误 */   
  • #define ERR_FOUND_NAME          0x43    /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中,如果需要使用,应该打开该文件 */   
  •    
  •  #ifndef UINT8   
  • typedef unsigned char                UINT8;   
  • #endif   
  • #ifndef UINT16   
  • typedef unsigned short               UINT16;   
  • #endif   
  • #ifndef UINT32   
  • typedef unsigned long                 UINT32;   
  • #endif   
  • #ifndef PUINT8   
  • typedef unsigned char               *PUINT8;   
  • #endif   
  •    
  •  /* 文件名 */   
  • #define PATH_WILDCARD_CHAR      0x2A    /* 路径名的通配符 '*' */   
  • #define PATH_SEPAR_CHAR1        0x5C    /* 路径名的分隔符 '\' */   
  • #define PATH_SEPAR_CHAR2        0x2F    /* 路径名的分隔符 '/' */   
  • #ifndef MAX_PATH_LEN   
  • #define MAX_PATH_LEN            30      /* 最大路径长度,含所有斜杠分隔符和小数点间隔符以及路径结束符00H */   
  • #endif   
  • #ifndef MAX_BYTE_IO   
  • #define MAX_BYTE_IO     ( MAX_PATH_LEN - 1 )    /* 以字节为单位单次读写文件时的最大长度,超过该长度可以分多次读写 */   
  • #endif   
  •    
  •   /* 外部命令参数 */   
  • typedef union _CMD_PARAM {   
  •     struct {   
  •         UINT8   mBuffer[ MAX_PATH_LEN ];   
  •     } Other;   
  •     struct {   
  •         UINT32  mDiskSizeSec;           /* 返回: 整个物理磁盘的总扇区数 */   
  •         UINT32  mTotalSector;           /* 返回: 当前逻辑盘的总扇区数 */   
  •         UINT32  mFreeSector;            /* 返回: 当前逻辑盘的剩余扇区数 */   
  •         UINT8   mDiskFat;               /* 返回: 当前逻辑盘的FAT类型 */   
  •     } Query;                            /* CMD_DiskQuery, 查询磁盘信息 */   
  •     struct {   
  •         UINT8   mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */   
  •     } Open;                             /* CMD_FileOpen, 打开文件 */   
  •     struct {   
  •         UINT8   mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名(含通配符*)...,枚举序号], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILE*",00H */   
  •     } Enumer;                           /* CMD_FileEnumer, 枚举文件,返回文件名 */   
  •     struct {   
  •         UINT8   mUpdateLen;             /* 输入参数: 是否允许更新长度: 0禁止,1允许 */   
  •     } Close;                            /* CMD_FileClose, 关闭当前文件 */   
  •     struct {   
  •         UINT8   mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */   
  •     } Create;                           /* CMD_FileCreate, 新建文件并打开,如果文件已经存在则先删除后再新建 */   
  •     struct {   
  •         UINT8   mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */   
  •     } Erase;                            /* CMD_FileErase, 删除文件并关闭 */   
  •     struct {   
  •         UINT32  mFileSize;              /* 输入参数: 新的文件长度,为0FFFFFFFFH则不修改, 返回: 原长度 */   
  •         UINT16  mFileDate;              /* 输入参数: 新的文件日期,为0FFFFH则不修改, 返回: 原日期 */   
  •         UINT16  mFileTime;              /* 输入参数: 新的文件时间,为0FFFFH则不修改, 返回: 原时间 */   
  •         UINT8   mFileAttr;              /* 输入参数: 新的文件属性,为0FFH则不修改, 返回: 原属性 */   
  •     } Modify;                           /* CMD_FileQuery, 查询当前文件的信息; CMD_FileModify, 查询或者修改当前文件的信息 */   
  •     struct {   
  •         UINT32  mSectorOffset;          /* 输入参数: 扇区偏移,0则移动到文件头,0FFFFFFFFH则移动到文件尾, 返回: 当前文件指针对应的绝对线性扇区号, 0FFFFFFFFH则已到文件尾 */   
  •     } Locate;                           /* CMD_FileLocate, 移动当前文件指针 */   
  •     struct {   
  •         UINT8   mSectorCount;           /* 输入参数: 读取扇区数, 返回: 实际读取扇区数 */   
  •     } Read;                             /* CMD_FileRead, 从当前文件读取数据 */   
  •     struct {   
  •         UINT8   mSectorCount;           /* 输入参数: 写入扇区数, 返回: 实际写入扇区数 */   
  •     } Write;                            /* CMD_FileWrite, 向当前文件写入数据 */   
  •     struct {   
  •         UINT8   mSectorCount;           /* 输入参数: 读取扇区数, 返回: 实际读取扇区数 */   
  •         UINT8   mReserved[7];   
  •         PUINT8  mDataBuffer;            /* 输入参数: 缓冲区起始地址, 返回: 缓冲区当前地址 */   
  •     } ReadX;                            /* CMD_FileReadX, 从当前文件读取数据到指定缓冲区 */   
  •     struct {   
  •         UINT8   mSectorCount;           /* 输入参数: 写入扇区数, 返回: 实际写入扇区数 */   
  •         UINT8   mReserved[7];   
  •         PUINT8  mDataBuffer;            /* 输入参数: 缓冲区起始地址, 返回: 缓冲区当前地址 */   
  •     } WriteX;                           /* CMD_FileWriteX, 向当前文件写入指定缓冲区的数据 */   
  •     struct {   
  •         UINT32  mDiskSizeSec;           /* 返回: 整个物理磁盘的总扇区数 */   
  •     } DiskSize;                         /* CMD_DiskSize, 查询磁盘容量 */   
  •     struct {   
  •         UINT32  mByteOffset;            /* 输入参数: 以字节为单位的偏移量, 以字节为单位的文件指针, 返回: 当前文件指针对应的绝对线性扇区号, 0FFFFFFFFH则已到文件尾 */   
  •     } ByteLocate;                       /* CMD_ByteLocate, 以字节为单位移动当前文件指针 */   
  •     struct {   
  •         UINT8   mByteCount;             /* 输入参数: 准备读取的字节数,不得大于MAX_BYTE_IO, 返回: 实际读出的字节数 */   
  •         UINT8   mByteBuffer[ MAX_BYTE_IO ]; /* 返回: 读出的数据块 */   
  •     } ByteRead;                         /* CMD_ByteRead, 以字节为单位从当前文件读取数据块 */   
  •     struct {   
  •         UINT8   mByteCount;             /* 输入参数: 准备写入的字节数,不得大于MAX_BYTE_IO, 返回: 实际写入的字节数 */   
  •         UINT8   mByteBuffer[ MAX_BYTE_IO ]; /* 输入参数: 准备写入的数据块 */   
  •     } ByteWrite;                        /* CMD_ByteWrite, 以字节为单位向当前文件写入数据块 */   
  •     struct {   
  •         UINT8   mSaveVariable;          /* 输入参数: 为0则恢复变量,非0值则备份/保存变量 */   
  •         UINT8   mReserved[3];   
  •         PUINT8  mBuffer;                /* 输入参数: 指向子程序库的变量的备份缓冲区,长度不小于80个字节 */   
  •     } SaveVariable;                     /* CMD_SaveVariable, 备份/保存/恢复子程序库的变量 */   
  •     union {   
  •         struct {   
  •             UINT32  mCBW_Sig;   
  •             UINT32  mCBW_Tag;   
  •             UINT8   mCBW_DataLen;       /* 输入: 数据传输长度,有效值是0到255 */   
  •             UINT8   mCBW_DataLen1;   
  •             UINT8   mCBW_DataLen2;   
  •             UINT8   mCBW_DataLen3;   
  •             UINT8   mCBW_Flag;          /* 输入: 传输方向等标志 */   
  •             UINT8   mCBW_LUN;   
  •             UINT8   mCBW_CB_Len;        /* 输入: 命令块的长度,有效值是1到16 */   
  •             UINT8   mCBW_CB_Buf[6];     /* 输入: 命令块,该缓冲区最多为16个字节 */   
  •         } mCBW;                         /* BulkOnly协议的命令块, 输入CBW结构 */   
  •         struct {   
  •             UINT32  mCSW_Sig;   
  •             UINT32  mCSW_Tag;   
  •             UINT32  mCSW_Residue;       /* 返回: 剩余数据长度 */   
  •             UINT8   mCSW_Status;        /* 返回: 命令执行结果状态 */   
  •             UINT8   mReserved;   
  •         } mCSW;                         /* BulkOnly协议的命令状态块, 输出CSW结构 */   
  •     } BOC;                              /* CMD_BulkOnlyCmd, 执行基于BulkOnly协议的命令, 如果有数据传输那么数据在DISK_BASE_BUF中 */   
  • } CMD_PARAM;   
  •    
  •    
  •   extern  UINT8   CH375DiskStatus;   
  •   extern  UINT8    CH375DiskConnect(void );   
  •   extern  UINT8      CH375IntStatus;   
  • void port_init(void)   
  •  {   
  •    DDRA=0XFF;   
  •    DDRC=0XFF;   
  •    PORTC&=~0X80;   
  •    DDRE=0X00;   
  •    DDRG=0X00;   
  •  }   
  •  void CH375_port_init(void)   
  •  {   
  •  DDRA=0X00;   
  •  DDRG=0X00;   
  •  PORTG=0X1F;   
  •  DDRC=0X00;   
  •  PORTC=0X00;   
  •  DDRE=0XFF;   
  •  }   
  •  void init_devices(void)   
  •  {   
  •  CLI();   
  •  port_init();   
  •  CH375_port_init();   
  •  MCUCR=0X80;   
  •  EICRB=0X00;   
  •  EIMSK|=0X10;   
  •  SEI();   
  •  }   
  •     
  •     
  • void delayms( UINT8  m)    
  •   {    
  •   UINT8 i,j;    
  •   while(m--)   
  •   {for ( i = 100; i != 0; i -- )   
  •   for ( j=10; j!=0; j-- );}   
  •   }   
  •      
  •  void delay2us(  UINT16  m)    
  •   {    
  •   UINT8 i;    
  •   while(m--)   
  •   {for ( i = 2; i != 0; i -- );}   
  •      
  •  }   
  •     
  •  void xWriteCH375Cmd( UINT8 mCmd )      /* 外部定义的被CH375程序库调用的子程序,向CH375写命令 */   
  • {   
  •     delay2us(1); /* 至少延时1uS */   
  •    /*   *(volatile unsigned char *)CH375_DAT_PORT_ADDR = mData;  通过并口直接读写CH375而非普通I/O模拟 */   
  •     PORTC |= 0x02;  /* 输出A0=1 ;CS=0*/   
  •     PORTA = mCmd;  /* 向CH375的并口输出数据 */   
  •     DDRA = 0xFF;  /* 并口D0-D7输出 */   
  •     PORTG=0X1E;  /* WR=0;RD=1*/   
  •     DDRA = 0xFF;  /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */   
  •     DDRA = 0x00;  /* 禁止数据输出 */   
  •     delay2us(1);  /* 至少延时2uS */   
  • }    
  •    
  •  UINT8 xReadCH375Data(void)         /* 外部定义的被CH375程序库调用的子程序,从CH375读数据 */   
  • {   
  •     UINT8   mData;   
  • /*  mData = *(volatile unsigned char *)CH375_DAT_PORT_ADDR;  通过并口直接读写CH375而非普通I/O模拟 */   
  •     delay2us(1);  /* 至少延时1.2uS */   
  •     DDRA = 0x00;  /* 数据输入 */   
  •     PORTC=0x00;  /* 输出A0=0 ;CS=0*/   
  •     PORTG=0X1C;  /* WR=1;RD=0*/   
  •     DDRA = 0x00;  /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */   
  •     mData = PINA;  /* 从CH375的并口PA输入数据 */   
  •     return( mData );   
  • }   
  •    
  •    
  • void xWriteCH375Data( UINT8 mData )     /* 外部定义的被CH375程序库调用的子程序,向CH375写数据 */   
  • {   
  • /*  *(volatile unsigned char *)CH375_DAT_PORT_ADDR = mData;  通过并口直接读写CH375而非普通I/O模拟 */   
  •     PORTA = mData;  /* 向CH375的并口输出数据 */   
  •     DDRA = 0xFF;  /* 并口D0-D7输出 */   
  •     PORTG=0X1E;  /* 输出有效写控制信号, 写CH375芯片的数据端口,WR=0;RD=1*/   
  •     PORTC=0x00;  /* 输出A0=0 ;CS=0*/   
  •     DDRA = 0xFF;  /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100nS */   
  •     DDRA = 0x00;  /* 禁止数据输出 */   
  •     delay2us(1);  /* 至少延时2uS */   
  • }   
  •    
  •   /* 设置CH375的工作模式 */   
  •  UINT8 set_usb_mode(UINT8 mode )   
  •  {   
  •       UINT8 i;   
  •       UINT8 RD_Data;   
  •    
  •      xWriteCH375Cmd(CMD_SET_USB_MODE);   
  •      delay2us(1);   
  •    
  •      xWriteCH375Data(mode);   
  •       delay2us(1);   
  •      for ( i = 100; i != 0; i -- )  /* 等待设置模式操作完成,不超过30uS */   
  •      {   
  •       RD_Data=xReadCH375Data();   
  •      if( RD_Data == CMD_RET_SUCCESS )   
  •      return 1;   
  •      }  /* 成功 */   
  •      return 0;   
  •  }   
  •    
  •      
  •  UINT8 ch375_init(UINT8 mode)   
  • {   
  •      UINT8 i, k;   
  •         
  •      /* 测试CH375是否正常工作 */   
  •      for( k=100; k!=0; k-- )   
  •        {   
  •          xWriteCH375Cmd(CMD_CHECK_EXIST) ;  /* 测试CH375是否正常工作 */   
  •          delay2us(1);   
  •          xWriteCH375Data(0x0f); /* 写入测试数据 */   
  •          /* 返回数据应该是测试数据取反 */   
  •          delay2us(1);   
  •          i=xReadCH375Data();   
  •          if ( 0xf0!= i)   /* CH375不正常 */   
  •         {   
  •             for ( i=5; i!=0; i-- )   
  •               xWriteCH375Cmd(CMD_RESET_ALL);  /* 多次重复发命令,执行硬件复位 */   
  •                
  •              delayms(50);  /* 延时50ms */   
  •         }   
  •         else   
  •         break;   
  •      }    if( k==0 )   
  •        return 0;   
  •        /* 设置USB工作模式, 必要操作 */   
  •         set_usb_mode( 6 ); /*已启用的主机方式并且自动产生SOF  */   
  •      return set_usb_mode(mode); //内部固件模式   
  •   }   
  •     
  •    UINT8    CH375LibInit( void )  /* 初始化CH375程序库和CH375芯片,操作成功返回0 */   
  • {   
  •     CH375LibConfig = LIB_CFG_VALUE;  /* CH375程序库配置值 */   
  •     DISK_BASE_BUF[0] = 0;  /* 该操作无意义,只是为了防止编译器优化时不产生DISK_BASE_BUF缓冲区 */   
  •     if ( CH375GetVer( ) < CH375_LIB_VER ) return( 0xFF );  /* 获取当前子程序库的版本号,版本太低则返回错误 */   
  •     return( CH375Init( ) );  /* 初始化CH375 */   
  • }   
  •     
  •     
  •    
  •    
  • /* 检查操作状态,如果错误则显示错误代码并停机 */   
  • void    mStopIfError( UINT8 iError )   
  • {   
  •     if ( iError == ERR_SUCCESS ) return;  /* 操作成功 */   
  •     printf( "Error: %02X\n", (UINT16)iError );  /* 显示错误 */   
  •        
  • }   
  •    
  • #ifndef NO_DEFAULT_CH375_INT            /* 在应用程序中定义NO_DEFAULT_CH375_INT可以禁止默认的中断处理程序,然后用自行编写的程序代替它 */   
  • #if LIB_CFG_INT_EN == 0                 /* CH375的INT#引脚连接方式为"查询方式" */   
  • void xQueryInterrupt( void )            /* 查询CH375中断并更新中断状态 */   
  • {   
  •     while ( PINE&0x10 );  /* 如果CH375的中断引脚输出高电平则等待 */   
  •     xWriteCH375Cmd( CMD_GET_STATUS );  /* 获取当前中断状态,发出命令后至少延时2uS */   
  •     CH375IntStatus = xReadCH375Data( );  /* 获取中断状态 */   
  •     if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT;  /* 检测到USB设备断开事件 */   
  •     else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT;  /* 检测到USB设备连接事件 */   
  • }   
  • #else                                   /* LIB_CFG_INT_EN != 0, CH375的INT#引脚连接方式为"中断方式" */   
  • void xQueryInterrupt( void )            /* 查询中断状态,等待硬件中断 */   
  • {   
  •     while ( CH375IntStatus == 0 );      /* 子程序库调用该子程序之前CH375IntStatus=0,硬件中断后,由中断服务程序置为非0的实际中断状态后返回 */   
  • }   
  • void    CH375Interrupt( void ) __attribute__ ((signal));   
  • void    CH375Interrupt( void )          /* CH375中断服务程序,由CH375的INT#的低电平或者下降沿触发单片机中断 */   
  • {   
  •     xWriteCH375Cmd( CMD_GET_STATUS );  /* 获取中断状态并取消中断请求 */   
  •     CH375IntStatus = xReadCH375Data( );  /* 获取中断状态 */   
  •     if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT;  /* 检测到USB设备断开事件 */   
  •     else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT;  /* 检测到USB设备连接事件 */   
  • #ifdef CLEAR_INT_MARK   
  •     CLEAR_INT_MARK( );  /* 某些单片机需要由软件清除中断标志 */   
  • #endif   
  • }   
  • #endif   
  • #endif   
  •    
  •  UINT8 waitint(void)   
  • {    
  •   while(PINE&0x10);   
  •   xWriteCH375Cmd(CMD_GET_STATUS);   
  •   delay2us(2);   
  •      
  •   return xReadCH375Data( );   
  •      
  • }   
  •     
  •    UINT8  CH375DiskReady(void )    
  •    {   
  •     xWriteCH375Cmd(CMD_DiskReady);   
  •     delay2us(2);   
  •     return xReadCH375Data( );   
  •    }   
  •    
  •       
  •    UINT8 InitDisk(void)   
  •  {    
  •      UINT8    i,Status;   
  •      xWriteCH375Cmd( CMD_GET_STATUS );  /* 获取当前中断状态,发出命令后至少延时2uS */   
  •      delay2us(1);   
  •      Status = xReadCH375Data( );  /* 获取中断状态 */   
  •      if (Status==USB_INT_DISCONNECT) return Status;/*usb断开 */   
  •      delay2us(10);   
  •      /* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */   
  •      for ( i = 0; i < 10; i ++ ) {  /* 有的U盘总是返回未准备好,不过可以被忽略 */   
  •      delayms( 100) ;   
  •                
  •      if ( CH375DiskReady( ) == USB_INT_SUCCESS ) break;  /* 查询磁盘是否准备好 */   
  •         }   
  •      xWriteCH375Cmd(CMD_DISK_INIT);          /*u盘初始化*/   
  •      Status=waitint(  );   
  •      if (Status!=USB_INT_SUCCESS) return Status;   
  •      xWriteCH375Cmd(CMD_DISK_SIZE);        /* 主机方式: 获取USB存储器的容量 */   
  •      Status=waitint(  );   
  •      if (Status!=USB_INT_SUCCESS)    
  •      {   
  •       delayms(250);   
  •       xWriteCH375Cmd(CMD_DISK_SIZE);   
  •       Status=waitint(  );      
  •      }   
  •      if (Status!=USB_INT_SUCCESS) return Status;   
  •      return 1;/*u盘初始化成功  */   
  •  }   
  •     
  •     UINT8  CH375FileOpen( )   
  •     {xWriteCH375Cmd(CMD_FileOpen);   
  •      delay2us(2);   
  •      return xReadCH375Data( );   
  •     }   
  •       
  •       
  •   int main(void )   
  •  {   
  •     UINT8 i,  c;   
  •     UINT8   *pCodeStr;   
  •     UINT16  TotalCount;   
  •    
  •     port_init();   
  •     CH375_port_init();   
  •     init_devices();   
  •     delay2us(10);   
  •     CH375LibInit(  )    
  •     c=ch375_init(6);   
  •     while(c!=1)   
  •     {for( i=5; i!=0; i-- )   
  •        c=ch375_init(6);   
  •        delayms(50);  /* 延时50ms */   
  •     }   
  •      
  • while ( 1 )   
  •       {   
  • //      while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( );  /* 查询CH375中断并更新中断状态,等待U盘插入 */   
  •         while ( CH375DiskStatus < DISK_CONNECT )    
  •         {  /* 查询CH375中断并更新中断状态,等待U盘插入 */   
  •             if ( CH375DiskConnect( ) == ERR_SUCCESS ) break;  /* 有设备连接则返回成功,CH375DiskConnect同时会更新全局变量CH375DiskStatus */   
  •              delayms(100);   
  •         }   
  •            
  •          delayms(200);;  /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */   
  •           }   
  •            
  •    InitDisk(); /*u盘初始化*/   
  •       
  •    /* 读取原文件 */   
  •     printf( "Open\n" );   
  •     strcpy(CMD_PARAM.Open.mPathName, "/C51/CH375HFT.C" );  /* 文件名,该文件在C51子目录下 */   
  •          i = CH375FileOpen( );  /* 打开文件 */   
  •          if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) {  /* 没有找到文件 */   
  • /* 列出文件 */   
  •             if ( i == ERR_MISS_DIR ) pCodeStr = (UINT8 *)"/*";  /* C51子目录不存在则列出根目录下的文件 */   
  •             else pCodeStr = (UINT8 *)"/C51/CH375*";  /* CH375HFT.C文件不存在则列出\C51子目录下的以CH375开头的文件 */   
  •             printf( "List file %s\n", pCodeStr );   
  •             for ( c = 0; c < 254; c ++ ) {  /* 最多搜索前254个文件 */   
  •                 strcpy( (char *)CMD_PARAM.Open.mPathName, (char *)pCodeStr );  /* 搜索文件名,*为通配符,适用于所有文件或者子目录 */   
  •                 i = strlen( (char *)CMD_PARAM.Open.mPathName );  /* 计算文件名长度,以处理文件名结束符 */   
  •                 CMD_PARAM.Open.mPathName[ i ] = c;  /* 根据字符串长度将结束符替换为搜索的序号,从0到255 */   
  •                 i = CH375FileOpen( );  /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */   
  •                 if ( i == ERR_MISS_FILE ) break;  /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */   
  •                 if ( i == ERR_FOUND_NAME ) {  /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */   
  •                     printf( "  match file %03d#: %s\n", (unsigned int)c, CMD_PARAM.Open.mPathName );  /* 显示序号和搜索到的匹配文件名或者子目录名 */   
  •                     continue;  /* 继续搜索下一个匹配的文件名,下次搜索时序号会加1 */   
  •                 }   
  •                 else {  /* 出错 */   
  •                     mStopIfError( i );   
  •                     break;   
  •                 }   
  •             }   
  •         }   
  •         else {  /* 找到文件或者出错 */   
  •             mStopIfError( i );   
  •             TotalCount = 600;  /* 准备读取总长度 */   
  •             printf( "从文件中读出的前%d个字符是:\n",TotalCount );   
  •             while ( TotalCount ) {  /* 如果文件比较大,一次读不完,可以再调用CH375ByteRead继续读取,文件指针自动向后移动 */   
  •                 if ( TotalCount > MAX_BYTE_IO ) c = MAX_BYTE_IO;  /* 剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.ByteRead.mByteBuffer ) */   
  •                 else c = TotalCount;  /* 最后剩余的字节数 */   
  •                 CMD_PARAM.ByteRead.mByteCount = c;  /* 请求读出几十字节数据 */   
  •                 i = CH375ByteRead( );  /* 以字节为单位读取数据块,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后读 */   
  •                 mStopIfError( i );   
  •                 TotalCount -=CMD_PARAM.ByteRead.mByteCount;  /* 计数,减去当前实际已经读出的字符数 */   
  •                 for ( i=0; i!=CMD_PARAM.ByteRead.mByteCount; i++ )  {printf( "%c", CMD_PARAM.ByteRead.mByteBuffer[i] ); } /* 显示读出的字符 */   
  •                 if ( CMD_PARAM.ByteRead.mByteCount < c ) {  /* 实际读出的字符数少于要求读出的字符数,说明已经到文件的结尾 */   
  •                     printf( "\n" );   
  •                     printf( "文件已经结束\n" );   
  •                     break;   
  •                 }   
  •     
  •            }   
  •        }   
  •  }