制作出來的實物圖如下:
單片機源程序如下:
- /********************************** (C) COPYRIGHT *******************************
- * File Name : CompositeKM.C
- * Author : WCH
- * Version : V1.0
- * Description : CH549模擬USB鍵鼠復合設備,支持類命令,支持喚醒
- 演示鍵盤鼠標簡單操作。其他鍵值,參考 HID USAGE TABLE協議文檔
- 串口0接收字符:
- ‘L’:鼠標左鍵
- ‘R’: 鼠標右鍵
- ‘A’: 鍵盤‘A’鍵
- ‘Q’: 鍵盤‘Caps’鍵
- 任意字符:主機睡眠狀態下,設備遠程喚醒主機(注意設備一般需自供電,因為主機休眠可能USB口也會掉電)
- *******************************************************************************/
- #include ".\Public\CH549.H"
- #include ".\Public\DEBUG.H"
- //#define Fullspeed
- #ifdef Fullspeed
- #define THIS_ENDP0_SIZE 64
- #else
- #define THIS_ENDP0_SIZE 8 //低速USB,中斷傳輸、控制傳輸最大包長度為8
- #endif
- #define EP1_IN_SIZE 8 //鍵盤端點數據包大小
- #define EP2_IN_SIZE 4 //鼠標端點數據包大小
- UINT8X Ep0Buffer[ THIS_ENDP0_SIZE+2 ] _at_ 0x0000; //端點0 OUT&IN緩沖區,必須是偶地址
- UINT8X Ep1Buffer[ EP1_IN_SIZE+2 ] _at_ THIS_ENDP0_SIZE+2; //端點1 IN緩沖區,必須是偶地址
- UINT8X Ep2Buffer[ EP2_IN_SIZE+2 ] _at_ THIS_ENDP0_SIZE+EP1_IN_SIZE+4; //端點2 IN緩沖區,必須是偶地址
- UINT8 SetupReq,Ready,UsbConfig;
- UINT16 SetupLen;
- PUINT8 pDescr; //USB配置標志
- USB_SETUP_REQ SetupReqBuf; //暫存Setup包
- #define UsbSetupBuf ((PUSB_SETUP_REQ)Ep0Buffer)
- #pragma NOAREGS
- /*設備描述符*/
- UINT8C DevDesc[] = { 0x12,0x01,0x10,0x01,0x00,0x00,0x00,THIS_ENDP0_SIZE,
- 0x86,0x1a,0xe1,0xe6,0x00,0x01,0x01,0x02,
- 0x00,0x01
- };
- /*字符串描述符*/
- UINT8C MyLangDescr[] = { 0x04, 0x03, 0x09, 0x04 }; // 語言描述符
- UINT8C MyManuInfo[] = { 0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0 }; // 廠家信息
- UINT8C MyProdInfo[] = { 0x0C, 0x03, 'C', 0, 'H', 0, '5', 0, '4', 0, '9', 0 }; // 產品信息
- /*HID類報表描述符*/
- UINT8C KeyRepDesc[] =
- {
- 0x05,0x01,0x09,0x06,0xA1,0x01,0x05,0x07,
- 0x19,0xe0,0x29,0xe7,0x15,0x00,0x25,0x01,
- 0x75,0x01,0x95,0x08,0x81,0x02,0x95,0x01,
- 0x75,0x08,0x81,0x01,0x95,0x03,0x75,0x01,
- 0x05,0x08,0x19,0x01,0x29,0x03,0x91,0x02,
- 0x95,0x05,0x75,0x01,0x91,0x01,0x95,0x06,
- 0x75,0x08,0x26,0xff,0x00,0x05,0x07,0x19,
- 0x00,0x29,0x91,0x81,0x00,0xC0
- };
- UINT8C MouseRepDesc[] =
- {
- 0x05,0x01,0x09,0x02,0xA1,0x01,0x09,0x01,
- 0xA1,0x00,0x05,0x09,0x19,0x01,0x29,0x03,
- 0x15,0x00,0x25,0x01,0x75,0x01,0x95,0x03,
- 0x81,0x02,0x75,0x05,0x95,0x01,0x81,0x01,
- 0x05,0x01,0x09,0x30,0x09,0x31,0x09,0x38,
- 0x15,0x81,0x25,0x7f,0x75,0x08,0x95,0x03,
- 0x81,0x06,0xC0,0xC0
- };
- /*配置描述符*/
- UINT8C CfgDesc[] =
- {
- 0x09,0x02,0x3b,0x00,0x02,0x01,0x00,0xA0,0x32, //配置描述符
- 0x09,0x04,0x00,0x00,0x01,0x03,0x01,0x01,0x00, //接口描述符,鍵盤
- 0x09,0x21,0x11,0x01,0x00,0x01,0x22,sizeof(KeyRepDesc)&0xFF,sizeof(KeyRepDesc)>>8,//HID類描述符
- 0x07,0x05,0x81,0x03,EP1_IN_SIZE,0x00,0x0a, //端點描述符
- 0x09,0x04,0x01,0x00,0x01,0x03,0x01,0x02,0x00, //接口描述符,鼠標
- 0x09,0x21,0x10,0x01,0x00,0x01,0x22,sizeof(MouseRepDesc)&0xFF,sizeof(MouseRepDesc)>>8,//HID類描述符
- 0x07,0x05,0x82,0x03,EP2_IN_SIZE,0x00,0x0a //端點描述符
- };
- /*鍵盤數據*/
- UINT8 HIDKey[EP1_IN_SIZE];
- /*鼠標數據*/
- UINT8 HIDMouse[EP2_IN_SIZE];
- UINT8 Endp1Busy = 0; //傳輸完成控制標志位
- UINT8 Endp2Busy = 0;
- UINT8 WakeUpEnFlag = 0; //遠程喚醒使能標志
- /*******************************************************************************
- * Function Name : CH554USBDevWakeup()
- * Description : CH554設備模式喚醒主機,發送K信號
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void CH554USBDevWakeup( )
- {
- #ifdef Fullspeed
- UDEV_CTRL |= bUD_LOW_SPEED;
- mDelaymS(2);
- UDEV_CTRL &= ~bUD_LOW_SPEED;
- #else
- UDEV_CTRL &= ~bUD_LOW_SPEED;
- mDelaymS(2);
- UDEV_CTRL |= bUD_LOW_SPEED;
- #endif
- }
- /*******************************************************************************
- * Function Name : USBDeviceInit()
- * Description : USB設備模式配置,設備模式啟動,收發端點配置,中斷開啟
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void USBDeviceInit()
- {
- IE_USB = 0;
- USB_CTRL = 0x00; // 先設定USB設備模式
- UDEV_CTRL = bUD_PD_DIS; // 禁止DP/DM下拉電阻
- #ifndef Fullspeed
- UDEV_CTRL |= bUD_LOW_SPEED; //選擇低速1.5M模式
- USB_CTRL |= bUC_LOW_SPEED;
- #else
- UDEV_CTRL &= ~bUD_LOW_SPEED; //選擇全速12M模式,默認方式
- USB_CTRL &= ~bUC_LOW_SPEED;
- #endif
- UEP1_T_LEN = 0; //預使用發送長度一定要清空
- UEP2_T_LEN = 0; //預使用發送長度一定要清空
- UEP2_DMA = Ep2Buffer; //端點2數據傳輸地址
- UEP2_3_MOD = UEP2_3_MOD & ~bUEP2_BUF_MOD | bUEP2_TX_EN; //端點2發送使能 64字節緩沖區
- UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; //端點2自動翻轉同步標志位,IN事務返回NAK
- UEP0_DMA = Ep0Buffer; //端點0數據傳輸地址
- UEP4_1_MOD &= ~(bUEP4_RX_EN | bUEP4_TX_EN); //端點0單64字節收發緩沖區
- UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; //OUT事務返回ACK,IN事務返回NAK
- UEP1_DMA = Ep1Buffer; //端點1數據傳輸地址
- UEP4_1_MOD = UEP4_1_MOD & ~bUEP1_BUF_MOD | bUEP1_TX_EN; //端點1發送使能 64字節緩沖區
- UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; //端點1自動翻轉同步標志位,IN事務返回NAK
- USB_DEV_AD = 0x00;
- USB_CTRL |= bUC_DEV_PU_EN | bUC_INT_BUSY | bUC_DMA_EN; // 啟動USB設備及DMA,在中斷期間中斷標志未清除前自動返回NAK
- UDEV_CTRL |= bUD_PORT_EN; // 允許USB端口
- USB_INT_FG = 0xFF; // 清中斷標志
- USB_INT_EN = bUIE_SUSPEND | bUIE_TRANSFER | bUIE_BUS_RST;
- IE_USB = 1;
- }
- /*******************************************************************************
- * Function Name : Enp1IntIn
- * Description : USB設備模式端點1的中斷上傳
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void Enp1IntIn( UINT8 *buf,UINT8 len )
- {
- memcpy( Ep1Buffer, buf, len ); //加載上傳數據
- UEP1_T_LEN = len; //上傳數據長度
- UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; //有數據時上傳數據并應答ACK
- }
- /*******************************************************************************
- * Function Name : Enp2IntIn()
- * Description : USB設備模式端點2的中斷上傳
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void Enp2IntIn( UINT8 *buf,UINT8 len )
- {
- memcpy( Ep2Buffer, buf, len); //加載上傳數據
- UEP2_T_LEN = len; //上傳數據長度
- UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; //有數據時上傳數據并應答ACK
- }
- /*******************************************************************************
- * Function Name : DeviceInterrupt()
- * Description : CH559USB中斷處理函數
- *******************************************************************************/
- void DeviceInterrupt( void ) interrupt INT_NO_USB using 1 //USB中斷服務程序,使用寄存器組1
- {
- UINT16 len = 0;
- if(UIF_TRANSFER) //USB傳輸完成標志
- {
- switch (USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP))
- {
- case UIS_TOKEN_IN | 2: //endpoint 2# 中斷端點上傳
- UEP2_T_LEN = 0; //預使用發送長度一定要清空
- // UEP1_CTRL ^= bUEP_T_TOG; //如果不設置自動翻轉則需要手動翻轉
- Endp2Busy = 0;
- UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; //默認應答NAK
- break;
- case UIS_TOKEN_IN | 1: //endpoint 1# 中斷端點上傳
- UEP1_T_LEN = 0; //預使用發送長度一定要清空
- // UEP2_CTRL ^= bUEP_T_TOG; //如果不設置自動翻轉則需要手動翻轉
- Endp1Busy = 0;
- UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; //默認應答NAK
- break;
- case UIS_TOKEN_SETUP | 0: //SETUP事務
- UEP0_CTRL = UEP0_CTRL & (~MASK_UEP_T_RES )| UEP_T_RES_NAK; //預置NAK,防止stall之后不及時清除響應方式
- len = USB_RX_LEN;
- if(len == (sizeof(USB_SETUP_REQ)))
- {
- SetupLen = ((UINT16)UsbSetupBuf->wLengthH<<8) + UsbSetupBuf->wLengthL;
- len = 0; // 默認為成功并且上傳0長度
- SetupReq = UsbSetupBuf->bRequest;
- if ( ( UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )/* HID類命令 */
- {
- switch( SetupReq )
- {
- case 0x01://GetReport
- break;
- case 0x02://GetIdle
- break;
- case 0x03://GetProtocol
- break;
- case 0x09://SetReport
- break;
- case 0x0A://SetIdle
- break;
- case 0x0B://SetProtocol
- break;
- default:
- len = 0xFFFF; /*命令不支持*/
- break;
- }
- }
- else
- {
- //標準請求
- switch(SetupReq) //請求碼
- {
- case USB_GET_DESCRIPTOR:
- switch(UsbSetupBuf->wValueH)
- {
- case 1: //設備描述符
- pDescr = DevDesc; //把設備描述符送到要發送的緩沖區
- len = sizeof(DevDesc);
- break;
- case 2: //配置描述符
- pDescr = CfgDesc; //把設備描述符送到要發送的緩沖區
- len = sizeof(CfgDesc);
- break;
- case 3:
- switch( UsbSetupBuf->wValueL )
- {
- case 1:
- pDescr = (PUINT8)( &MyManuInfo[0] );
- len = sizeof( MyManuInfo );
- break;
- case 2:
- pDescr = (PUINT8)( &MyProdInfo[0] );
- len = sizeof( MyProdInfo );
- break;
- case 0:
- pDescr = (PUINT8)( &MyLangDescr[0] );
- len = sizeof( MyLangDescr );
- break;
- default:
- len = 0xFFFF; // 不支持的字符串描述符
- break;
- }
- break;
- case 0x22: //報表描述符
- if(UsbSetupBuf->wIndexL == 0) //接口0報表描述符
- {
- pDescr = KeyRepDesc; //數據準備上傳
- len = sizeof(KeyRepDesc);
- }
- else if(UsbSetupBuf->wIndexL == 1) //接口1報表描述符
- {
- pDescr = MouseRepDesc; //數據準備上傳
- len = sizeof(MouseRepDesc);
- }
- else
- {
- len = 0xFFFF; //本程序只有2個接口,這句話正常不可能執行
- }
- break;
- default:
- len = 0xFFFF; //不支持的命令或者出錯
- break;
- }
- if ( SetupLen > len )
- {
- SetupLen = len; //限制總長度
- }
- len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen; //本次傳輸長度
- memcpy(Ep0Buffer,pDescr,len); //加載上傳數據
- SetupLen -= len;
- pDescr += len;
- break;
- case USB_SET_ADDRESS:
- SetupLen = UsbSetupBuf->wValueL; //暫存USB設備地址
- break;
- case USB_GET_CONFIGURATION:
- Ep0Buffer[0] = UsbConfig;
- if ( SetupLen >= 1 )
- {
- len = 1;
- }
- break;
- case USB_SET_CONFIGURATION:
- UsbConfig = UsbSetupBuf->wValueL;
- if(UsbConfig)
- {
- #ifdef DE_PRINTF
- printf("SET CONFIG.\n");
- #endif
- Ready = 1; //set config命令一般代表usb枚舉完成的標志
- }
- break;
- case 0x0A:
- break;
- case USB_CLEAR_FEATURE: //Clear Feature
- if ( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP )// 端點
- {
- switch( UsbSetupBuf->wIndexL )
- {
- case 0x82:
- UEP2_CTRL = UEP2_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
- break;
- case 0x81:
- UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK;
- break;
- case 0x01:
- UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_R_TOG | MASK_UEP_R_RES ) | UEP_R_RES_ACK;
- break;
- default:
- len = 0xFFFF; // 不支持的端點
- break;
- }
- }
- if ( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE )// 設備
- {
- WakeUpEnFlag = 0;
- printf("Wake up\n");
- break;
- }
- else
- {
- len = 0xFFFF; // 不是端點不支持
- }
- break;
- case USB_SET_FEATURE: /* Set Feature */
- if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x00 ) /* 設置設備 */
- {
- if( ( ( ( UINT16 )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x01 )
- {
- if( CfgDesc[ 7 ] & 0x20 )
- {
- WakeUpEnFlag = 1; /* 設置喚醒使能標志 */
- printf("Enable Remote Wakeup.\n");
- }
- else
- {
- len = 0xFFFF; /* 操作失敗 */
- }
- }
- else
- {
- len = 0xFFFF; /* 操作失敗 */
- }
- }
- else if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x02 ) /* 設置端點 */
- {
- if( ( ( ( UINT16 )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x00 )
- {
- switch( ( ( UINT16 )UsbSetupBuf->wIndexH << 8 ) | UsbSetupBuf->wIndexL )
- {
- case 0x82:
- UEP2_CTRL = UEP2_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* 設置端點2 IN STALL */
- break;
- case 0x02:
- UEP2_CTRL = UEP2_CTRL & (~bUEP_R_TOG) | UEP_R_RES_STALL;/* 設置端點2 OUT Stall */
- break;
- case 0x81:
- UEP1_CTRL = UEP1_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* 設置端點1 IN STALL */
- break;
- default:
- len = 0xFFFF; //操作失敗
- break;
- }
- }
- else
- {
- len = 0xFFFF; //操作失敗
- }
- }
- else
- {
- len = 0xFFFF; //操作失敗
- }
- break;
- case USB_GET_STATUS:
- Ep0Buffer[0] = 0x00;
- Ep0Buffer[1] = 0x00;
- if ( SetupLen >= 2 )
- {
- len = 2;
- }
- else
- {
- len = SetupLen;
- }
- break;
- default:
- len = 0xFFFF; //操作失敗
- break;
- }
- }
- }
- else
- {
- len = 0xFFFF; //包長度錯誤
- }
- if(len == 0xFFFF)
- {
- SetupReq = 0xFF;
- UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL;//STALL
- }
- else if(len) //上傳數據或者狀態階段返回0長度包
- {
- UEP0_T_LEN = len;
- UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//默認數據包是DATA1,返回應答ACK
- }
- else
- {
- UEP0_T_LEN = 0; //雖然尚未到狀態階段,但是提前預置上傳0長度數據包以防主機提前進入狀態階段
- UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//默認數據包是DATA1,返回應答ACK
- }
- break;
- case UIS_TOKEN_IN | 0: //endpoint0 IN
- switch(SetupReq)
- {
- case USB_GET_DESCRIPTOR:
- len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen; //本次傳輸長度
- memcpy( Ep0Buffer, pDescr, len ); //加載上傳數據
- SetupLen -= len;
- pDescr += len;
- UEP0_T_LEN = len;
- UEP0_CTRL ^= bUEP_T_TOG; //同步標志位翻轉
- break;
- case USB_SET_ADDRESS:
- USB_DEV_AD = USB_DEV_AD & bUDA_GP_BIT | SetupLen;
- UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
- break;
- default:
- UEP0_T_LEN = 0; //狀態階段完成中斷或者是強制上傳0長度數據包結束控制傳輸
- UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
- break;
- }
- break;
- case UIS_TOKEN_OUT | 0: // endpoint0 OUT
- len = USB_RX_LEN;
- if(SetupReq == 0x09)
- {
- if(Ep0Buffer[0])
- {
- printf("Light on Num Lock LED!\n");
- }
- else if(Ep0Buffer[0] == 0)
- {
- printf("Light off Num Lock LED!\n");
- }
- }
- UEP0_CTRL ^= bUEP_R_TOG; //同步標志位翻轉
- break;
- default:
- break;
- }
- UIF_TRANSFER = 0; //寫0清空中斷
- }
- else if(UIF_BUS_RST) //設備模式USB總線復位中斷
- {
- UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
- UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK;
- UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK;
- USB_DEV_AD = 0x00;
- UIF_SUSPEND = 0;
- UIF_TRANSFER = 0;
- Ready = 0;
- UIF_BUS_RST = 0; //清中斷標志
- }
- else if (UIF_SUSPEND) //USB總線掛起/喚醒完成
- {
- UIF_SUSPEND = 0;
- if ( USB_MIS_ST & bUMS_SUSPEND ) //掛起
- {
- #ifdef DE_PRINTF
- printf( "z" ); //睡眠狀態
- #endif
- // while ( XBUS_AUX & bUART0_TX )
- // {
- // ; //等待發送完成
- // }
- // SAFE_MOD = 0x55;
- // SAFE_MOD = 0xAA;
- // WAKE_CTRL = bWAK_BY_USB | bWAK_RXD0_LO; //USB或者RXD0有信號時可被喚醒
- // PCON |= PD; //睡眠
- // SAFE_MOD = 0x55;
- // SAFE_MOD = 0xAA;
- // WAKE_CTRL = 0x00;
- }
- else // 喚醒
- {
- #ifdef DE_PRINTF
- printf( "w" );
- #endif
- }
- }
- else { //意外的中斷,不可能發生的情況
- USB_INT_FG = 0xFF; //清中斷標志
- #ifdef DE_PRINTF
- printf("UnknownInt \n");
- #endif
- }
- }
- void HIDValueHandle()
- {
- UINT8 i;
- i = getkey( );
- printf( "%c", (UINT8)i );
- if( WakeUpEnFlag ) //主機已休眠
- {
- CH554USBDevWakeup(); //喚醒主機
- }
- else
- {
- switch(i)
- {
- //鼠標數據上傳示例
- case 'L': //左鍵
- HIDMouse[0] = 0x01;
- while( Endp2Busy )
- {
- ; //如果忙(上一包數據沒有傳上去),則等待。
- }
- Endp2Busy = 1; //設置為忙狀態
- Enp2IntIn(HIDMouse,sizeof(HIDMouse));
- HIDMouse[0] = 0; //抬起
- while( Endp2Busy )
- {
- ; //如果忙(上一包數據沒有傳上去),則等待。
- }
- Endp2Busy = 1; //設置為忙狀態
- Enp2IntIn(HIDMouse,sizeof(HIDMouse));
- break;
- case 'R': //右鍵
- HIDMouse[0] = 0x02;
- while( Endp2Busy )
- {
- ; //如果忙(上一包數據沒有傳上去),則等待。
- }
- Endp2Busy = 1; //設置為忙狀態
- Enp2IntIn(HIDMouse,sizeof(HIDMouse));
- HIDMouse[0] = 0; //抬起
- while( Endp2Busy )
- {
- ; //如果忙(上一包數據沒有傳上去),則等待。
- }
- Endp2Busy = 1; //設置為忙狀態
- Enp2IntIn(HIDMouse,sizeof(HIDMouse));
- break;
- //鍵盤數據上傳示例
- case 'A': //A鍵
- HIDKey[2] = 0x04; //按鍵開始
- while( Endp1Busy )
- {
- ; //如果忙(上一包數據沒有傳上去),則等待。
- }
- Endp1Busy = 1; //設置為忙狀態
- Enp1IntIn(HIDKey,sizeof(HIDKey));
- HIDKey[2] = 0; //按鍵結束
- while( Endp1Busy )
- {
- ; //如果忙(上一包數據沒有傳上去),則等待。
- }
- Endp1Busy = 1; //設置為忙狀態
- Enp1IntIn(HIDKey,sizeof(HIDKey));
- break;
- case 'Q': //CAP鍵
- HIDKey[2] = 0x39;
- while( Endp1Busy )
- {
- ; //如果忙(上一包數據沒有傳上去),則等待。
- }
- Endp1Busy = 1; //設置為忙狀態
- Enp1IntIn(HIDKey,sizeof(HIDKey));
- HIDKey[2] = 0; //按鍵結束
- while( Endp1Busy )
- {
- ; //如果忙(上一包數據沒有傳上去),則等待。
- }
- Endp1Busy = 1; //設置為忙狀態
- Enp1IntIn(HIDKey,sizeof(HIDKey));
- break;
- default: //其他
- break;
- }
- }
- }
- void main()
- {
- CfgFsys( ); //CH549時鐘選擇配置
- mDelaymS(20); //修改主頻等待內部晶振穩定,必加
- mInitSTDIO( ); //串口0初始化
- printf("KM Device start ...\n");
- USBDeviceInit(); //USB設備模式初始化
- EA = 1; //允許單片機中斷
- memset(HIDKey,0,sizeof(HIDKey)); //清空緩沖區
- memset(HIDMouse,0,sizeof(HIDMouse));
- while(1)
- {
- if(Ready)
- {
- HIDValueHandle(); //串口0,程序會停在getkey函數等待接收一個字符
- }
- }
- }
復制代碼
CompositeKM.docx
(24.24 KB, 下載次數: 43)
2018-11-14 19:55 上傳
點擊文件名下載附件
鍵盤程序
|