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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 7372|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

CH549模擬USB鍵鼠復(fù)合設(shè)備源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:166208 發(fā)表于 2018-11-14 19:58 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
制作出來的實(shí)物圖如下:


單片機(jī)源程序如下:
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name          : CompositeKM.C
  3. * Author             : WCH
  4. * Version            : V1.0
  5. * Description        : CH549模擬USB鍵鼠復(fù)合設(shè)備,支持類命令,支持喚醒
  6.                        演示鍵盤鼠標(biāo)簡(jiǎn)單操作。其他鍵值,參考 HID USAGE TABLE協(xié)議文檔
  7.                        串口0接收字符:
  8.                        ‘L’:鼠標(biāo)左鍵
  9.                        ‘R’: 鼠標(biāo)右鍵
  10.                        ‘A’: 鍵盤‘A’鍵
  11.                        ‘Q’: 鍵盤‘Caps’鍵
  12.                     任意字符:主機(jī)睡眠狀態(tài)下,設(shè)備遠(yuǎn)程喚醒主機(jī)(注意設(shè)備一般需自供電,因?yàn)橹鳈C(jī)休眠可能USB口也會(huì)掉電)
  13. *******************************************************************************/
  14. #include ".\Public\CH549.H"
  15. #include ".\Public\DEBUG.H"
  16. //#define Fullspeed
  17. #ifdef  Fullspeed
  18. #define THIS_ENDP0_SIZE         64
  19. #else
  20. #define THIS_ENDP0_SIZE         8                                              //低速USB,中斷傳輸、控制傳輸最大包長(zhǎng)度為8
  21. #endif
  22. #define EP1_IN_SIZE             8                                              //鍵盤端點(diǎn)數(shù)據(jù)包大小
  23. #define EP2_IN_SIZE             4                                              //鼠標(biāo)端點(diǎn)數(shù)據(jù)包大小
  24. UINT8X  Ep0Buffer[ THIS_ENDP0_SIZE+2 ] _at_ 0x0000;                            //端點(diǎn)0 OUT&IN緩沖區(qū),必須是偶地址
  25. UINT8X  Ep1Buffer[ EP1_IN_SIZE+2 ]     _at_ THIS_ENDP0_SIZE+2;                 //端點(diǎn)1 IN緩沖區(qū),必須是偶地址
  26. UINT8X  Ep2Buffer[ EP2_IN_SIZE+2 ]     _at_ THIS_ENDP0_SIZE+EP1_IN_SIZE+4;     //端點(diǎn)2 IN緩沖區(qū),必須是偶地址
  27. UINT8   SetupReq,Ready,UsbConfig;
  28. UINT16  SetupLen;
  29. PUINT8  pDescr;                                                                //USB配置標(biāo)志
  30. USB_SETUP_REQ   SetupReqBuf;                                                   //暫存Setup包
  31. #define UsbSetupBuf     ((PUSB_SETUP_REQ)Ep0Buffer)
  32. #pragma  NOAREGS
  33. /*設(shè)備描述符*/
  34. UINT8C DevDesc[] = { 0x12,0x01,0x10,0x01,0x00,0x00,0x00,THIS_ENDP0_SIZE,
  35.                      0x86,0x1a,0xe1,0xe6,0x00,0x01,0x01,0x02,
  36.                      0x00,0x01
  37.                    };
  38. /*字符串描述符*/
  39. UINT8C  MyLangDescr[] = { 0x04, 0x03, 0x09, 0x04 };                                    // 語言描述符
  40. UINT8C  MyManuInfo[] = { 0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0 }; // 廠家信息
  41. UINT8C  MyProdInfo[] = { 0x0C, 0x03, 'C', 0, 'H', 0, '5', 0, '4', 0, '9', 0 };         // 產(chǎn)品信息
  42. /*HID類報(bào)表描述符*/
  43. UINT8C KeyRepDesc[] =
  44. {
  45.     0x05,0x01,0x09,0x06,0xA1,0x01,0x05,0x07,
  46.     0x19,0xe0,0x29,0xe7,0x15,0x00,0x25,0x01,
  47.     0x75,0x01,0x95,0x08,0x81,0x02,0x95,0x01,
  48.     0x75,0x08,0x81,0x01,0x95,0x03,0x75,0x01,
  49.     0x05,0x08,0x19,0x01,0x29,0x03,0x91,0x02,
  50.     0x95,0x05,0x75,0x01,0x91,0x01,0x95,0x06,
  51.     0x75,0x08,0x26,0xff,0x00,0x05,0x07,0x19,
  52.     0x00,0x29,0x91,0x81,0x00,0xC0
  53. };
  54. UINT8C MouseRepDesc[] =
  55. {
  56.     0x05,0x01,0x09,0x02,0xA1,0x01,0x09,0x01,
  57.     0xA1,0x00,0x05,0x09,0x19,0x01,0x29,0x03,
  58.     0x15,0x00,0x25,0x01,0x75,0x01,0x95,0x03,
  59.     0x81,0x02,0x75,0x05,0x95,0x01,0x81,0x01,
  60.     0x05,0x01,0x09,0x30,0x09,0x31,0x09,0x38,
  61.     0x15,0x81,0x25,0x7f,0x75,0x08,0x95,0x03,
  62.     0x81,0x06,0xC0,0xC0
  63. };
  64. /*配置描述符*/
  65. UINT8C CfgDesc[] =
  66. {
  67.     0x09,0x02,0x3b,0x00,0x02,0x01,0x00,0xA0,0x32,                    //配置描述符

  68.     0x09,0x04,0x00,0x00,0x01,0x03,0x01,0x01,0x00,                    //接口描述符,鍵盤
  69.     0x09,0x21,0x11,0x01,0x00,0x01,0x22,sizeof(KeyRepDesc)&0xFF,sizeof(KeyRepDesc)>>8,//HID類描述符
  70.     0x07,0x05,0x81,0x03,EP1_IN_SIZE,0x00,0x0a,                       //端點(diǎn)描述符

  71.     0x09,0x04,0x01,0x00,0x01,0x03,0x01,0x02,0x00,                    //接口描述符,鼠標(biāo)
  72.     0x09,0x21,0x10,0x01,0x00,0x01,0x22,sizeof(MouseRepDesc)&0xFF,sizeof(MouseRepDesc)>>8,//HID類描述符
  73.     0x07,0x05,0x82,0x03,EP2_IN_SIZE,0x00,0x0a                        //端點(diǎn)描述符
  74. };
  75. /*鍵盤數(shù)據(jù)*/
  76. UINT8 HIDKey[EP1_IN_SIZE];
  77. /*鼠標(biāo)數(shù)據(jù)*/
  78. UINT8 HIDMouse[EP2_IN_SIZE];
  79. UINT8 Endp1Busy = 0;                                                 //傳輸完成控制標(biāo)志位
  80. UINT8 Endp2Busy = 0;
  81. UINT8 WakeUpEnFlag = 0;                                              //遠(yuǎn)程喚醒使能標(biāo)志
  82. /*******************************************************************************
  83. * Function Name  : CH554USBDevWakeup()
  84. * Description    : CH554設(shè)備模式喚醒主機(jī),發(fā)送K信號(hào)
  85. * Input          : None
  86. * Output         : None
  87. * Return         : None
  88. *******************************************************************************/
  89. void CH554USBDevWakeup( )
  90. {
  91. #ifdef Fullspeed
  92.     UDEV_CTRL |= bUD_LOW_SPEED;
  93.     mDelaymS(2);
  94.     UDEV_CTRL &= ~bUD_LOW_SPEED;
  95. #else
  96.     UDEV_CTRL &= ~bUD_LOW_SPEED;
  97.     mDelaymS(2);
  98.     UDEV_CTRL |= bUD_LOW_SPEED;
  99. #endif
  100. }
  101. /*******************************************************************************
  102. * Function Name  : USBDeviceInit()
  103. * Description    : USB設(shè)備模式配置,設(shè)備模式啟動(dòng),收發(fā)端點(diǎn)配置,中斷開啟
  104. * Input          : None
  105. * Output         : None
  106. * Return         : None
  107. *******************************************************************************/
  108. void USBDeviceInit()
  109. {
  110.     IE_USB = 0;
  111.     USB_CTRL = 0x00;                                                           // 先設(shè)定USB設(shè)備模式
  112.     UDEV_CTRL = bUD_PD_DIS;                                                    // 禁止DP/DM下拉電阻
  113. #ifndef Fullspeed
  114.     UDEV_CTRL |= bUD_LOW_SPEED;                                                //選擇低速1.5M模式
  115.     USB_CTRL |= bUC_LOW_SPEED;
  116. #else
  117.     UDEV_CTRL &= ~bUD_LOW_SPEED;                                               //選擇全速12M模式,默認(rèn)方式
  118.     USB_CTRL &= ~bUC_LOW_SPEED;
  119. #endif
  120.     UEP1_T_LEN = 0;                                                            //預(yù)使用發(fā)送長(zhǎng)度一定要清空
  121.     UEP2_T_LEN = 0;                                                            //預(yù)使用發(fā)送長(zhǎng)度一定要清空
  122.     UEP2_DMA = Ep2Buffer;                                                      //端點(diǎn)2數(shù)據(jù)傳輸?shù)刂?br />
  123.     UEP2_3_MOD = UEP2_3_MOD & ~bUEP2_BUF_MOD | bUEP2_TX_EN;                    //端點(diǎn)2發(fā)送使能 64字節(jié)緩沖區(qū)
  124.     UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK;                                 //端點(diǎn)2自動(dòng)翻轉(zhuǎn)同步標(biāo)志位,IN事務(wù)返回NAK
  125.     UEP0_DMA = Ep0Buffer;                                                      //端點(diǎn)0數(shù)據(jù)傳輸?shù)刂?br />
  126.     UEP4_1_MOD &= ~(bUEP4_RX_EN | bUEP4_TX_EN);                                //端點(diǎn)0單64字節(jié)收發(fā)緩沖區(qū)
  127.     UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;                                 //OUT事務(wù)返回ACK,IN事務(wù)返回NAK
  128.     UEP1_DMA = Ep1Buffer;                                                      //端點(diǎn)1數(shù)據(jù)傳輸?shù)刂?br />
  129.     UEP4_1_MOD = UEP4_1_MOD & ~bUEP1_BUF_MOD | bUEP1_TX_EN;                    //端點(diǎn)1發(fā)送使能 64字節(jié)緩沖區(qū)
  130.     UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK;                                 //端點(diǎn)1自動(dòng)翻轉(zhuǎn)同步標(biāo)志位,IN事務(wù)返回NAK
  131.     USB_DEV_AD = 0x00;
  132.     USB_CTRL |= bUC_DEV_PU_EN | bUC_INT_BUSY | bUC_DMA_EN;                     // 啟動(dòng)USB設(shè)備及DMA,在中斷期間中斷標(biāo)志未清除前自動(dòng)返回NAK
  133.     UDEV_CTRL |= bUD_PORT_EN;                                                  // 允許USB端口
  134.     USB_INT_FG = 0xFF;                                                         // 清中斷標(biāo)志
  135.     USB_INT_EN = bUIE_SUSPEND | bUIE_TRANSFER | bUIE_BUS_RST;
  136.     IE_USB = 1;
  137. }
  138. /*******************************************************************************
  139. * Function Name  : Enp1IntIn
  140. * Description    : USB設(shè)備模式端點(diǎn)1的中斷上傳
  141. * Input          : None
  142. * Output         : None
  143. * Return         : None
  144. *******************************************************************************/
  145. void Enp1IntIn( UINT8 *buf,UINT8 len )
  146. {
  147.     memcpy( Ep1Buffer, buf, len );                                            //加載上傳數(shù)據(jù)
  148.     UEP1_T_LEN = len;                                                         //上傳數(shù)據(jù)長(zhǎng)度
  149.     UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK;                 //有數(shù)據(jù)時(shí)上傳數(shù)據(jù)并應(yīng)答ACK
  150. }
  151. /*******************************************************************************
  152. * Function Name  : Enp2IntIn()
  153. * Description    : USB設(shè)備模式端點(diǎn)2的中斷上傳
  154. * Input          : None
  155. * Output         : None
  156. * Return         : None
  157. *******************************************************************************/
  158. void Enp2IntIn( UINT8 *buf,UINT8 len )
  159. {
  160.     memcpy( Ep2Buffer, buf, len);                                              //加載上傳數(shù)據(jù)
  161.     UEP2_T_LEN = len;                                                          //上傳數(shù)據(jù)長(zhǎng)度
  162.     UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK;                  //有數(shù)據(jù)時(shí)上傳數(shù)據(jù)并應(yīng)答ACK
  163. }
  164. /*******************************************************************************
  165. * Function Name  : DeviceInterrupt()
  166. * Description    : CH559USB中斷處理函數(shù)
  167. *******************************************************************************/
  168. void    DeviceInterrupt( void ) interrupt INT_NO_USB using 1                    //USB中斷服務(wù)程序,使用寄存器組1
  169. {
  170.     UINT16 len = 0;
  171.     if(UIF_TRANSFER)                                                            //USB傳輸完成標(biāo)志
  172.     {
  173.         switch (USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP))
  174.         {
  175.         case UIS_TOKEN_IN | 2:                                                  //endpoint 2# 中斷端點(diǎn)上傳
  176.             UEP2_T_LEN = 0;                                                     //預(yù)使用發(fā)送長(zhǎng)度一定要清空
  177. //            UEP1_CTRL ^= bUEP_T_TOG;                                          //如果不設(shè)置自動(dòng)翻轉(zhuǎn)則需要手動(dòng)翻轉(zhuǎn)
  178.             Endp2Busy = 0;
  179.             UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK;           //默認(rèn)應(yīng)答NAK
  180.             break;
  181.         case UIS_TOKEN_IN | 1:                                                  //endpoint 1# 中斷端點(diǎn)上傳
  182.             UEP1_T_LEN = 0;                                                     //預(yù)使用發(fā)送長(zhǎng)度一定要清空
  183. //            UEP2_CTRL ^= bUEP_T_TOG;                                          //如果不設(shè)置自動(dòng)翻轉(zhuǎn)則需要手動(dòng)翻轉(zhuǎn)
  184.             Endp1Busy = 0;
  185.             UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK;           //默認(rèn)應(yīng)答NAK
  186.             break;
  187.         case UIS_TOKEN_SETUP | 0:                                               //SETUP事務(wù)
  188.             UEP0_CTRL = UEP0_CTRL & (~MASK_UEP_T_RES )| UEP_T_RES_NAK;          //預(yù)置NAK,防止stall之后不及時(shí)清除響應(yīng)方式
  189.             len = USB_RX_LEN;
  190.             if(len == (sizeof(USB_SETUP_REQ)))
  191.             {
  192.                 SetupLen = ((UINT16)UsbSetupBuf->wLengthH<<8) + UsbSetupBuf->wLengthL;
  193.                 len = 0;                                                        // 默認(rèn)為成功并且上傳0長(zhǎng)度
  194.                 SetupReq = UsbSetupBuf->bRequest;
  195.                 if ( ( UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )/* HID類命令 */
  196.                 {
  197.                     switch( SetupReq )
  198.                     {
  199.                     case 0x01://GetReport
  200.                         break;
  201.                     case 0x02://GetIdle
  202.                         break;
  203.                     case 0x03://GetProtocol
  204.                         break;
  205.                     case 0x09://SetReport
  206.                         break;
  207.                     case 0x0A://SetIdle
  208.                         break;
  209.                     case 0x0B://SetProtocol
  210.                         break;
  211.                     default:
  212.                         len = 0xFFFF;                                  /*命令不支持*/
  213.                         break;
  214.                     }
  215.                 }
  216.                 else
  217.                 {
  218.                     //標(biāo)準(zhǔn)請(qǐng)求
  219.                     switch(SetupReq)                                        //請(qǐng)求碼
  220.                     {
  221.                     case USB_GET_DESCRIPTOR:
  222.                         switch(UsbSetupBuf->wValueH)
  223.                         {
  224.                         case 1:                                             //設(shè)備描述符
  225.                             pDescr = DevDesc;                               //把設(shè)備描述符送到要發(fā)送的緩沖區(qū)
  226.                             len = sizeof(DevDesc);
  227.                             break;
  228.                         case 2:                                             //配置描述符
  229.                             pDescr = CfgDesc;                               //把設(shè)備描述符送到要發(fā)送的緩沖區(qū)
  230.                             len = sizeof(CfgDesc);
  231.                             break;
  232.                         case 3:
  233.                             switch( UsbSetupBuf->wValueL )
  234.                             {
  235.                             case 1:
  236.                                 pDescr = (PUINT8)( &MyManuInfo[0] );
  237.                                 len = sizeof( MyManuInfo );
  238.                                 break;
  239.                             case 2:
  240.                                 pDescr = (PUINT8)( &MyProdInfo[0] );
  241.                                 len = sizeof( MyProdInfo );
  242.                                 break;
  243.                             case 0:
  244.                                 pDescr = (PUINT8)( &MyLangDescr[0] );
  245.                                 len = sizeof( MyLangDescr );
  246.                                 break;
  247.                             default:
  248.                                 len = 0xFFFF;                           // 不支持的字符串描述符
  249.                                 break;
  250.                             }
  251.                             break;
  252.                         case 0x22:                                          //報(bào)表描述符
  253.                             if(UsbSetupBuf->wIndexL == 0)                   //接口0報(bào)表描述符
  254.                             {
  255.                                 pDescr = KeyRepDesc;                        //數(shù)據(jù)準(zhǔn)備上傳
  256.                                 len = sizeof(KeyRepDesc);
  257.                             }
  258.                             else if(UsbSetupBuf->wIndexL == 1)              //接口1報(bào)表描述符
  259.                             {
  260.                                 pDescr = MouseRepDesc;                      //數(shù)據(jù)準(zhǔn)備上傳
  261.                                 len = sizeof(MouseRepDesc);
  262.                             }
  263.                             else
  264.                             {
  265.                                 len = 0xFFFF;                                 //本程序只有2個(gè)接口,這句話正常不可能執(zhí)行
  266.                             }
  267.                             break;
  268.                         default:
  269.                             len = 0xFFFF;                                     //不支持的命令或者出錯(cuò)
  270.                             break;
  271.                         }
  272.                         if ( SetupLen > len )
  273.                         {
  274.                             SetupLen = len;    //限制總長(zhǎng)度
  275.                         }
  276.                         len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen; //本次傳輸長(zhǎng)度
  277.                         memcpy(Ep0Buffer,pDescr,len);                        //加載上傳數(shù)據(jù)
  278.                         SetupLen -= len;
  279.                         pDescr += len;
  280.                         break;
  281.                     case USB_SET_ADDRESS:
  282.                         SetupLen = UsbSetupBuf->wValueL;                     //暫存USB設(shè)備地址
  283.                         break;
  284.                     case USB_GET_CONFIGURATION:
  285.                         Ep0Buffer[0] = UsbConfig;
  286.                         if ( SetupLen >= 1 )
  287.                         {
  288.                             len = 1;
  289.                         }
  290.                         break;
  291.                     case USB_SET_CONFIGURATION:
  292.                         UsbConfig = UsbSetupBuf->wValueL;
  293.                         if(UsbConfig)
  294.                         {
  295. #ifdef DE_PRINTF
  296.                             printf("SET CONFIG.\n");
  297. #endif
  298.                             Ready = 1;                                                   //set config命令一般代表usb枚舉完成的標(biāo)志
  299.                         }
  300.                         break;
  301.                     case 0x0A:
  302.                         break;
  303.                     case USB_CLEAR_FEATURE:                                              //Clear Feature
  304.                         if ( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP )// 端點(diǎn)
  305.                         {
  306.                             switch( UsbSetupBuf->wIndexL )
  307.                             {
  308.                             case 0x82:
  309.                                 UEP2_CTRL = UEP2_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
  310.                                 break;
  311.                             case 0x81:
  312.                                 UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
  313.                                 break;
  314.                             case 0x01:
  315.                                 UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_R_TOG | MASK_UEP_R_RES ) | UEP_R_RES_ACK;
  316.                                 break;
  317.                             default:
  318.                                 len = 0xFFFF;                                            // 不支持的端點(diǎn)
  319.                                 break;
  320.                             }
  321.                         }
  322.                         if ( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE )// 設(shè)備
  323.                         {
  324.                             WakeUpEnFlag = 0;
  325.                             printf("Wake up\n");
  326.                             break;
  327.                         }
  328.                         else
  329.                         {
  330.                             len = 0xFFFF;                                                // 不是端點(diǎn)不支持
  331.                         }
  332.                         break;
  333.                     case USB_SET_FEATURE:                                               /* Set Feature */
  334.                         if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x00 )              /* 設(shè)置設(shè)備 */
  335.                         {
  336.                             if( ( ( ( UINT16 )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x01 )
  337.                             {
  338.                                 if( CfgDesc[ 7 ] & 0x20 )
  339.                                 {
  340.                                     WakeUpEnFlag = 1;                                   /* 設(shè)置喚醒使能標(biāo)志 */
  341.                                     printf("Enable Remote Wakeup.\n");
  342.                                 }
  343.                                 else
  344.                                 {
  345.                                     len = 0xFFFF;                                        /* 操作失敗 */
  346.                                 }
  347.                             }
  348.                             else
  349.                             {
  350.                                 len = 0xFFFF;                                            /* 操作失敗 */
  351.                             }
  352.                         }
  353.                         else if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x02 )        /* 設(shè)置端點(diǎn) */
  354.                         {
  355.                             if( ( ( ( UINT16 )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x00 )
  356.                             {
  357.                                 switch( ( ( UINT16 )UsbSetupBuf->wIndexH << 8 ) | UsbSetupBuf->wIndexL )
  358.                                 {
  359.                                 case 0x82:
  360.                                     UEP2_CTRL = UEP2_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* 設(shè)置端點(diǎn)2 IN STALL */
  361.                                     break;
  362.                                 case 0x02:
  363.                                     UEP2_CTRL = UEP2_CTRL & (~bUEP_R_TOG) | UEP_R_RES_STALL;/* 設(shè)置端點(diǎn)2 OUT Stall */
  364.                                     break;
  365.                                 case 0x81:
  366.                                     UEP1_CTRL = UEP1_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* 設(shè)置端點(diǎn)1 IN STALL */
  367.                                     break;
  368.                                 default:
  369.                                     len = 0xFFFF;                               //操作失敗
  370.                                     break;
  371.                                 }
  372.                             }
  373.                             else
  374.                             {
  375.                                 len = 0xFFFF;                                   //操作失敗
  376.                             }
  377.                         }
  378.                         else
  379.                         {
  380.                             len = 0xFFFF;                                      //操作失敗
  381.                         }
  382.                         break;
  383.                     case USB_GET_STATUS:
  384.                         Ep0Buffer[0] = 0x00;
  385.                         Ep0Buffer[1] = 0x00;
  386.                         if ( SetupLen >= 2 )
  387.                         {
  388.                             len = 2;
  389.                         }
  390.                         else
  391.                         {
  392.                             len = SetupLen;
  393.                         }
  394.                         break;
  395.                     default:
  396.                         len = 0xFFFF;                                           //操作失敗
  397.                         break;
  398.                     }
  399.                 }
  400.             }
  401.             else
  402.             {
  403.                 len = 0xFFFF;                                                   //包長(zhǎng)度錯(cuò)誤
  404.             }
  405.             if(len == 0xFFFF)
  406.             {
  407.                 SetupReq = 0xFF;
  408.                 UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL;//STALL
  409.             }
  410.             else if(len)                                                //上傳數(shù)據(jù)或者狀態(tài)階段返回0長(zhǎng)度包
  411.             {
  412.                 UEP0_T_LEN = len;
  413.                 UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//默認(rèn)數(shù)據(jù)包是DATA1,返回應(yīng)答ACK
  414.             }
  415.             else
  416.             {
  417.                 UEP0_T_LEN = 0;  //雖然尚未到狀態(tài)階段,但是提前預(yù)置上傳0長(zhǎng)度數(shù)據(jù)包以防主機(jī)提前進(jìn)入狀態(tài)階段
  418.                 UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//默認(rèn)數(shù)據(jù)包是DATA1,返回應(yīng)答ACK
  419.             }
  420.             break;
  421.         case UIS_TOKEN_IN | 0:                                               //endpoint0 IN
  422.             switch(SetupReq)
  423.             {
  424.             case USB_GET_DESCRIPTOR:
  425.                 len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen;    //本次傳輸長(zhǎng)度
  426.                 memcpy( Ep0Buffer, pDescr, len );                            //加載上傳數(shù)據(jù)
  427.                 SetupLen -= len;
  428.                 pDescr += len;
  429.                 UEP0_T_LEN = len;
  430.                 UEP0_CTRL ^= bUEP_T_TOG;                                     //同步標(biāo)志位翻轉(zhuǎn)
  431.                 break;
  432.             case USB_SET_ADDRESS:
  433.                 USB_DEV_AD = USB_DEV_AD & bUDA_GP_BIT | SetupLen;
  434.                 UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
  435.                 break;
  436.             default:
  437.                 UEP0_T_LEN = 0;                                              //狀態(tài)階段完成中斷或者是強(qiáng)制上傳0長(zhǎng)度數(shù)據(jù)包結(jié)束控制傳輸
  438.                 UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
  439.                 break;
  440.             }
  441.             break;
  442.         case UIS_TOKEN_OUT | 0:  // endpoint0 OUT
  443.             len = USB_RX_LEN;
  444.             if(SetupReq == 0x09)
  445.             {
  446.                 if(Ep0Buffer[0])
  447.                 {
  448.                     printf("Light on Num Lock LED!\n");
  449.                 }
  450.                 else if(Ep0Buffer[0] == 0)
  451.                 {
  452.                     printf("Light off Num Lock LED!\n");
  453.                 }
  454.             }
  455.             UEP0_CTRL ^= bUEP_R_TOG;                                      //同步標(biāo)志位翻轉(zhuǎn)
  456.             break;
  457.         default:
  458.             break;
  459.         }
  460.         UIF_TRANSFER = 0;                                                 //寫0清空中斷
  461.     }
  462.     else if(UIF_BUS_RST)                                                  //設(shè)備模式USB總線復(fù)位中斷
  463.     {
  464.         UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
  465.         UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK;
  466.         UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK;
  467.         USB_DEV_AD = 0x00;
  468.         UIF_SUSPEND = 0;
  469.         UIF_TRANSFER = 0;
  470.         Ready = 0;
  471.         UIF_BUS_RST = 0;                                                 //清中斷標(biāo)志
  472.     }
  473.     else if (UIF_SUSPEND)                                                           //USB總線掛起/喚醒完成
  474.     {
  475.         UIF_SUSPEND = 0;
  476.         if ( USB_MIS_ST & bUMS_SUSPEND )                                            //掛起
  477.         {
  478. #ifdef DE_PRINTF
  479.             printf( "z" );                                                          //睡眠狀態(tài)
  480. #endif
  481. //             while ( XBUS_AUX & bUART0_TX )
  482. //             {
  483. //                 ;    //等待發(fā)送完成
  484. //             }
  485. //             SAFE_MOD = 0x55;
  486. //             SAFE_MOD = 0xAA;
  487. //             WAKE_CTRL = bWAK_BY_USB | bWAK_RXD0_LO;                              //USB或者RXD0有信號(hào)時(shí)可被喚醒
  488. //             PCON |= PD;                                                          //睡眠
  489. //             SAFE_MOD = 0x55;
  490. //             SAFE_MOD = 0xAA;
  491. //             WAKE_CTRL = 0x00;
  492.         }
  493.         else                                                                        // 喚醒
  494.         {
  495. #ifdef DE_PRINTF
  496.             printf( "w" );
  497. #endif
  498.         }
  499.     }
  500.     else {                                                                          //意外的中斷,不可能發(fā)生的情況
  501.         USB_INT_FG = 0xFF;                                                          //清中斷標(biāo)志
  502. #ifdef DE_PRINTF
  503.         printf("UnknownInt  \n");
  504. #endif
  505.     }
  506. }
  507. void HIDValueHandle()
  508. {
  509.     UINT8 i;
  510.     i = getkey( );
  511.     printf( "%c", (UINT8)i );
  512.     if( WakeUpEnFlag )                                                   //主機(jī)已休眠
  513.     {
  514.         CH554USBDevWakeup();                                             //喚醒主機(jī)
  515.     }
  516.     else
  517.     {
  518.         switch(i)
  519.         {
  520. //鼠標(biāo)數(shù)據(jù)上傳示例
  521.         case 'L':                                                        //左鍵
  522.             HIDMouse[0] = 0x01;
  523.             while( Endp2Busy )
  524.             {
  525.                 ;    //如果忙(上一包數(shù)據(jù)沒有傳上去),則等待。
  526.             }
  527.             Endp2Busy = 1;                                               //設(shè)置為忙狀態(tài)
  528.             Enp2IntIn(HIDMouse,sizeof(HIDMouse));
  529.             HIDMouse[0] = 0;                                             //抬起
  530.             while( Endp2Busy )
  531.             {
  532.                 ;    //如果忙(上一包數(shù)據(jù)沒有傳上去),則等待。
  533.             }
  534.             Endp2Busy = 1;                                               //設(shè)置為忙狀態(tài)
  535.             Enp2IntIn(HIDMouse,sizeof(HIDMouse));
  536.             break;
  537.         case 'R':                                                        //右鍵
  538.             HIDMouse[0] = 0x02;
  539.             while( Endp2Busy )
  540.             {
  541.                 ;    //如果忙(上一包數(shù)據(jù)沒有傳上去),則等待。
  542.             }
  543.             Endp2Busy = 1;                                               //設(shè)置為忙狀態(tài)
  544.             Enp2IntIn(HIDMouse,sizeof(HIDMouse));
  545.             HIDMouse[0] = 0;                                             //抬起
  546.             while( Endp2Busy )
  547.             {
  548.                 ;    //如果忙(上一包數(shù)據(jù)沒有傳上去),則等待。
  549.             }
  550.             Endp2Busy = 1;                                               //設(shè)置為忙狀態(tài)
  551.             Enp2IntIn(HIDMouse,sizeof(HIDMouse));
  552.             break;
  553. //鍵盤數(shù)據(jù)上傳示例
  554.         case 'A':                                                         //A鍵
  555.             HIDKey[2] = 0x04;                                             //按鍵開始
  556.             while( Endp1Busy )
  557.             {
  558.                 ;    //如果忙(上一包數(shù)據(jù)沒有傳上去),則等待。
  559.             }
  560.             Endp1Busy = 1;                                               //設(shè)置為忙狀態(tài)
  561.             Enp1IntIn(HIDKey,sizeof(HIDKey));
  562.             HIDKey[2] = 0;                                                //按鍵結(jié)束
  563.             while( Endp1Busy )
  564.             {
  565.                 ;    //如果忙(上一包數(shù)據(jù)沒有傳上去),則等待。
  566.             }
  567.             Endp1Busy = 1;                                               //設(shè)置為忙狀態(tài)
  568.             Enp1IntIn(HIDKey,sizeof(HIDKey));
  569.             break;
  570.         case 'Q':                                                         //CAP鍵
  571.             HIDKey[2] = 0x39;
  572.             while( Endp1Busy )
  573.             {
  574.                 ;    //如果忙(上一包數(shù)據(jù)沒有傳上去),則等待。
  575.             }
  576.             Endp1Busy = 1;                                               //設(shè)置為忙狀態(tài)
  577.             Enp1IntIn(HIDKey,sizeof(HIDKey));
  578.             HIDKey[2] = 0;                                                //按鍵結(jié)束
  579.             while( Endp1Busy )
  580.             {
  581.                 ;    //如果忙(上一包數(shù)據(jù)沒有傳上去),則等待。
  582.             }
  583.             Endp1Busy = 1;                                               //設(shè)置為忙狀態(tài)
  584.             Enp1IntIn(HIDKey,sizeof(HIDKey));
  585.             break;
  586.         default:                                                          //其他
  587.             break;
  588.         }
  589.     }
  590. }
  591. void main()
  592. {
  593.     CfgFsys( );                                                           //CH549時(shí)鐘選擇配置
  594.     mDelaymS(20);                                                         //修改主頻等待內(nèi)部晶振穩(wěn)定,必加
  595.     mInitSTDIO( );                                                        //串口0初始化
  596.     printf("KM Device start ...\n");
  597.     USBDeviceInit();                                                      //USB設(shè)備模式初始化
  598.     EA = 1;                                                               //允許單片機(jī)中斷
  599.     memset(HIDKey,0,sizeof(HIDKey));                                      //清空緩沖區(qū)
  600.     memset(HIDMouse,0,sizeof(HIDMouse));
  601.     while(1)
  602.     {
  603.         if(Ready)
  604.         {
  605.             HIDValueHandle();                                             //串口0,程序會(huì)停在getkey函數(shù)等待接收一個(gè)字符
  606.         }
  607.     }
  608. }


復(fù)制代碼

CompositeKM.docx (24.24 KB, 下載次數(shù): 43)


null1dd06be447654b10.jpg (36.37 KB, 下載次數(shù): 175)

null1dd06be447654b10.jpg

null-2e9e8452d6d2fded.jpg (176.75 KB, 下載次數(shù): 189)

null-2e9e8452d6d2fded.jpg

評(píng)分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 激情视频一区 | 不卡的av在线 | 欧美日韩精品中文字幕 | 午夜免费在线观看 | 精品av | 日韩av免费在线观看 | 三级黄色片在线播放 | av网站在线播放 | 日韩一区二区不卡 | 亚洲一区二区在线视频 | 日韩视频一区二区 | 国产羞羞视频在线观看 | 国产一级片免费视频 | 在线小视频 | 国产欧美一区二区三区在线看蜜臀 | 亚洲福利一区二区 | 国产污视频在线 | a级片在线观看 | 欧美日韩在线国产 | 亚洲一区二区久久久 | 波多野结衣二区 | 亚洲精品久久久一区二区三区 | 爱草视频 | 成人免费激情视频 | 欧美日韩三级 | 999久久久| 久久亚洲春色中文字幕久久久 | 中文字幕高清免费日韩视频在线 | 在线高清免费观看视频 | 国产欧美精品区一区二区三区 | 欧美不卡网站 | 日韩欧美综合在线视频 | 欧美一卡二卡在线 | 久久久精品一区二区三区 | 午夜性色a√在线视频观看9 | 欧美午夜影院 | 亚洲视频免费在线看 | 亚洲欧美激情精品一区二区 | 久久久久久国产 | 国产精品一区一区三区 | 一区二区精品 |