求USB鍵盤相關(guān)源碼

大師,

?

???? 目前有個(gè)項(xiàng)目STC12的單片機(jī),11.0592晶振,CH376S模塊(網(wǎng)購),USB鍵盤。想通過串口獲取USB鍵盤或USB激光掃描槍的數(shù)據(jù)。使用了論壇的程序,但不成功。

?

論壇里是總線方式,我改了三個(gè)用串口讀寫的函數(shù)。

?

我用串口1USB通信,用串口2 顯示數(shù)據(jù)

?

? CH376_WR_CMD_PORT( 0x06 );

?

? CH376_WR_DAT_PORT( 0x55 );

?

? s = CH376_RD_DAT_PORT( );

?

?? SerialPortTwo_Send(s);

?

可以正常串口2輸出0AAH

但后續(xù)點(diǎn)擊鍵盤沒有反應(yīng)。

?

是否仍有其他代碼需要修改,才能正常獲取鍵盤數(shù)據(jù)。

?

代碼如下:

?

?

/****************************************

**? Copyright? (C)? WCH? 1999-2009??? **

**? Web:? http://www.winchiphead.com? **

****************************************

**? USB 1.1 Host Examples for CH376?? **

**? KC7.0@MCS-51????????????????????? **

** ?Version: v1.0???????????????????? **

**? Author: tech14????????????????? ? **

**? Time? : 2009/11/18??????????????? **

****************************************

*/

/* CH376操作HID設(shè)備,比如鍵盤,鼠標(biāo),兼容HID復(fù)合設(shè)備*/

?

?

#include

#include

#include

?

#include "CH376INC.H"

?

#include "hid.h"

?

// 獲取設(shè)備描述符

const?? unsigned char code SetupGetDevDescr[] = { 0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x12, 0x00 };

// 獲取配置描述符

const?? unsigned char code SetupGetCfgDescr[] = { 0x80, 0x06, 0x00, 0x02, 0x00, 0x00, 0x09, 0x00 };

// 設(shè)置USB地址

const?? unsigned char code SetupSetUsbAddr[] = { 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };

// 設(shè)置USB配置

//const unsigned char code SetupSetUsbConfig[] = { 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

// SET IDLE

const?? unsigned char code SetupSetidle[]={0x21,0x0a,0x00,0x00,0x00,0x00,0x00,0x00};???????

// 獲取HID 報(bào)告描述符

const?? unsigned char code SetupGetHidDes[]={0x81,0x06,0x00,0x22,0x00,0x00,0x81,0x00};???

// SET REPORT

const?? unsigned char code SetupSetReport[]={0x21,0x09,0x00,0x02,0x00,0x00,0x01,0x00};????

?

?

//單片機(jī)總線方式操作CH376

#define CH376_CMD_PORT? *(unsigned char volatile xdata *)0xBDF1

#define CH376_DAT_PORT? *(unsigned char volatile xdata *)0xBCF0

?

#define CH376_INT_WIRE?? INT0?????? //定義CH376中斷引腳,可省略;

?

struct _Device_Atti{

? ? UINT8 Device_connect;????? //設(shè)備連接狀態(tài) 1:連接,0:斷開

? ? UINT8 Device_compat;?????? //0:非復(fù)合設(shè)備,1表示復(fù)合設(shè)備?

? ? UINT8 Cfg_value;?????????? //設(shè)備配置描述符中配置值

? struct _Device{

? ? UINT8 Device_type;? ?????? //設(shè)備類型 1:鍵盤,2:鼠標(biāo)

? ? UINT8 Device_inf;?? ?????? //設(shè)備接口號(hào)默認(rèn)為0? 最多支持兩個(gè)接口設(shè)備

? ? UINT8 Device_endp;???????? //設(shè)備端點(diǎn)地址 最多支持一個(gè)端點(diǎn)

? ? UINT8 Device_size;???????? //設(shè)備端點(diǎn)大小

? ? UINT16 Device_report_len;?? //設(shè)備報(bào)表長度

??? UINT8 tog;????????????? ?? //端點(diǎn)的同步標(biāo)志

? }Device[2];

}Device_Atti = { 0 };

?

UINT8 receive_mode = 0x00,send_mode = 0x00;

UINT8 data_buf[160];

UINT8 status;

bit?? flag_config_2; //第二次獲取配置描述符標(biāo)志

UINT8 report_cou;??? //實(shí)際獲取的報(bào)表長度

?

//**********************************************

//* NAME:??? mDelay2uS( )??????????????????????????????????

//* FUCTION: 延時(shí)2us子函數(shù)????????????????????????????????

//* 輸入?yún)?shù):無

//* 輸出參數(shù):無???????????????????????????????????

//* 說明:??? 根據(jù)單片機(jī)的主頻進(jìn)行調(diào)整?????????????????????????????????

//**********************************************

?

void mDelay2uS( )

{

?UINT8 i;

?for(i=6;i!=0;i--);

?

}

?

//**********************************************

//* NAME:??? mDelay50mS( )?????????????????????????????????

//* FUCTION: 延時(shí)50ms子函數(shù)???????????????????????????????????

//* 輸入?yún)?shù):無

//* 輸出參數(shù):無???????????????????????????????????

//* 說明:??? 根據(jù)單片機(jī)的主頻進(jìn)行調(diào)整?????????????????????????????????

//**********************************************

?

void mDelay50mS( )

{

?UINT8 i,j,h;

?for (h=1;h!=0;h--)

? for(i=250;i!=0;i--)

?? ?for(j=250;j!=0;j--);

}

?

void mDelaymS(unsigned char delay)

{?? unsigned char i,h;

??? do{

??? ?? for ?(h=0;h!=1;h++)

??? ?? {

??? ??? for(i=0;i!=250;i++){;}

??????? for(i=0;i!=250;i++){;}

??????? for(i=0;i!=150;i++){;}

??????? }

??? }while(--delay);

}

?

?

/* ****************************************************

*

* 名稱 :?? SerialPortTwo_Send

* 功能 :?? 利用串口2發(fā)送數(shù)據(jù)

* 入口函數(shù):Text,用于表示需要發(fā)送的數(shù)據(jù)

*

*******************************************************/

void SerialPortTwo_Send(uchar Text) //利用串口2進(jìn)行數(shù)據(jù)發(fā)送

{

??? uchar temp = 0;

?

??? IE2?? = 0x00;

??? S2CON = S2CON & 0xfd;?????? //清除標(biāo)志位

??? S2BUF = Text;

??? do

??? {

??????? temp = S2CON;

??????? temp = temp & 0x02;

??? }

??? while(temp == 0);?????? ? //等待發(fā)送完成

?

??? S2CON = S2CON & 0xfd;?? ? //清除發(fā)送完成標(biāo)志

??? IE2?? = 0x01;

}

?

/* ********************************************************

*

* ? 名稱 :?? SendStr

* ? 功能 : ? 將對(duì)應(yīng)的數(shù)據(jù)通過串口2發(fā)送給上位機(jī)

* 入口函數(shù):? *s發(fā)送內(nèi)容

* 出口函數(shù):

*

************************************************************/

void SendStrTwo(uchar *s)?? //發(fā)送某一數(shù)組數(shù)據(jù)

?{

?

//? SerialPortTwo_Send('#');

?

??? while(*s!= ' ')

??? {

??????? SerialPortTwo_Send(*s);

??????? s++;

??? }

//? SerialPortTwo_Send('*');

?}

?

?

?

//**********************************************

//* NAME:??? CH376_WR_CMD_PORT( UINT8 cmd )????????????????????????????????

//* FUCTION: CH376命令子函數(shù)????????????????????????????????

//* 輸入?yún)?shù):8位命令碼

//* 輸出參數(shù):無???????????????????????????????????

//* 說明:對(duì)于速度較快的單片機(jī),則需要1.5uS延時(shí)???????????????????????????????????

//**********************************************

?

void CH376_WR_CMD_PORT( UINT8 cmd )

{

?// CH376_CMD_PORT = cmd;

//? mDelay2uS( );???????????? //對(duì)于高速單片機(jī)需要2us的延時(shí)

?

?TI = 0;

??? SBUF = SER_SYNC_CODE1;? /* 啟動(dòng)操作的第1個(gè)串口同步碼 */

??? while ( TI == 0 );

??? TI = 0;

??? SBUF = SER_SYNC_CODE2;? /* 啟動(dòng)操作的第2個(gè)串口同步碼 */

??? while ( TI == 0 );

??? TI = 0;

??? SBUF = cmd;? /* 串口輸出 */

??? while ( TI == 0 );

?

?

}

?

?

//**********************************************

//* NAME:??? CH376_WR_DAT_PORT( UINT8 dat )????????????????????????????????

//* FUCTION: CH376數(shù)據(jù)子函數(shù)????????????????????????????????

//* 輸入?yún)?shù):8位數(shù)據(jù)

//* 輸出參數(shù):無???????????????????????????????????

//* 說明:對(duì)于速度較快的單片機(jī),則需要0.6uS延時(shí)???????????????????????????????????

//**********************************************

?

void CH376_WR_DAT_PORT( UINT8 dat )

{

?//CH376_DAT_PORT = dat;

?

?? TI = 0;

??? SBUF = dat;? /* 串口輸出 */

??? while ( TI == 0 );

?

}

?

//**********************************************

//* NAME:??? CH376_RD_DAT_PORT( void )?????????????????????????????????

//* FUCTION: CH376數(shù)據(jù)子函數(shù)????????????????????????????????

//* 輸入?yún)?shù):無

//* 輸出參數(shù):8位數(shù)據(jù)??????????????????????????????????

//* 說明:對(duì)于速度較快的單片機(jī),則需要0.6uS延時(shí)???????????????????????????????????

//**********************************************

?

UINT8 CH376_RD_DAT_PORT( void )

{

?// return(CH376_DAT_PORT);

?

?? UINT32?? i;

??? for ( i = 0; i < 500000; i ++ ) {? /* 計(jì)數(shù)防止超時(shí) */

??????? if ( RI ) {? /* 串口接收到 */

??????????? RI = 0;

??????????? ?// SerialPortTwo_Send(SBUF);

??????????? return( SBUF );? /* 串口輸入 */

??? ??? }

??? }

??? return( 0 );? /* 不應(yīng)該發(fā)生的情況 */

}

?

?

//**********************************************

//* NAME:??? StdioInit( void )?????????????????????????????????

//* FUCTION: 單片機(jī)串口初始化,用于檢測程序????????????????????????????????

//* 輸入?yún)?shù):無

//* 輸出參數(shù):無???????????????????????????????????

//* 說明: 單片機(jī)主頻24M使用定時(shí)器1 波特率9600???????????????????????????????????

//**********************************************

?

void??? StdioInit( )

{

?

?

?

??? //串口1設(shè)置

??? TMOD = 0x20;//設(shè)置波特率

?

??? TH1? = 0xfd;//Baudrate=9600;f4->1200

??? TL1? = 0xfd;

??? PCON = 0x00;

??? SCON = 0x50;//串行通信設(shè)置

//? RI=0;

?

??? //串口2設(shè)置

??? AUXR &= 0xf7;//波特率不倍速

??? S2CON = 0x50;//8位數(shù)據(jù),可變波特率

??? BRT?? = 0xB8;//設(shè)定獨(dú)立波特率發(fā)生器重裝值 0x70 4800? 0xB8? 9600

??? AUXR |= 0xc; //獨(dú)立波特率發(fā)生器時(shí)鐘為Fosc,12T

??? AUXR |= 0x10;//啟動(dòng)獨(dú)立波特率發(fā)生器

?//?? IE2?? = 0X01;//開啟串口2中斷

?

??? TMOD |= 0x01;

??? TH0 = 0x4c;???? //重新賦值

??? TL0 = 0x00;

?

??? TR1? = 1;

?

?

?

?

}

?

//**********************************************

//* NAME:??? Set_USB_Mode( UINT8 mode )????????????????????????????????

//* FUCTION: 設(shè)置CH376的工作模式 0x06 為主機(jī)模式??????????????????????????????????

//* 輸入?yún)?shù):模式代碼

//* 輸出參數(shù):操作狀態(tài) TRUE:成功,FALSE失敗???????????????????????????????????

//* 說明: 設(shè)置CH376的工作模式????????????????????????????????

//**********************************************

?

UINT8 Set_USB_Mode( UINT8 mode ) {?

??? UINT8 i;

??? CH376_WR_CMD_PORT( CMD_SET_USB_MODE );

??? CH376_WR_DAT_PORT( mode );

??? receive_mode=send_mode=0x00;? //主機(jī)端復(fù)位USB數(shù)據(jù)同步標(biāo)志

??? for( i=0; i!=100; i++ ) {??? //等待設(shè)置模式操作完成,不超過30uS

??????? if ( CH376_RD_DAT_PORT()==CMD_RET_SUCCESS ) return( TRUE );? //成功

??? }

?

??? return( FALSE );????????????? //CH376出錯(cuò),例如芯片型號(hào)錯(cuò)或者處于串口方式或者不支持

}

?

?

//*****************************************************

//* NAME:??? set_freq(void)????????????????????????????????

//* FUCTION: 設(shè)置CH376的進(jìn)入低速模式??????????????????????????????????

//* 輸入?yún)?shù):無

//* 輸出參數(shù):無???????????????????????????????????

//* 說明: 對(duì)于鼠標(biāo)鍵盤等低速設(shè)備,要先設(shè)置ch376為低速模式????????????????????????????????

//******************************************************

?

void set_freq(void)

{??

??? CH376_WR_CMD_PORT(0x0b);??? // 切換使375B進(jìn)入低速模式

??? CH376_WR_DAT_PORT(0x17);

??? CH376_WR_DAT_PORT(0xd8);

}

?

?

?

//*****************************************************

//* NAME:???? RD_USB_DATA( UINT8 *buf )????????????????????????????????

//* FUCTION:? CH376的端點(diǎn)緩沖區(qū)讀取接收到的數(shù)據(jù)?????????????????????????????????

//* 輸入?yún)?shù): 數(shù)據(jù)緩沖區(qū)的地址

//* 輸出參數(shù):返回接收的數(shù)據(jù)長度???????????????????????????????????

//* 說明:??? CH376的主機(jī)端點(diǎn)緩沖區(qū)中讀取接收到的數(shù)據(jù)???????????????????????????????????

//******************************************************

?

UINT8 RD_USB_DATA( UINT8 *buf ) {?

??? UINT8 i, len;

??? CH376_WR_CMD_PORT( CMD01_RD_USB_DATA0 ); ?? ?????????// CH37X讀取數(shù)據(jù)塊

??? len=CH376_RD_DAT_PORT();???????????????????????????? // 后續(xù)數(shù)據(jù)長度

??? for ( i=0; i!=len; i++ ) *buf++=CH376_RD_DAT_PORT();

??? return( len );

}

?

?

//*****************************************************

//* NAME:???? WR_USB_DATA( UINT8 len, UINT8 *buf )?????????????????????????????????

//* FUCTION:? CH376的端點(diǎn)緩沖區(qū)寫入數(shù)據(jù)塊???????????????????????????????

//* 輸入?yún)?shù): 要寫入數(shù)據(jù)塊的長度,寫入數(shù)據(jù)緩沖區(qū)的地址

//* 輸出參數(shù):無???????????????????????????????????

//* 說明:??? CH376的主機(jī)端點(diǎn)緩沖區(qū)中寫入要發(fā)送的數(shù)據(jù)塊?????????????????????????????????

//******************************************************

?

void WR_USB_DATA( UINT8 len, UINT8 *buf ) {?

??? CH376_WR_CMD_PORT( CMD10_WR_HOST_DATA );???? // CH376的端點(diǎn)緩沖區(qū)寫入準(zhǔn)備發(fā)送的數(shù)據(jù)

??? CH376_WR_DAT_PORT( len );??????????????????? // 后續(xù)數(shù)據(jù)長度, len不能大于64

??? while( len-- ) CH376_WR_DAT_PORT( *buf++ );

}

?

?

//*****************************************************

//* NAME:???? issue_token(UINT8 endptog, UINT8 endp_and_pid )??????????????????????????????

//* FUCTION:? 執(zhí)行USB事務(wù)?????????????????????????????

//* 輸入?yún)?shù): 同步標(biāo)志,端點(diǎn)號(hào)和令牌

//* 輸出參數(shù):無???????????????????????????????????

//* 說明:??? 4位目的端點(diǎn)號(hào), 4位令牌PID??????????????????????????????????

//******************************************************

?

void issue_token(UINT8 endptog, UINT8 endp_and_pid ) {?

??? CH376_WR_CMD_PORT( CMD2H_ISSUE_TKN_X );

??? CH376_WR_DAT_PORT( endptog );

??? CH376_WR_DAT_PORT( endp_and_pid );

??? mDelay2uS();?

}

?

///*------------------------------------------------

//??????????????????? 發(fā)送一個(gè)字節(jié)

//------------------------------------------------*/

//

//void SendByte(unsigned char dat)

//{

// SBUF = dat;

// while(!TI);

//????? TI = 0;

//}

?

//*****************************************************

//* NAME:???? wait_interrupt( )????????????????????????????

//* FUCTION:? 等待中斷,并且獲取中斷狀態(tài)???????????????????????????????

//* 輸入?yún)?shù):

//* 輸出參數(shù):中斷狀態(tài)?????????????????????????????????

//* 說明:??? CH376操作完成中斷(INT#低電平)?? ????????????????????????????????? ?

//******************************************************

?

UINT8 wait_interrupt( ) {?

??? while( CH376_INT_WIRE );

??? CH376_WR_CMD_PORT( CMD_GET_STATUS );

??? return( CH376_RD_DAT_PORT() );

}

?

?

?

//*****************************************************

//* NAME:???? Get_Dev_Descr( )?????????????????????????????

//* FUCTION:? 獲取設(shè)備描述符???????????????????????????????

//* 輸入?yún)?shù):

//* 輸出參數(shù):成功返回1,否則返回0????????????????????????????????

//* 說明:??? 該程序采用外置固件模式獲取設(shè)備描述符?? ?????????????????????????????????? ?

//******************************************************

?

UINT8 Get_Dev_Descr( )

{??

??? UINT8 descr_len;

??? UINT8? *p=data_buf;

??? send_mode=0x00;

??? WR_USB_DATA(8,SetupGetDevDescr);

?

??? issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)?????? ???????????????????????????????????????????????//SETUP階段操作成功

??? {

??????? receive_mode=0x80;

??? }

??? else return(0);

?

??? issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)???????????????????????????????????????????????????? //DATA階段操作成功

??? {

??????? descr_len=data_buf[0]-RD_USB_DATA(data_buf);???

??????? while(descr_len>0)

??????? {??

??????????? receive_mode ^= 0x80;

??????????? p+=0x08;

??????????? issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();

??????????? if(status==USB_INT_SUCCESS)???????????????????????????????????????????? //DATA階段操作成功

??????????????? descr_len-=RD_USB_DATA(p);?

??????????? else return(0);

???????????

??????? }

??? }

??? else return(0);

?

??? send_mode=0x40;

??? WR_USB_DATA(0,SetupGetDevDescr);

??? issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)???????????????????????????????????????????????? ??? //狀態(tài)階段操作成功

??????? return(1);?

??? else return(0);

}

?

?

?

//*****************************************************

//* NAME:???? Get_Cfg_Descr( PUINT8 buf )??????????????????????????????

//* FUCTION:? 獲取配置描述符???????????????????????????????

//* 輸入?yún)?shù): 接收緩沖區(qū)地址

//* 輸出參數(shù):成功返回1,否則返回0????????????????????????????????

//* 說明:? ??該程序采用外置固件模式獲取配置描述符?? ?????????????????????????????????? ?

//******************************************************

?

UINT8 Get_Cfg_Descr( PUINT8 buf )

{

??? unsigned char descr_len;

??? unsigned char *p=data_buf;

??? send_mode=0x00;

??? WR_USB_DATA(8,buf);

??? issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)???????????????????????????????????????????????????? //SETUP階段操作成功

??? {

??????? receive_mode=0x80;

??? }

??? else return(0);

??? issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)???????????????????????????????????????????????????? //DATA階段操作成功

??? {??

??? ??? receive_mode ^= 0x80;

??????? if(flag_config_2)?????????????????????????????????????????????????????? ??? //第二次獲取設(shè)備的配置描述符

??? ???????? descr_len=data_buf[2]-RD_USB_DATA(data_buf);

??????? else descr_len=data_buf[0]-RD_USB_DATA(data_buf);??

??????? while(descr_len>0)

??????? {??

??????????? p+=0x08;

??????????? issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();

??????????? if(status==USB_INT_SUCCESS)???????????????????????????????????????????? //DATA階段操作成功

??????????? ? {

??????????? ??? receive_mode ^= 0x80;

??????????????? descr_len-=RD_USB_DATA(p);?

??????????? ?? }

??????????? else return(0);

???????????

??????? }

??? }

??? else return(0);

??? send_mode = 0x40;

??? WR_USB_DATA(0,SetupGetCfgDescr);

??? issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)???????????????????????????????????????????????????? //狀態(tài)階段操作成功

??????? return(1);?

??? else return(0);

}

?

?

void parse_config_descr( )

{

? Device_Atti.Device_connect = 1;?????????????????????? ??????????????????? //表示設(shè)備連接

? Device_Atti.Cfg_value = ((PUSB_CFG_DESCR)data_buf)->bConfigurationValue;? //保留配置描述符中的配置值

?

?if(((PUSB_CFG_DESCR)data_buf)->bNumInterfaces==1)????? ? ????????????????? //只有一個(gè)接口設(shè)備

? {

??? Device_Atti.Device_compat = 0;????????????????????? ? ????????????????? //非復(fù)合設(shè)備

?

?#define HID_Dev? ((PHID_DEVICE)data_buf)

???

? ? Device_Atti.Device[0].Device_type =? HID_Dev->hid_itf_descr.bInterfaceProtocol; //設(shè)備類型:0x01 鍵盤,0x02 鼠標(biāo)

??? Device_Atti.Device[0].Device_inf? =? HID_Dev->hid_itf_descr.bInterfaceNumber;?? //設(shè)備的接口號(hào)

??? Device_Atti.Device[0].Device_endp =? HID_Dev->endp_descr.bEndpointAddress;????? //設(shè)備端點(diǎn)地址

? ? Device_Atti.Device[0].Device_size =? HID_Dev->endp_descr.wMaxPacketSize;??????? //設(shè)備端點(diǎn)大小

??? Device_Atti.Device[0].Device_report_len =? (HID_Dev->hid_class_descr.wDescriptorLength>>8)|(HID_Dev->hid_class_descr.wDescriptorLength<<8); ?? //報(bào)表長度,大小端數(shù)據(jù)格式轉(zhuǎn)換

?

? }

?

?else if(((PUSB_CFG_DESCR)data_buf)->bNumInterfaces==2)???? ? ????????????? //2個(gè)接口設(shè)備

? {

??? Device_Atti.Device_compat = 1;????????????????????? ? ????????????????? //復(fù)合設(shè)備

?

?#define HID_Dev1? ((PHID_COMPOSITE_DEVICE1)data_buf)

???

? ? Device_Atti.Device[0].Device_type =? HID_Dev1->hid_itf_descr1.bInterfaceProtocol;

??? Device_Atti.Device[0].Device_inf? =? HID_Dev1->hid_itf_descr1.bInterfaceNumber;

??? Device_Atti.Device[0].Device_endp =? HID_Dev1->endp_descr1.bEndpointAddress;

? ? Device_Atti.Device[0].Device_size =? HID_Dev1->endp_descr1.wMaxPacketSize;

??? Device_Atti.Device[0].Device_report_len =? (HID_Dev1->hid_class_descr1.wDescriptorLength>>8)|(HID_Dev1->hid_class_descr1.wDescriptorLength<<8); //報(bào)表長度,大小端數(shù)據(jù)格式轉(zhuǎn)換

?

? ? Device_Atti.Device[1].Device_type =? HID_Dev1->hid_itf_descr2.bInterfaceProtocol;

??? Device_Atti.Device[1].Device_inf? =? HID_Dev1->hid_itf_descr2.bInterfaceNumber;

??? Device_Atti.Device[1].Device_endp =? HID_Dev1->endp_descr2.bEndpointAddress;

? ? Device_Atti.Device[1].Device_size =? HID_Dev1->endp_descr2.wMaxPacketSize;

??? Device_Atti.Device[1].Device_report_len =? (HID_Dev1->hid_class_descr2.wDescriptorLength>>8)|(HID_Dev1->hid_class_descr2.wDescriptorLength<<8); //報(bào)表長度,大小端數(shù)據(jù)格式轉(zhuǎn)換

?

? }

?

}

?

?

UINT8 set_config( UINT8 cfg ) {?

??? CH376_WR_CMD_PORT( CMD_SET_CONFIG );?

??? CH376_WR_DAT_PORT( cfg );?

??? return( wait_interrupt() );?

}

?

?

UINT8 set_idle( UINT8 inf )

{

??? send_mode=0x00;

??? memcpy(data_buf,SetupSetidle,8);

??? data_buf[4] = inf;

??? WR_USB_DATA(8,data_buf);??????????????????????????????? //SETUP數(shù)據(jù)總是8字節(jié)

??? issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);

??? status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)???????????????????????????? //SETUP階段操作成功

??? {

??????? receive_mode=0x80;

??????? issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN );status=wait_interrupt();

??????? if(status==USB_INT_SUCCESS)???????????????????????? //狀態(tài)階段操作成功

??????? {

??????????? if(RD_USB_DATA(data_buf)!=0)

??????????? return(0);

??????? }

??????? else return(0);

??? }

??? else return(0);

??? return(1);?

}

?

?

?

UINT8 get_report_descr_ex( UINT8 inf,UINT16 len)???????

{

??? unsigned char descr_len;

??? unsigned char *p=data_buf;

??? unsigned char report_cou_temp=0;

??? report_cou=0;

??? send_mode=0x00;

??? memcpy(data_buf,SetupGetHidDes,8);

??? data_buf[4] = inf;

??? data_buf[6] = len+0x40;????????????????

??? WR_USB_DATA(8,data_buf);???????

??? issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();?

??? if(status==USB_INT_SUCCESS)???????????????????????????????????????????????????? //SETUP階段操作成功

??? {??

??? ??? receive_mode=0x80;?

??? }

??? else return(0);

??? issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)???? ??????????????????????????????????????????????? //DATA階段操作成功

??? {??

??? ??

??? ?? RD_USB_DATA(data_buf);

??????? report_cou+=8;?

??????? descr_len=data_buf[6]-0x08;???????????????????????????????????????????????? //剩余描述符長度計(jì)算

??????? while(descr_len>0)

??????? {??

??????????? receive_mode ^= 0x80;

??????????? p+=0x08;

??????????? issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();

??????????? if(status==USB_INT_SUCCESS)???????????????????????????????????????????? // DATA階段操作成功

??????????? {??

??????????? ??? report_cou_temp=RD_USB_DATA(p);

??????????????? if(report_cou_temp!=0x08){report_cou+=report_cou_temp;break;}

??????????????? else {descr_len-=0x08;report_cou+=8;}

??????????? }

??????????? else return(0);

???????????

??????? }

??? }

??? else return(0);

??? send_mode=0x40;

??? WR_USB_DATA(0,data_buf);

??? issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)???????????????????????????????????????????????????? //狀態(tài)階段操作成功

??????? return(1);?

??? else return(0);

}

?

?

UINT8 set_report( )

{??

??? send_mode=0x00;

??? WR_USB_DATA(8,SetupSetReport);????????????????????????????????????????????????? //SETUP數(shù)據(jù)總是8字節(jié)

??? issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();

??? if(status==USB_INT_SUCCESS)???????????????????????????? ??????????????????????? //SETUP階段操作成功

??? {??

??? ??? send_mode ^= 0x40;

??????? data_buf[0]=0x01;

??????? WR_USB_DATA(1,data_buf);

??????? issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();

??????? if(status==USB_INT_SUCCESS) ??????????????????????????????????????????????? //DATA階段操作成功

??????? {??

??????? ??? receive_mode=0x80;

??????????? issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();

??????????? if(status==USB_INT_SUCCESS)???????????????????????????????????????????? //狀態(tài)階段操作成功

??????????? {??

??????????? ??? if(RD_USB_DATA(data_buf)!=0)

??????????????? return(0);

??????????? }

??????????? else return(0);

??????? }

??????? else return(0);

??? }??

??? else return(0);

???

???

??? return(1);

}

?

?

//*****************************************************

//* NAME:???? get_int_in(UINT8 tog,UINT8 endp_int)?????????????????????????????

//* FUCTION:? 獲取HID類設(shè)備的數(shù)據(jù)?????????????????????????????

//* 輸入?yún)?shù): 該設(shè)備的同步標(biāo)志,端點(diǎn)號(hào)

//* 輸出參數(shù):操作狀態(tài)?????????????????????????????????

//* 說明:??? 支持復(fù)合設(shè)備的操作? ????????????????????????????????? ?

//******************************************************

?

UINT8 get_int_in(UINT8 tog,UINT8 endp_int)

{

??? UINT8 s,t,j;

??? tog = tog ? 0x80 : 0x00;

??? issue_token(tog,( endp_int << 4 ) | DEF_USB_PID_IN);

??? s = wait_interrupt( );

??? ?if(s == USB_INT_SUCCESS)

??? ?{

??????? ? t = RD_USB_DATA(data_buf);??????????????????????????????????????? //鍵盤中斷端點(diǎn)數(shù)據(jù)長度一般為8字節(jié),鼠標(biāo)為4字節(jié)

???????

??????? for(j=0;j!=t;j++)?? SerialPortTwo_Send(data_buf[j]);

? ????? if( endp_int == Device_Atti.Device[0].Device_endp )

??????? ?Device_Atti.Device[0].tog = Device_Atti.Device[0].tog ? FALSE : TRUE;

? ? ????else

??????? ?Device_Atti.Device[1].tog = Device_Atti.Device[1].tog ? FALSE : TRUE;

??? }

??? ?SerialPortTwo_Send('g');//

??? return s;

}

?

?

?

void Reset_Device( )

{??

??? Set_USB_Mode( 7 );? ??????????????????????????????????????????????????? //復(fù)位USB設(shè)備,CH376USB信號(hào)線的D+D-輸出低電平

??? mDelaymS(10);

??? Set_USB_Mode( 6 );? ??????????????????????????????????????????????????? //結(jié)束復(fù)位,將CH376設(shè)置成主機(jī)模式

??? while ( wait_interrupt()!=USB_INT_CONNECT );? ????????????????????????? //等待復(fù)位之后的設(shè)備端再次連接上來

?

}

?

//*****************************************************

//* NAME:???? set_addr( UINT8 addr )???????????????????????????????

//* FUCTION:? 設(shè)置USB設(shè)備地址,并且設(shè)置USB主機(jī)端要操作的USB設(shè)備地址????????????????????? ???????

//* 輸入?yún)?shù): 地址值(1~127)

//* 輸出參數(shù):操作狀態(tài)?????????????????????????????????

//* 說明:???

//******************************************************

?

UINT8 set_addr( UINT8 addr ) {

??? UINT8 status;

??? CH376_WR_CMD_PORT( CMD_SET_ADDRESS );?

??? CH376_WR_DAT_PORT( addr );?

??? status=wait_interrupt();? ????????????????????????????????????????????? //等待CH376操作完成

??? if ( status==USB_INT_SUCCESS ) {? ????????????????????????????????????? //操作成功

??????? CH376_WR_CMD_PORT( CMD_SET_USB_ADDR );? ??????????????????????????? //設(shè)置USB主機(jī)端的USB地址

??????? CH376_WR_DAT_PORT( addr );? ??????????????????????????????????????? //當(dāng)目標(biāo)USB設(shè)備的地址成功修改后,應(yīng)該同步修改主機(jī)端的USB地址

??? }

??? return( status );

}

?

?

?

void main( void )

{

? UINT8 i,s;

? mDelay50mS( );??? ?? //CH376上電之后需要延時(shí)40ms左右

?

? StdioInit( );

//? SendByte('A');?

//? printf("start \n");

?

?// SendStrTwo("QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ");

?

//做測試命令,檢測單片機(jī)和CH376硬件連接,以及讀寫時(shí)序是否正確?

? CH376_WR_CMD_PORT( 0x06 );

?

? CH376_WR_DAT_PORT( 0x55 );

?

? s = CH376_RD_DAT_PORT( );

?

?? SerialPortTwo_Send(s);

?

//? SendByte('B');

?

? SerialPortTwo_Send(Set_USB_Mode( 6 )+0x30);? ???????????????????????????????? //設(shè)置USB主機(jī)模式, 如果設(shè)備端是CH37X, 那么56均可

?

? set_freq( );? ?????? ???????????????????????????????? //使376進(jìn)入低速模式

?

//? SendByte('C');

?

?while(1)

?{

? //? printf(" \n wait usb device : \n");

??? while ( wait_interrupt()!=USB_INT_CONNECT );

??? SerialPortTwo_Send('A');

??? mDelaymS(50);

??? Reset_Device();

??? SerialPortTwo_Send('B');??????????????????????????????????? //復(fù)位usb設(shè)備

??? mDelaymS(50);

??? set_freq( );?????? ???????????????????????????????? //使376進(jìn)入低速模式

??? mDelaymS(50);

?

//獲取設(shè)備描述符

??? if(Get_Dev_Descr()==1)

??? {

??????? for(i=0;i!=data_buf[0];i++)

??? ??? SerialPortTwo_Send('D'); // printf("%02x ",(unsigned int)data_buf[i]);?

??? ??? //? printf("\n");

??? }

??? else SerialPortTwo_Send('E');//printf("\n get device descr failed \n");

?

//設(shè)置地址?????

??? SerialPortTwo_Send(set_addr(5));???????????????????????????????????????

?

//獲取配置描述符

??? if( Get_Cfg_Descr( SetupGetCfgDescr ) == 1)

??? ?{

?? ???? for(i=0;i!=data_buf[0];i++)

??? ????? SerialPortTwo_Send(data_buf[i]);?

??????? ?// SerialPortTwo_Send("\n");

??? ?}

??? ?s = ((PUSB_CFG_DESCR)data_buf)->wTotalLengthL;

??? ?memcpy( data_buf,SetupGetCfgDescr,8);

???? data_buf[6] = s;

?

??? ?flag_config_2 = 1;

??? if( Get_Cfg_Descr( data_buf ) == 1)

??? ?{

?? ???? for(i=0;i!=((PUSB_CFG_DESCR)data_buf)->wTotalLengthL;i++)

??????? ? SerialPortTwo_Send(data_buf[i]);?

??????? ?// SerialPortTwo_Send("\n");

??? ?}

?

//保存配置描述符中設(shè)備信息

??? parse_config_descr( );

?

?

#if 0

#endif

? SendStrTwo("line838");

//設(shè)置USB配置??

?? s = set_config( Device_Atti.Cfg_value );

? //?? SerialPortTwo_Send(" cfg %02x \n",(UINT16)s);

?

//設(shè)置HID類設(shè)備的IDLE

?? s = set_idle( Device_Atti.Device[0].Device_inf );

?? if(s == 1)

????? SerialPortTwo_Send('O');

?? else?? SerialPortTwo_Send('N');

?

//獲取HID類設(shè)備的報(bào)表描述符

? ?s = get_report_descr_ex( Device_Atti.Device[0].Device_inf,Device_Atti.Device[0].Device_report_len);

??? if( s == 1)

??? ?{

??? ?? for(i=0;i!=report_cou;i++)

??? ????? SerialPortTwo_Send(data_buf[i]);

??? ?

??? ?}

?

//如果該HID類設(shè)備是鍵盤,則可以設(shè)置報(bào)表

??? if(Device_Atti.Device[0].Device_type == 0x01)

??? {

??? s = set_report( );

??? if(s==1)?? SerialPortTwo_Send('J');

??? else?? SerialPortTwo_Send('P');

??? }

?

//如果該設(shè)備是復(fù)合設(shè)備,則需要配置另外一個(gè)接口設(shè)備

#if 1

??? if(Device_Atti.Device_compat == 1)

??? {

//設(shè)置IDLE

??? ?s = set_idle( Device_Atti.Device[1].Device_inf );

????? if(s == 1)

?? ????SerialPortTwo_Send('Q');

???? else?? SerialPortTwo_Send('R');

?

//獲取報(bào)表描述符

???? s = get_report_descr_ex( Device_Atti.Device[1].Device_inf,Device_Atti.Device[1].Device_report_len);

??? ? if( s == 1)

??? ?? {

??? ??? for(i=0;i!=report_cou;i++)

??? ????? SerialPortTwo_Send(data_buf[i]);?

??? ?? }

?

//如果該設(shè)備是鍵盤,則可以設(shè)置報(bào)表

??? if(Device_Atti.Device[1].Device_type == 0x01)

??? ?{

??? ? s = set_report( );

??? ? if(s==1)?? SerialPortTwo_Send('S');

??? ? else?? SerialPortTwo_Send('T');

?

??? ?}

?

?? }

#endif

?

?

??? CH376_WR_CMD_PORT( CMD20_SET_RETRY );?????? //設(shè)置CH376重試次數(shù)

??? CH376_WR_DAT_PORT( 0x25 );

??? CH376_WR_DAT_PORT( 0x00 );????????????????? //為了保證兼容性對(duì)于部分鼠標(biāo)鍵盤需要設(shè)置有限次重試(0xc0),而對(duì)于復(fù)合設(shè)備,

??? ???????????????????????????????????????????? //比如USB轉(zhuǎn)PS2的設(shè)備,復(fù)合鍵盤,則不需要重試(0x00)

?

?

??? Device_Atti.Device[0].tog = FALSE;????????? //設(shè)置設(shè)備的同步標(biāo)志,默認(rèn)0

??? Device_Atti.Device[1].tog = FALSE;

?

SendStrTwo("line906");

?

?? while(1)

?? {

//獲取設(shè)備1的數(shù)據(jù)

?? s = get_int_in( Device_Atti.Device[0].tog,Device_Atti.Device[0].Device_endp);

?

//如果該設(shè)備是符合設(shè)備,則需要獲取設(shè)備2的數(shù)據(jù)

??? if( Device_Atti.Device_compat )

??? {

??? ?s = get_int_in( Device_Atti.Device[1].tog,Device_Atti.Device[1].Device_endp);

??? }

?

//以下是檢測設(shè)備插拔狀態(tài)

??? CH376_WR_CMD_PORT(CMD01_TEST_CONNECT );???????? //檢測設(shè)備插拔

??? ?s = CH376_RD_DAT_PORT( );

??? ?if(s == USB_INT_DISCONNECT )

??? ?{

????? Device_Atti.Device_connect = 0;

//? ??? Device_Atti = {0};

??? ? break;??????????????????????????????????????? //設(shè)備斷開

?? ?}

?? }

?}

?

}

?

?

這個(gè)程序可以直接讀取鍵盤數(shù)據(jù)的,你現(xiàn)在是到哪一步?jīng)]過?你打印或者用Bushound監(jiān)控下程序。


我看到你發(fā)的郵件了,你換個(gè)郵箱發(fā)吧,這個(gè)郵箱我們郵件發(fā)不進(jìn)去。


hid.h頭文件到哪里找?


icon_rar.gif20132281345081.rar

這是ch376操作HID的例子,里面有hid.h


只有登錄才能回復(fù),可以選擇微信賬號(hào)登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频