久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3086|回復: 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 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久99 | 成人国产精品久久久 | 欧美黄在线观看 | 亚洲成人a v | 欧美日韩亚洲三区 | 国产一区二区电影 | 99精品久久久久久中文字幕 | 国产精品视频500部 a久久 | h片免费看| 国产精品久久国产愉拍 | 欧美日韩久久久久 | 欧美成人免费在线 | 国产精品久久在线 | 日韩一区精品 | 黑人巨大精品欧美一区二区免费 | 香蕉大人久久国产成人av | 91色视频在线观看 | www.午夜 | 精品综合久久久 | 日韩av一区二区在线观看 | 午夜精品一区二区三区在线播放 | 国产精品久久久久久238 | 久久久久久国产精品免费免费狐狸 | 久久久久国产 | 日日骚网 | 午夜精品影院 | 欧美精品在线播放 | 久久久亚洲 | 91视频免费在观看 | 青青久久久 | 国产视频线观看永久免费 | 国产高清视频在线播放 | 日韩在线不卡 | 精品国产乱码久久久久久影片 | 免费视频成人国产精品网站 | 精品福利一区二区三区 | 久在线精品视频 | 国产一区二区三区在线看 | 欧美精品乱码久久久久久按摩 | 美女一级毛片 | a国产一区二区免费入口 |