找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2621|回复: 0
打印 上一主题 下一主题
收起左侧

ch372 51单片机例程及库文件

[复制链接]
跳转到指定楼层
楼主
内含51读写操作ch372/ch373的例程及库文件,有需要的小伙伴可以下载哦。
CH372+MCU的U盘方案:C语言源程序 V1.1

1、硬件需求:普通的MCS51单片机,CH372(或者CH375),存储器(SRAM或者闪存等)
2、用途:了解U盘的程序原理,设计自己的U盘/闪存盘/SRAM盘等,
   可以直接将仪器的数据以U盘形式交给计算机,计算机端无需驱动程序
3、这是一个基于CH375/CH372通用接口芯片用62256作存储的U盘方案。
   其中CH375/CH372使用外置固件的设备模式,存储器用62256只是用于演示用。
   实际应用应根据存储器的种类和容量做相应修改。
   本方案只是一个例程所以在一些问题上没有细化,实际应用中要注意。
4、使用前,需要加上头文件 CH375INC.H 才能编译通过,该文件在网上评估板资料中有。
5、方案中有一个文件系统,是我们调试时用的,这个文件系统适应于存储器比较小的系统。
   当然你可以不用,让WINDOWS来格式化就可以了。只是在容量小于20K时WINDOWS就格不了。
6、DOCUMENT目录下是相关英文技术规范文档。



单片机源程序如下:
  1. /* 可引导U盘方案 CH372/CH375 + MCS51 + EEPROM24CXX
  2. ;
  3. ;****************************************************************************
  4. UDISK程序
  5. 用32K的SRAM62256做小容量的U盘,可以替换为闪存做成真正的U盘
  6. */

  7. /* MCS-51单片机C语言的示例程序 */
  8. #define MY_DISK_SIZE  0x00000040        /* U盘容量 */

  9. #pragma NOAREGS
  10. #include <reg52.h>
  11. #include "CH375INC.H"
  12. #include  "USBDISK.H"

  13. unsigned char mVarSetupRequest;                                                 //USB请求码
  14. unsigned char mVarSetupLength;                                             //        控制传输后续数据长度
  15. unsigned char  code * VarSetupDescr;                             //描述符偏移地址
  16. unsigned char idata VarUsbAddress;                                                 //USB分配地址

  17. union {
  18. unsigned int mDataLength;                                                        //数据长度
  19. unsigned char mdataLen[2];                                                        //
  20. } LEN;
  21. unsigned int  XDataAdd;                                                                //数据地址
  22.                                                                                                         //因为在此用的是256作存储,所以用的是整型

  23. unsigned char        BcswStatus;                                                        //CSW状态
  24. bit CH375FLAGERR;                                                                        //错误清0
  25. bit        CH375CONFLAG;                                                     //配置标志
  26. bit CH375BULKUP;                                                                        //数据上传
  27. bit CH375BULKDOWN;                                                                        //数据下传
  28. bit CH375CSW;                                                                                //CSW上传标志
  29. bit FSTALL;                                                                                        //数据错误标志
  30. bit lastFSTALL;
  31. unsigned char  *pBuf;                                                                //端点2上传下传全局数据指针
  32. unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1;                /* CH375命令端口的I/O地址 */
  33. unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0;                /* CH375数据端口的I/O地址 */
  34. unsigned char  xdata *pXDatbuf;                                                                //存储器地址指针
  35. mREQUEST_PACKET  request;
  36. MASS_PARA  MassPara;
  37. sbit  CH375ACT  = P1^4;
  38. unsigned char mSenseKey;
  39. unsigned char mASC;
  40. unsigned char mdCBWTag[4];                                                //dCBWTag

  41. void DiskInit(){                                                                //本子程序用于对SRAM进行初始化,默认格式化
  42.         unsigned char  xdata *IntData;
  43.         unsigned int i;
  44.         IntData=0;
  45.         if(*IntData==0xEB){
  46.                 IntData++;
  47.                 if(*IntData==0x3E){
  48.                           IntData++;
  49.                           if(*IntData==0x90)return;
  50.                         }
  51.                 }                // 如果有文件信息则不格式化
  52.         IntData=0;                                                                //自己写入FAT文件系统
  53.         for (i=0;i!=0X200;i++){
  54.          *IntData=DBR[i];
  55.                 IntData++;
  56.         }
  57.                                                                         //自己写入FAT文件系统
  58.         for (i=0;i!=0X200;i++){
  59.          *IntData=FAT[i];
  60.                 IntData++;
  61.         }
  62.         if ( DBR[0x11] == 2 ) {  // 两个FAT表
  63.                 for (i=0;i!=0X200;i++){
  64.                  *IntData=FAT[i];
  65.                         IntData++;
  66.                 }
  67.         }                                                                //自己写入DIR文件系统
  68.         for (i=0;i!=0X200;i++){
  69.          *IntData=ROOT[i];
  70.                 IntData++;
  71.         }

  72. }

  73. #define Delay1us()          /* 对于MCS51,因其速度较慢,完全不需要该子程序 */

  74. //void Delay1us(){  /* 对于MCS51,因其速度较慢,完全不需要该子程序 */
  75. //        for ( i=DELAY_START_VALUE; i!=0; i-- );
  76. //}

  77. void        Delay2us( )
  78. {
  79.         unsigned char i;
  80. #define DELAY_START_VALUE        1                                                                  /* 根据单片机的时钟选择初值,20MHz以下为0,30MHz以上为2 */
  81.         for ( i=DELAY_START_VALUE; i!=0; i-- );
  82. }

  83. /* 延时50毫秒,不精确 */
  84. void        Delay50ms( )
  85. {
  86.         unsigned char i, j;
  87.         for ( i=200; i!=0; i-- ) for ( j=250; j!=0; j-- );
  88. }

  89. void CH375_WR_CMD_PORT( unsigned char cmd ) {                                  /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */
  90.         Delay2us( );
  91.         CH375_CMD_PORT=cmd;
  92.         Delay2us( );
  93. }

  94. void CH375_WR_DAT_PORT( unsigned char dat ) {                                  /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */
  95.         CH375_DAT_PORT=dat;
  96.           Delay1us( );  /* 因为MCS51单片机较慢所以实际上无需延时 */
  97. }

  98. unsigned char CH375_RD_DAT_PORT() {                                                  /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */
  99.          Delay1us( );  /* 因为MCS51单片机较慢所以实际上无需延时 */
  100.         return( CH375_DAT_PORT );
  101. }

  102. /* CH375初始化子程序 */
  103. void        CH375_Init( )
  104. {
  105.         unsigned char i;
  106. /* 设置USB工作模式, 必要操作 */
  107.         CH375_WR_CMD_PORT( CMD_SET_USB_MODE );
  108.         CH375_WR_DAT_PORT( 1 );                                                                          /* 设置为使用内置固件的USB设备方式 */
  109.         Delay2us( );
  110.         for ( i=0xff; i!=0; i-- ) {                                                                                          /* 等待操作成功,通常需要等待10uS-20uS */
  111.                 if ( CH375_RD_DAT_PORT()==CMD_RET_SUCCESS ) break;
  112.         }
  113. /* 下述启用中断,假定CH375连接在INT0 */
  114.         IT0 = 0;  /* 置外部信号为低电平触发 */
  115.         IE0 = 0;  /* 清中断标志 */
  116.         EX0 = 1;  /* 允许CH375中断 */
  117. }

  118. //*****************************************************************************
  119. //BLOCK ONLY  The Thirteen Cases

  120. void  BulkThirteen(unsigned char Case)
  121. {
  122.         switch(Case)
  123.         {
  124.         case CASEOK:
  125.         case CASE1:                                                                             /* Hn=Dn*/
  126.         case CASE6:                                                                             /* Hi=Di*/
  127.                 BcswStatus = 0;
  128.                 break;
  129.         case CASE12:                                                                            /* Ho=Do*/
  130.                 BcswStatus = 0;
  131.                 break;

  132.         case CASE2:                                                                             /* Hn<Di*/
  133.         case CASE3:                                                                             /* Hn<Do*/

  134.                 CH375_WR_CMD_PORT(CMD_SET_ENDP7);                                //清除端点2上传
  135.                 CH375_WR_DAT_PORT(0x0f);
  136.                 FSTALL=1;
  137.                                                                                                                 //这里上传端点设置一个STALL,待主机清掉 // may or may-not
  138.                 BcswStatus =2;
  139.                 break;

  140.         case CASE4:                                                                             /* Hi>Dn*/
  141.         case CASE5:                                                                             /* Hi>Di*/


  142.                 CH375_WR_CMD_PORT(CMD_SET_ENDP7);                                        //清除端点2上传
  143.                 CH375_WR_DAT_PORT(0x0f);
  144.                 FSTALL=1;
  145.                                                                                                                 //这里上传端点设置一个STALL,待主机清掉
  146.                 BcswStatus= 1;                                                                        //CSW_GOOD or CSW_FAIL
  147.                 break;


  148.         case CASE7:                                                                                     /* Hi<Di*/
  149.         case CASE8:                                                                             /* Hi<>Do */

  150.                         CH375_WR_CMD_PORT(CMD_SET_ENDP7);                                        //清除端点2上传
  151.                         CH375_WR_DAT_PORT(0x0f);
  152.                         FSTALL=1;
  153.                                                                                                         //这里上传端点设置一个STALL,待主机清掉
  154.                 BcswStatus = 2;
  155.                 break;

  156.         case CASE9:                                                                                     /* Ho>Dn*/
  157.         case CASE11:                                                                            /* Ho>Do*/

  158.         CH375_WR_CMD_PORT(CMD_SET_ENDP6);                                        //清除端点2上传
  159.                 CH375_WR_DAT_PORT(0x0f);
  160.                 FSTALL=1;
  161.                                                                                                         //这里上传端点设置一个STALL,待主机清掉
  162.         BcswStatus =1;                                                                        //CSW_GOOD or CSW_FAIL
  163.                 break;

  164.         case CASE10:                                                                    /* Ho<>Di */
  165.         case CASE13:                                                                    /* Ho<Do*/

  166.                 CH375_WR_CMD_PORT(CMD_SET_ENDP7);                                        //清除端点2上传
  167.                 CH375_WR_DAT_PORT(0x0f);
  168.                 FSTALL=1;
  169.                                                                                                         //这里上传端点设置一个STALL,待主机清掉
  170.                 CH375_WR_CMD_PORT(CMD_SET_ENDP6);                                        //清除端点2上传
  171.                 CH375_WR_DAT_PORT(0x0f);
  172.                                                                                                         //这里上传端点设置一个STALL,待主机清掉
  173.                 BcswStatus = 2;
  174.                 break;

  175.         case CASECBW:                                                                   /* invalid CBW */

  176.             CH375_WR_CMD_PORT(CMD_SET_ENDP7);
  177.                 CH375_WR_DAT_PORT(0x0f);
  178.                 FSTALL=1;
  179.                                                                                                 //这里上传端点设置一个STALL,待主机清掉
  180.                 CH375_WR_CMD_PORT(CMD_SET_ENDP6);
  181.                 CH375_WR_DAT_PORT(0x0f);
  182.                                                                                                 //这里上传端点设置一个STALL,待主机清掉

  183.                 BcswStatus = 2;
  184.                 break;

  185.         case CASECMDFAIL:

  186.                   CH375_WR_CMD_PORT(CMD_SET_ENDP7);
  187.                 CH375_WR_DAT_PORT(0x0f);
  188.                 FSTALL=1;
  189.                                                                                                 //这里上传端点设置一个STALL,待主机清掉
  190.                 BcswStatus= 1;
  191.                 break;

  192.         default:
  193.                 break;
  194.         }
  195. }
  196. //*********************************************************

  197. //UFI  CMD
  198. void UFI_Hunding(void ){
  199.                 switch(MassPara.cbw.cbwcb.buf1[0]){
  200.                         case INQUIRY:
  201.                                 UFI_inquiry();
  202.                         break;
  203.                         case WRITE:
  204.                UFI_write();
  205.                         break;
  206.                         case TES_UNIT:
  207.                                 UFI_testUnit();
  208.                         break;
  209.                         case READ:
  210.                                 UFI_read10();
  211.                         break;
  212.                         case REQUEST_SENSE:
  213.                                 UFI_requestSense();
  214.                         break;
  215.                         case READ_CAPACITY:
  216.                 UFI_readCapacity();
  217.                         break;
  218.                         case VERIFY:
  219.                                 UFI_verify();
  220.                                 break;
  221.                 //        case 0x23:

  222.                 //        break;
  223.                 //        case MODE_SELECT:
  224.                         //        UFI_modeSlect();
  225.                 //        break;
  226.                         case MODE_SENSE:
  227.                                 UFI_modeSense();
  228.                         break;
  229.                                                                         case MODE_SENSE5:
  230.                                                                 UFI_modeSense5();
  231.                                                                         break;
  232.                 //        case WRITE_BUFFER:
  233.                 //                UFI_writeBuf();
  234.         //                break;
  235.         //                case PREVENT:
  236.                 //        break;
  237.         //                case FORMAT_UNIT:
  238.                 //                UFI_format();
  239.         //                break;
  240.         //                case RELEASE:
  241.         //                break;
  242.                         case STA_STO_UNIT:
  243.                                 UFI_staStoUnit();
  244.                         break;
  245.                         case PRE_OR_MED:
  246.                                 UFI_perOrMed();
  247.                         break;
  248.                         default:
  249.                                 mSenseKey=5;
  250.                                 mASC=0x20;
  251.                                 BcswStatus=1;
  252.                                 CH375BULKUP=0;
  253.                                 BulkThirteen(CASECBW);
  254.                                 break;
  255.                         }
  256. }

  257. /*//ufi协议处理
  258. void  UFI_format(void ){
  259.                                         //格式化命令不支持
  260.                 mSenseKey=5;
  261.                 mASCQ=0;
  262.                 mASC=0x20;
  263.                 BulkThirteen(CASECMDFAIL);
  264. }*/
  265. void  UFI_inquiry(void ){
  266.                 pBuf=DBINQUITY;                                        ////查询U盘信息
  267.                 if(LEN.mDataLength>36)LEN.mDataLength=36;
  268.                 BcswStatus=0;
  269.                 mSenseKey=0;
  270.                 mASC=0;
  271. }
  272. /*void  UFI_modeSlect(void ){
  273.                 BcswStatus=1;                                        //模式选择不支持
  274.                 mSenseKey=5;
  275.                 mASCQ=0;
  276.                 mASC=0x20;

  277. }                //*/
  278. void  UFI_modeSense(void ){
  279.                                                                                 //模式认识
  280.                 if(MassPara.cbw.cbwcb.buf1[2]==0x3F){
  281.                         if ( LEN.mDataLength > sizeof(modesense3F) ) LEN.mDataLength = sizeof(modesense3F);
  282.                         pBuf=modesense3F;
  283.                         BcswStatus=0;
  284.                         mSenseKey=0;
  285.                         mASC=0;
  286.                 }
  287.                 else {
  288.                         CH375BULKUP=0;
  289.                                                                         mSenseKey=5;
  290.                                                                         mASC=0x20;

  291.                                                                         BcswStatus=1;
  292.                         BulkThirteen(CASECMDFAIL);
  293.                    }
  294. }
  295. void  UFI_modeSense5(void ){

  296.                 if(MassPara.cbw.cbwcb.buf1[2]==0x3F){
  297.                         if ( LEN.mDataLength > sizeof(mode5sense3F) ) LEN.mDataLength = sizeof(mode5sense3F);
  298.                         pBuf=mode5sense3F;
  299.                         BcswStatus=0;
  300.                         mSenseKey=0;
  301.                         mASC=0;
  302.                 }
  303.                 else {
  304.                         CH375BULKUP=0;
  305.                         mSenseKey=5;
  306.                         mASC=0x20;
  307.                         BcswStatus=1;
  308.                         BulkThirteen(CASECMDFAIL);
  309.                    }
  310. }
  311. void  UFI_perOrMed(void ){                                //允许移出磁盘
  312.                 BcswStatus=0;
  313.                 mSenseKey=0;
  314.                 mASC=0;
  315. }

  316. //这里因为是用62256做优盘所以地址不超过32K,高地址先不关心
  317. void  UFI_read10(void){
  318.                                                                                                         //读取数据
  319.                 LEN.mDataLength=MassPara.cbw.cbwcb.buf1[8]*512;
  320.                 pXDatbuf=MassPara.cbw.cbwcb.buf1[5]*512;
  321.                 pBuf=pXDatbuf;
  322.                 BcswStatus=0;
  323.                 mSenseKey=0;
  324.                 mASC=0;

  325. }
  326. void  UFI_readCapacity(void ){
  327.                 if ( LEN.mDataLength > sizeof(DBCAPACITY) ) LEN.mDataLength = sizeof(DBCAPACITY);
  328.                 pBuf=(unsigned char*)DBCAPACITY;                                                                //读取容量
  329.                 BcswStatus=0;
  330.                 mSenseKey=0;
  331.                 mASC=0;
  332. }

  333. void  UFI_verify(void ){
  334.                 BcswStatus=0;                //校验存储器空间
  335.                 mSenseKey=0;
  336.                 mASC=0;
  337.                                         //这里这里只是作为演示所以没有真正检测物理存储器
  338.                                         //但实际上这一步一定要处理
  339. }

  340. void  UFI_requestSense(void ){
  341.                                                                                         //请求认识
  342.         if ( FSTALL | lastFSTALL ) {
  343.                 lastFSTALL=FSTALL;
  344.                 FSTALL=0;
  345.                 MassPara.Sense.ErrorCode=0x70;
  346.                 MassPara.Sense.Reserved1=0;
  347.                 MassPara.Sense.SenseKey=mSenseKey;
  348.                 MassPara.Sense.Information[0]=0;
  349.                 MassPara.Sense.Information[1]=0;
  350.                 MassPara.Sense.Information[2]=0;
  351.                 MassPara.Sense.Information[3]=0;
  352.                 MassPara.Sense.AddSenseLength=0x0a;
  353.                 MassPara.Sense.Reserved2[0]=0;
  354.                 MassPara.Sense.Reserved2[1]=0;
  355.                 MassPara.Sense.Reserved2[2]=0;
  356.                 MassPara.Sense.Reserved2[3]=0;
  357.                 MassPara.Sense.AddSenseCode=mASC;
  358.                 MassPara.Sense.AddSenseCodeQua=00;
  359.                 MassPara.Sense.Reserved3[0]=0;
  360.                 MassPara.Sense.Reserved3[1]=0;
  361.                 MassPara.Sense.Reserved3[2]=0;
  362.                 MassPara.Sense.Reserved3[3]=0;
  363.                 pBuf=MassPara.buf;
  364.                 BcswStatus=0;
  365.         }
  366.         else {
  367.                 lastFSTALL=FSTALL;
  368.                 FSTALL=0;
  369.                 MassPara.Sense.ErrorCode=0x70;
  370.                 MassPara.Sense.Reserved1=0;
  371.                 MassPara.Sense.SenseKey=0x00;
  372.                 MassPara.Sense.Information[0]=0;
  373.                 MassPara.Sense.Information[1]=0;
  374.                 MassPara.Sense.Information[2]=0;
  375.                 MassPara.Sense.Information[3]=0;
  376.                 MassPara.Sense.AddSenseLength=0x0a;
  377.                 MassPara.Sense.Reserved2[0]=0;
  378.                 MassPara.Sense.Reserved2[1]=0;
  379.                 MassPara.Sense.Reserved2[2]=0;
  380.                 MassPara.Sense.Reserved2[3]=0;
  381.                 MassPara.Sense.AddSenseCode=0x00;
  382.                 MassPara.Sense.AddSenseCodeQua=00;
  383.                 MassPara.Sense.Reserved3[0]=0;
  384.                 MassPara.Sense.Reserved3[1]=0;
  385.                 MassPara.Sense.Reserved3[2]=0;
  386.                 MassPara.Sense.Reserved3[3]=0;
  387.                 pBuf=MassPara.buf;
  388.                 BcswStatus=0;
  389.         }
  390. }
  391. void  UFI_staStoUnit(void ){
  392.                 CH375BULKDOWN=0;
  393.                 CH375BULKUP=0;
  394.                 BcswStatus=0;
  395.                         mSenseKey=0;
  396.                         mASC=0;
  397. }
  398. void  UFI_testUnit(void ){
  399.                         CH375BULKDOWN=0;
  400.                         CH375BULKUP=0;
  401.                 BcswStatus=0;                        //测试U盘是否准备好
  402.                 mSenseKey=0;
  403.                 mASC=0;
  404. }

  405. void  UFI_write(void ){
  406.         LEN.mDataLength=MassPara.cbw.cbwcb.buf1[8]*512;                //写数据
  407.                 pXDatbuf=MassPara.cbw.cbwcb.buf1[5]*512;                //取外部RAM的首地址
  408.                 pBuf=pXDatbuf;
  409.                 BcswStatus=0;
  410.                 mSenseKey=0;
  411.                 mASC=0;
  412. }

  413. //UFI END
  414. //**********************************************************************************
  415. void CH375bulkUpData(){                                                                                        //调用端点2上传数据
  416.                 unsigned char len;
  417.                 if(LEN.mDataLength>0x40){
  418.                         len=0x40;
  419.                         LEN.mDataLength-=0x40;
  420.                 }
  421.                 else {
  422.                         len= (unsigned char) LEN.mDataLength;
  423.                         LEN.mDataLength=0;
  424.                         CH375BULKUP=0;
  425.                 }
  426.         CH375_WR_CMD_PORT(CMD_WR_USB_DATA7);                                                //发出写端点0的命令
  427.           CH375_WR_DAT_PORT(len);
  428.         do{
  429.                 CH375_WR_DAT_PORT( *pBuf );
  430.                 pBuf++;
  431.         }while(--len);

  432. }

  433. void mCH375UpCsw()
  434. {
  435.                 unsigned char i;                                                                                                        //如果数据为0
  436.                 pBuf=&MassPara.buf[0];
  437.                 CH375CSW=0;                                                                                                                                        //上传CSW
  438.                 CH375BULKUP=0;                                                                                                                //取消数据上传
  439.                 MassPara.buf[0]=0x55;                                                                                                //dCSWSignature
  440.                 MassPara.buf[1]=0x53;
  441.                 MassPara.buf[2]=0x42;
  442.                 MassPara.buf[3]=0x53;
  443.                 MassPara.buf[4]=mdCBWTag[0];
  444.                 MassPara.buf[5]=mdCBWTag[1];
  445.                 MassPara.buf[6]=mdCBWTag[2];
  446.                 MassPara.buf[7]=mdCBWTag[3];
  447.                 MassPara.buf[8]=0;
  448.                 MassPara.buf[9]=0;
  449.                 MassPara.buf[10]=LEN.mdataLen[1];
  450.                 MassPara.buf[11]=LEN.mdataLen[0];
  451.                 MassPara.buf[12]=BcswStatus;
  452.                 CH375_WR_CMD_PORT(CMD_WR_USB_DATA7);                                                //发出写端点0的命令
  453.                   CH375_WR_DAT_PORT(13);
  454.                 for(i=0;i!=13;i++){
  455.                         CH375_WR_DAT_PORT(MassPara.buf[i]);
  456.                 }
  457. }
  458. void mCH375BulkOnly(){
  459.                         if(MassPara.buf[0]==0x55){
  460.                                 if(MassPara.buf[1]==0x53){
  461.                                    if(MassPara.buf[2]==0x42){
  462.                                             if(MassPara.buf[3]==0x43){
  463. //                                                        LEN.mDataLength=BIG_ENDIAN(MassPara.cbw.dCBWDatL);                        //做BO协议处理
  464.                                                         LEN.mdataLen[1]=*(unsigned char *)(&MassPara.cbw.dCBWDatL);  /* 将PC机的低字节在前的16位字数据转换为C51的高字节在前的数据 */
  465.                                                         LEN.mdataLen[0]=*( (unsigned char *)(&MassPara.cbw.dCBWDatL) + 1 );
  466.                                                         mdCBWTag[0]=MassPara.buf[4];
  467.                              mdCBWTag[1]=MassPara.buf[5];
  468.                               mdCBWTag[2]=MassPara.buf[6];
  469.                                   mdCBWTag[3]=MassPara.buf[7];                                                                                                          //取出数据长度
  470.                                                           if(LEN.mDataLength){
  471.                                                                         CH375BULKDOWN=(MassPara.cbw.bmCBWFlags&0X80)?0:1;        //判断是上传还是下传数据
  472.                                                                         CH375BULKUP=(MassPara.cbw.bmCBWFlags&0X80)?1:0;
  473.                                                                 }
  474.                                                   // if(!CBWLUN){                      //只支持一个物理盘
  475.                                                                 CH375CSW=1;
  476.                                                                 UFI_Hunding();
  477.                                                         //调用UFI协议处理
  478.                                                 //        }
  479.                                                         //        else ;//此处应做错误处理
  480.                                            }
  481.                                            else{ CH375_WR_CMD_PORT(CMD_SET_ENDP7);                                                        //清除端点2上传
  482.                                                                 CH375_WR_DAT_PORT(0x0f);
  483.                                                  }
  484.                                   }
  485.                                    else{ CH375_WR_CMD_PORT(CMD_SET_ENDP7);                                                        //清除端点2上传
  486.                                                                 CH375_WR_DAT_PORT(0x0f);
  487.                                                  }
  488.                              }
  489.                                  else{ CH375_WR_CMD_PORT(CMD_SET_ENDP7);                                                        //清除端点2上传
  490.                                                                 CH375_WR_DAT_PORT(0x0f);
  491.                                                  }
  492.                          }
  493.                         else { CH375_WR_CMD_PORT(CMD_SET_ENDP7);                                                        //清除端点2上传
  494.                                                 CH375_WR_DAT_PORT(0x0f);
  495.                                                  }
  496. }

  497. void mCH375BulkDownData(){
  498.                 unsigned char len;
  499.                 CH375_WR_CMD_PORT(CMD_RD_USB_DATA);                //发出读数据命令
  500.                   len=CH375_RD_DAT_PORT();                                //读出长度
  501.                                                                                                 //判?
  502.                         LEN.mDataLength-=len;                                //全局数据长度减掉当前获得的长度
  503.         do{
  504.                 *pBuf=CH375_RD_DAT_PORT();                                //复制数据进入存储区
  505.                 pBuf++;
  506.         }while(--len);
  507.         if(LEN.mDataLength==0){                                                                                                                //如果数据为0,则传送CSW
  508.                 CH375BULKDOWN=0;
  509.                 mCH375UpCsw();                                //上传CSW
  510.         }
  511. }

  512. //*********************************************************
  513. //端点0数据上传
  514. void mCh375Ep0Up(){
  515.         unsigned char i,len;
  516.         if(mVarSetupLength){                                                                                                //长度不为0传输具体长度的数据
  517.                 if(mVarSetupLength<=8){
  518.                         len=mVarSetupLength;
  519.                         mVarSetupLength=0;
  520.         }        //长度小于8则长输要求的长度
  521.                 else{
  522.                         len=8;
  523.                         mVarSetupLength-=8;
  524.                 }                                                                                                //长度大于8则传输8个,切总长度减8
  525.             CH375_WR_CMD_PORT(CMD_WR_USB_DATA3);                                                //发出写端点0的命令
  526.                CH375_WR_DAT_PORT(len);                                                                                //写入长度
  527.             for(i=0;i!=len;i++)
  528.         CH375_WR_DAT_PORT(request.buffer[i]);                                      //循环写入数据
  529.     }
  530.         else{
  531.                 CH375_WR_CMD_PORT(CMD_WR_USB_DATA3);                                                //发出写端点0的命令
  532.                 CH375_WR_DAT_PORT(0);                                                           //上传0长度数据,这是一个状态阶段
  533.         }
  534. }

  535. //复制描述符以便上传
  536. void mCh375DesUp(){
  537.         unsigned char k;
  538.         for (k=0; k!=8; k++ ) {
  539.          request.buffer[k]=*VarSetupDescr;                                                                  //依次复制8个描述符,
  540.          VarSetupDescr++;
  541.     }
  542. }

  543. /* CH375中断服务程序INT0,使用寄存器组1 */
  544. void        mCH375Interrupt( ) interrupt 0 using 1
  545. {
  546.         unsigned char InterruptStatus;
  547.         unsigned char length, len;
  548.         CH375_WR_CMD_PORT(CMD_GET_STATUS);                                                                          /* 获取中断状态并取消中断请求 */
  549.         InterruptStatus =CH375_RD_DAT_PORT();                                                                          /* 获取中断状态 */
  550.                                                                                                                                                           /* 清中断标志,对应于INT0中断 */
  551.         switch(InterruptStatus){  // 分析中断状态
  552.                 case  USB_INT_EP2_OUT:                                                                                          // 批量端点下传成功
  553.                         if(CH375BULKDOWN)mCH375BulkDownData();                                                                        //如果上传数据阶段则调用数据上传
  554.                         else{                                                                                         //不是数据下传则判断是否
  555.                                         CH375_WR_CMD_PORT(CMD_RD_USB_DATA);                                                                        //发出读数据命令
  556.                                         length=CH375_RD_DAT_PORT();
  557.                                         if(!length)break;                                                                //数据包长度为零则跳出
  558.                                                                                                                                 //首先读出的是长度
  559.                                         for(len=0;len!=length;len++) MassPara.buf[len]=CH375_RD_DAT_PORT();        //将数据读入到缓冲区
  560.                                         mCH375BulkOnly();

  561.                                         if(!CH375BULKDOWN){
  562.                                                 if(CH375BULKUP)CH375bulkUpData();                                        //调用批量数据上传
  563.                                                 else if(!FSTALL)mCH375UpCsw();                                                                //没有数据上传调用CSW上传
  564.                                                                                                                                                 //在这里做上传数据调用
  565.                                         }
  566.                         }
  567.                         break;
  568.                 case   USB_INT_EP2_IN:
  569.                         if(CH375BULKUP)CH375bulkUpData();                                                                //调用数据上传
  570.                         else if(CH375CSW)mCH375UpCsw();                                                                        //上传CSW
  571.             CH375_WR_CMD_PORT (CMD_UNLOCK_USB);                                                                 //批量端点上传成功,未处理
  572.                         break;
  573.                 case   USB_INT_EP1_IN:                                                                                                 //中断端点上传成功,未处理
  574.             CH375_WR_CMD_PORT (CMD_UNLOCK_USB);  //释放缓冲区
  575.                         break;
  576.                 case   USB_INT_EP1_OUT:                                                                                                  //中断端点下传成功,未处理
  577.             CH375_WR_CMD_PORT (CMD_UNLOCK_USB);  //释放缓冲区
  578.                         break;
  579.                 case   USB_INT_EP0_SETUP:                                                                                         //控制端点建立成功
  580.                     CH375FLAGERR=0;
  581.                         CH375_WR_CMD_PORT(CMD_RD_USB_DATA);
  582.                         length=CH375_RD_DAT_PORT();
  583.                         for(len=0;len!=length;len++)request.buffer[len]=CH375_RD_DAT_PORT();  // 取出数据
  584.                         if(length==0x08){
  585.                             mVarSetupLength=request.buffer[6]&0x7f;                                                        //控制传输数据长度最大设置为128
  586.                                 if((request.r.bmReuestType)&0x40){                                                  //厂商请求,未处理
  587.                                 }
  588.                                 if((request.r.bmReuestType)&0x20){                                                  //类请求,未处理
  589.                                         if(request.buffer[1]==0xfe)request.buffer[0]=0;                                //类请求得到逻辑盘数目,这里只有一个盘所以
  590.                                 //        else if(request.buffer[1]==0x00);                                                                //复位逻辑单元,这里未处理
  591.                                  }
  592.                                 if(!((request.r.bmReuestType)&0x60)){                                          //标准请求
  593.                                         mVarSetupRequest=request.r.bRequest;                                                        //暂存标准请求码
  594.                                         switch(request.r.bRequest){  // 分析标准请求
  595.                                                 case DEF_USB_CLR_FEATURE:                                                                        //清除特性
  596.                                                         if((request.r.bmReuestType&0x1F)==0X02){                                        //不是端点不支持
  597.                                                                 switch(request.buffer[4]){
  598.                                                                         case 0x82:
  599.                                                                                 CH375_WR_CMD_PORT(CMD_SET_ENDP7);                                        //清除端点2上传
  600.                                                                                 CH375_WR_DAT_PORT(0x8E);                                       //发命令清除端点
  601.                                                                                 if(CH375CSW)mCH375UpCsw();
  602.                                                                                 lastFSTALL=FSTALL;
  603.                                                                                 FSTALL=0;
  604.                                                                                 break;
  605.                                                                         case 0x02:
  606.                                                                                 CH375_WR_CMD_PORT(CMD_SET_ENDP6);
  607.                                                                                 CH375_WR_DAT_PORT(0x80);                                //清除端点2下传
  608.                                                                                 if(CH375CSW)mCH375UpCsw();
  609.                                                                                 lastFSTALL=FSTALL;
  610.                                                                                 FSTALL=0;
  611.                                                                                 break;
  612.                                                                         case 0x81:
  613.                                                                                 CH375_WR_CMD_PORT(CMD_SET_ENDP5);                                        //清除端点1上传
  614.                                                                                 CH375_WR_DAT_PORT(0x8E);
  615.                                                                                 break;
  616.                                                                         case 0x01:
  617.                                                                                 CH375_WR_CMD_PORT(CMD_SET_ENDP4);                                        //清除端点1下传
  618.                                                                                 CH375_WR_DAT_PORT(0x80);
  619.                                                                                 break;
  620.                                                                         default:
  621.                                                                                 break;
  622.                                                                 }
  623.                                                         }
  624.                                                         else{
  625.                                                                 CH375FLAGERR=1;                                                                //不支持的清除特性,置错误标志
  626.                                                         }
  627.                                                         break;
  628.                                                 case DEF_USB_GET_STATUS:                                                                //获得状态
  629.                                                         request.buffer[0]=0;
  630.                                                         request.buffer[1]=0;                                                                //上传状态
  631.                                                         break;
  632.                                                 case DEF_USB_SET_ADDRESS:                                                                //设置地址
  633.                                                         VarUsbAddress=request.buffer[2];                                        //暂存USB主机发来的地址
  634.                                                         break;
  635.                                                 case DEF_USB_GET_DESCR:                                                                 //获得描述符
  636.                                                         if(request.buffer[3]==1)                                                        //设备描述符上传
  637.                                                                 VarSetupDescr=DevDes;
  638.                                                         else if(request.buffer[3]==2)                                                         //配置描述符上传
  639.                                                                 VarSetupDescr=ConDes;
  640.                                                         else if(request.buffer[3]==3) {
  641.                                                                 if ( request.buffer[2]== 0 ) VarSetupDescr=LangDes;
  642.                                                                 else VarSetupDescr=SerDes;                                                 //做字符串处理
  643.                                                         }
  644.                                                         mCh375DesUp();                                                                                        //其余描述符不支持
  645.                                                         break;
  646.                                                 case DEF_USB_GET_CONFIG:                                                                        //获得配置
  647.                                                         request.buffer[0]=0;                                                                        //没有配置则传0
  648.                                                         if(CH375CONFLAG) request.buffer[0]=1;                                                                        //已经配置则传1;这是在描述符里规定的
  649.                                                         break;
  650.                                                 case DEF_USB_SET_CONFIG:                                                         //设置配置
  651.                                                         CH375CONFLAG=0;
  652.                                                         CH375ACT=1;
  653.                                                         if ( request.buffer[2] != 0 ) {
  654.                                                                 CH375CONFLAG=1;                                                                                        //设置配置标志
  655.                                                                 CH375ACT=0;                                                                                                //输出配置完成信号
  656.                                                         }
  657.                                                         break;
  658.                                                 case DEF_USB_GET_INTERF:                                                                                //得到接口
  659.                                                         request.buffer[0]=1;                                                                        //上传接口数,本事例只支持一个接口
  660.                                                         break;
  661.                                                 case DEF_USB_SET_INTERF:                                                                                //设置接口
  662.                                                         break;
  663.                                                 default :
  664.                                                         break;                                                                                                        //不支持的标准请求
  665.                                         }
  666.                                 }
  667.                         }
  668.                         else {  //不支持的控制传输,不是8字节的控制传输
  669.                                 CH375FLAGERR=1;
  670.                         }
  671.                         if(!CH375FLAGERR) mCh375Ep0Up();                                                                                //没有错误/调用数据上传,,长度为0上传为状态
  672.                         else {
  673.                                 CH375_WR_CMD_PORT(CMD_SET_ENDP3);                                                                //设置端点1为STALL,指示一个错误
  674.                                 CH375_WR_DAT_PORT(0x0F);
  675.                         }
  676.             CH375_WR_CMD_PORT (CMD_UNLOCK_USB);
  677.                         break;
  678.                 case   USB_INT_EP0_IN:
  679.             CH375_WR_CMD_PORT (CMD_UNLOCK_USB);                                                                                                //控制端点上串成功
  680.                         if(mVarSetupRequest==DEF_USB_GET_DESCR){                                                                //描述符上传
  681.                                 mCh375DesUp();
  682.                                 mCh375Ep0Up();
  683.                         }
  684.                         else if(mVarSetupRequest==DEF_USB_SET_ADDRESS){                                                        //设置地址
  685.                                 CH375_WR_CMD_PORT(CMD_SET_USB_ADDR);
  686.                                 CH375_WR_DAT_PORT(VarUsbAddress);                                                                //设置USB地址,设置下次事务的USB地址
  687.                         }
  688.                         break;
  689.                 case   USB_INT_EP0_OUT:                                                                                                        //控制端点下传成功
  690.             CH375_WR_CMD_PORT (CMD_UNLOCK_USB);  //释放缓冲区
  691.                         break;
  692.                 default:
  693.                         if((InterruptStatus&0x03)==0x03){                                                                        //总线复位
  694.                                 FSTALL=0;
  695.                                 CH375FLAGERR=0;                                                                                                        //错误清0
  696.                                 CH375CONFLAG=0;                                                                                                        //配置清0
  697.                                 mVarSetupLength=0;
  698.                                  CH375FLAGERR=0;                                                                                                //错误清0
  699.                                  CH375BULKUP=0;                                                                                                        //
  700.                                 CH375BULKDOWN=0;
  701.                                  CH375CSW=0;
  702.                                 FSTALL=0;
  703.                                 CH375ACT=1;                                                                                                                //清配置完成输出
  704.                         }
  705.                         else{                                                                                                                                //命令不支持
  706.                                 ;
  707.                         }
  708.             CH375_WR_CMD_PORT (CMD_UNLOCK_USB);  //释放缓冲区
  709.                         CH375_RD_DAT_PORT( );
  710.                         break;
  711.         }
  712. }

  713. main( ) {
  714.         Delay50ms( );        /* 延时等待CH375初始化完成,如果单片机由CH375提供复位信号则不必延时 */
  715.         Delay50ms( );        /* 延时等待CH375初始化完成,如果单片机由CH375提供复位信号则不必延时 */
  716.         DiskInit();                //对SRAM进行初始化,默认格式化,如果是闪存那么应该跳过此步
  717.         CH375_Init( );  /* 初始化CH375 */
  718.     EA=1;
  719.         while(1);
  720. }
复制代码

所有资料51hei提供下载:
CH372DSK.ZIP (332.77 KB, 下载次数: 14)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表