請(qǐng)問(wèn)如何單片機(jī)通過(guò)usb協(xié)議發(fā)送數(shù)據(jù)控制電腦里面打開(kāi)的ppt。采用的是CH375B作為USB接口芯片.內(nèi)置固件的模式。 問(wèn)題一:我不知道單片機(jī)發(fā)送的數(shù)據(jù)如何使電腦產(chǎn)生相應(yīng)的反應(yīng)。例如當(dāng)你打開(kāi)ppt后,是單片機(jī)通過(guò)usb協(xié)議發(fā)送ALT+F5的鍵值他就能關(guān)閉ppt嗎,發(fā)送pagedown的鍵值他就會(huì)往下翻頁(yè)嗎?還是要編寫上位機(jī)程序。(一般的實(shí)例中都是單片機(jī)發(fā)送數(shù)據(jù),讓上位機(jī)顯示。) 問(wèn)題二:有沒(méi)有關(guān)于此項(xiàng)目的相關(guān)資料,其實(shí)主要問(wèn)題還是單片機(jī)模擬usb鍵盤,有沒(méi)有相關(guān)的usb鍵盤工作原理的資料,或者此工程的資料,分享一下。謝謝!
你要實(shí)現(xiàn)的就是使用CH372/375模擬一個(gè)鍵盤就可以了,當(dāng)然需要使用CH372/375的外置固件模式,到下面的地址中下載事例程序 http://www.findthetime.net/bbs/View.asp?T=1&S=101&I=19463
我想采用內(nèi)置固件減少編程量,難道不可以嗎?一定要采用外置固件嗎?請(qǐng)高手幫我解答一下,謝謝。
一定要使用外置固件,因?yàn)閮?nèi)置固件是無(wú)法模擬出鍵盤的。
如果采用1樓_study_的資料(如下),用外置固件,發(fā)送pagedown的鍵值就能使打開(kāi)的ppt翻頁(yè)嗎?
375、372外置固件模擬鍵盤鼠標(biāo)的例子程序: UploadImages/200842213304565.rar
首先一個(gè)問(wèn)題就是你使用普通的鍵盤使用pagedown這個(gè)鍵就可以實(shí)現(xiàn)翻頁(yè)嗎?如果可以的話,那么使用CH372發(fā)送這個(gè)鍵值也是可以實(shí)現(xiàn)的,CH372模擬的鍵盤和普通鍵盤完全一樣。
/*;CH372/CH375 USB device mode & external firmware ; U2(AT89C51) Program ; ; Website: http://winchiphead.com ; Email: 個(gè)人信息保護(hù),已隱藏 ; Author: W.ch 2003.12, 2005.03 ; ;**************************************************************************** 關(guān)于程序的說(shuō)明: 模擬鍵盤程序,主機(jī)枚舉好后,發(fā)送K,可以在TXT文檔中顯示出來(lái)。作為演示,需要其他鍵值可以自己修改,如果不是連續(xù)發(fā)數(shù)據(jù)的 話,一般發(fā)送完畢鍵值后發(fā)送一包00,主機(jī)認(rèn)為發(fā)送結(jié)束 */
/* MCS-51單片機(jī)C語(yǔ)言的示例程序 */ #include #include "CH375INC.H"
unsigned char idata buf[8]; typedef union _REQUEST_PACK{ unsigned char buffer[8]; struct{ unsigned char bmReuestType; //標(biāo)準(zhǔn)請(qǐng)求字 unsigned char bRequest; //請(qǐng)求代碼 unsigned int wValue; //特性選擇高 unsigned int wIndx; //索引 unsigned int wLength; //數(shù)據(jù)長(zhǎng)度 }r; } mREQUEST_PACKET, *mpREQUEST_PACKET;
//設(shè)備描述符 unsigned char code DevDes[]={ 0x12 //描述符大小 , 0x01 //常數(shù)DEVICE , 0x10 //USB規(guī)范版本信息 , 0x01 , 0x00 //類別碼, , 0x00 //子類別碼 , 0x00 //協(xié)議碼 , 0x08 //端點(diǎn)0的最大信息包大小 , 0x3c //廠商ID , 0x41 , 0x03 //產(chǎn)品ID , 0x20 , 0x00 //設(shè)備版本信息 , 0x02 , 0x01 //索引值 , 0x02 , 0x00 , 0x01 //可能配置的數(shù)目 }; //配置描述符 unsigned char code ConDes[]={ //配置描述符 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x04, 0xa0, 0x23,//配置描述符 0x09, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x01, 0x05,//接口描述符 0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, 0x41, 0x00,//HID類描述符 0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x18 //端點(diǎn)描述符,只配置了輸入端點(diǎn),輸出端點(diǎn)用0端點(diǎn) }; //配置描述符
/*報(bào)表描述符*/ unsigned char code Hid_des[]={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, 0x01, 0x75, 0x05, 0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05, 0x07, 0x19, 0x00, 0x2a, 0xff, 0x00, 0x81, 0x00, 0xc0 }; /*關(guān)于全局變量的定義*/ unsigned char mVarSetupRequest; // ;USB請(qǐng)求碼 unsigned char mVarSetupLength; // 后續(xù)數(shù)據(jù)長(zhǎng)度 unsigned char code * VarSetupDescr; //描述符偏移地址 unsigned char VarUsbAddress ; sbit CH375_INT_WIRE = 0xB0^2; //P3.2, INT0, 連接CH375的INT#引腳,用于查詢中斷狀態(tài) */ sbit CH375ACT = P1^4; bit CH375FLAGERR; //錯(cuò)誤清0 bit CH375CONFLAG; unsigned char idata UPDATA_FLAG; mREQUEST_PACKET request;
/*硬件定義,根據(jù)硬件修改*/ unsigned char volatile xdata CH375_CMD_PORT _at_ 0XB1FF;//0xBDF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0XB0FF;//0xBCF0; /* CH375數(shù)據(jù)端口的I/O地址 */
/* 延時(shí)2微秒,不精確 */ void Delay1us() { ; }
void Delay2us( ) { unsigned char i; #define DELAY_START_VALUE 0 /* 根據(jù)單片機(jī)的時(shí)鐘選擇初值,20MHz以下為0,30MHz以上為2 */ for ( i=DELAY_START_VALUE; i!=0; i-- ); }
/* 延時(shí)50毫秒,不精確 */ void Delay50ms( ) { unsigned char i, j; for ( i=200; i!=0; i-- ) for ( j=250; j!=0; j-- ); }
void CH375_WR_CMD_PORT( unsigned char cmd ) { /* 向CH375的命令端口寫入命令,周期不小于4uS,如果單片機(jī)較快則延時(shí) */ CH375_CMD_PORT=cmd; Delay2us( ); }
void CH375_WR_DAT_PORT( unsigned char dat ) { /* 向CH375的數(shù)據(jù)端口寫入數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時(shí) */ CH375_DAT_PORT=dat; Delay1us(); /* 因?yàn)镸CS51單片機(jī)較慢所以實(shí)際上無(wú)需延時(shí) */ }
unsigned char CH375_RD_DAT_PORT() { /* 從CH375的數(shù)據(jù)端口讀出數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時(shí) */ Delay1us( ); /* 因?yàn)镸CS51單片機(jī)較慢所以實(shí)際上無(wú)需延時(shí) */ return( CH375_DAT_PORT );
} /* CH375初始化子程序 */ void CH375_Init( ) { /* 設(shè)置USB工作模式, 必要操作 */ CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); CH375_WR_DAT_PORT( 1 ); /* 設(shè)置為使用內(nèi)置固件的USB設(shè)備方式 */ for ( ;; ) { /* 等待操作成功,通常需要等待10uS-20uS */ if ( CH375_RD_DAT_PORT( )==CMD_RET_SUCCESS )P1=0XAA;Delay50ms( );P1=0XFF; break;
} }
//端點(diǎn)0數(shù)據(jù)上傳 void mCh375Ep0Up() { unsigned char i,len; if(mVarSetupLength) { //長(zhǎng)度不為0傳輸具體長(zhǎng)度的數(shù)據(jù) if(mVarSetupLength<=8) { len=mVarSetupLength; mVarSetupLength=0; } //長(zhǎng)度小于8則長(zhǎng)輸要求的長(zhǎng)度 else { len=8; mVarSetupLength-=8; } //長(zhǎng)度大于8則傳輸8個(gè),切總長(zhǎng)度減8 CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //發(fā)出寫端點(diǎn)0的命令 CH375_WR_DAT_PORT(len); //寫入長(zhǎng)度 for(i=0;i!=len;i++) CH375_WR_DAT_PORT(request.buffer[i]); //循環(huán)寫入數(shù)據(jù) } else { CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //發(fā)出寫端點(diǎn)0的命令 CH375_WR_DAT_PORT(0); //上傳0長(zhǎng)度數(shù)據(jù),這是一個(gè)狀態(tài)階段 } }
//復(fù)制描述符以便上傳 void mCh375DesUp() { unsigned char k; for (k=0; k!=8; k++ ) { request.buffer[k]=*VarSetupDescr; //依次復(fù)制8個(gè)描述符, VarSetupDescr++; } }
/*中斷函數(shù),但是本例用的是查詢方式,只處理了輸入端點(diǎn)1和端點(diǎn)0的事件,其余不處理*/ void mCH375Interrupt( ) { unsigned char InterruptStatus; unsigned char length, c1, len; CH375_WR_CMD_PORT(CMD_GET_STATUS); /* 獲取中斷狀態(tài)并取消中斷請(qǐng)求 */ InterruptStatus =CH375_RD_DAT_PORT(); /* 獲取中斷狀態(tài) */ switch(InterruptStatus){ // 分析中斷狀態(tài) case USB_INT_EP1_OUT: //中斷端點(diǎn)下傳成功,未處理 CH375_WR_CMD_PORT(CMD_RD_USB_DATA); //發(fā)出讀數(shù)據(jù)命令 if( length=CH375_RD_DAT_PORT( ) ) { //長(zhǎng)度為0跳出 for(len=0;len!=length;len++)c1=CH375_RD_DAT_PORT(); //取出下傳數(shù)據(jù) } break; case USB_INT_EP0_SETUP: //控制端點(diǎn)建立成功 CH375_WR_CMD_PORT(CMD_RD_USB_DATA); length=CH375_RD_DAT_PORT(); for(len=0;len!=length;len++)request.buffer[len]=CH375_RD_DAT_PORT(); // 取出數(shù)據(jù) if(length==0x08){ mVarSetupLength=request.buffer[6]; //控制傳輸數(shù)據(jù)長(zhǎng)度最大設(shè)置為128 if((c1=request.r.bmReuestType)&0x40){ //廠商請(qǐng)求,未處理 } if((c1=request.r.bmReuestType)&0x20) { //類請(qǐng)求,未處理 if(request.buffer[1]==0x0a) { } //SET_IDLE else if(request.buffer[1]==0x09) { UPDATA_FLAG=1; } } if(!((c1=request.r.bmReuestType)&0x60)) { //標(biāo)準(zhǔn)請(qǐng)求 mVarSetupRequest=request.r.bRequest; //暫存標(biāo)準(zhǔn)請(qǐng)求碼 switch(request.r.bRequest){ // 分析標(biāo)準(zhǔn)請(qǐng)求 case DEF_USB_CLR_FEATURE: //清除特性 if((c1=request.r.bmReuestType&0x1F)==0X02) { //不是端點(diǎn)不支持 switch(request.buffer[4]) { case 0x82: CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端點(diǎn)2上傳 CH375_WR_DAT_PORT(0x8E); //發(fā)命令清除端點(diǎn) break; case 0x02: CH375_WR_CMD_PORT(CMD_SET_ENDP6); CH375_WR_DAT_PORT(0x80); //清除端點(diǎn)2下傳 break; case 0x81: CH375_WR_CMD_PORT(CMD_SET_ENDP5); //清除端點(diǎn)1上傳 CH375_WR_DAT_PORT(0x8E); break; case 0x01: CH375_WR_CMD_PORT(CMD_SET_ENDP4); //清除端點(diǎn)1下傳 CH375_WR_DAT_PORT(0x80); break; default: break; } } else { CH375FLAGERR=1; //不支持的清除特性,置錯(cuò)誤標(biāo)志 } break; case DEF_USB_GET_STATUS: //獲得狀態(tài) request.buffer[0]=0; request.buffer[1]=0; //上傳狀態(tài) break; case D
你模擬的是鍵盤鼠標(biāo),你用的軟件是CH372DRV驅(qū)動(dòng)的測(cè)試程序,那是可以那才怪呢。 簡(jiǎn)單的說(shuō),你寫了一個(gè)對(duì)U盤讀寫的應(yīng)用程序,這是基于U盤驅(qū)動(dòng)的,而你現(xiàn)在插一個(gè)鼠標(biāo),你的應(yīng)用程序能讀寫這個(gè)鼠標(biāo)嗎??、
謝謝紅桃六大哥的提點(diǎn)。剛開(kāi)始接觸這東西,還有點(diǎn)不知所措,還是小菜鳥(niǎo)。
請(qǐng)問(wèn)我該選擇什么驅(qū)動(dòng)呢?到哪里下載?
我在網(wǎng)上看到說(shuō)用HID設(shè)備枚舉可以不用驅(qū)動(dòng)。我在網(wǎng)上找到一個(gè)程序,這種使用HID枚舉的方式嗎?程序如下:
/*;CH372/CH375 USB device mode & external firmware ; U2(AT89C51) Program ; Website: http://winchiphead.com ; Email: 個(gè)人信息保護(hù),已隱藏 ; Author: W.ch 2003.12, 2005.03 ;**************************************************************************** CH375 外部固件方式范例 ;此程序?yàn)閁SB設(shè)備,主機(jī)為計(jì)算機(jī);主機(jī)要識(shí)別設(shè)備的類型、完成與設(shè)備的通訊必須先獲取設(shè)備的描述符(用一組數(shù)據(jù)描述了 ;設(shè)備的詳細(xì)內(nèi)容), /* MCS-51單片機(jī)C語(yǔ)言的示例程序 */ #pragma NOAREGS #include #include "CH375INC.H" #include "stdio.h" unsigned char idata buf[64]; typedef union _REQUEST_PACK{ unsigned char buffer[8]; struct{ unsigned char bmReuestType; //標(biāo)準(zhǔn)請(qǐng)求字 unsigned char bRequest; //請(qǐng)求代碼 unsigned int wValue; //特性選擇高 unsigned int wIndx; //索引 unsigned int wLength; //數(shù)據(jù)長(zhǎng)度 }r; } mREQUEST_PACKET, *mpREQUEST_PACKET; //設(shè)備的描述符包含設(shè)備描述符、配置描述符、字符描述符;識(shí)別描述符的類型就是根據(jù)它的第二個(gè)字節(jié)值來(lái)識(shí)別; //一般情況下設(shè)備描述符不需要用戶去配置,因?yàn)榭梢灾苯佑密浖默F(xiàn)有的設(shè)備中讀?。煌N設(shè)備的描述符都相同;如優(yōu)盤描述符都一樣 /*以下是設(shè)備描述符,(為什么是這些數(shù)值,可查閱USB協(xié)議書(shū)籍)*/ unsigned char code DevDes[]={ 0x12 //描述符大小,即此數(shù)組的長(zhǎng)度 ,0x01 //常數(shù)表示描述符的類型;(數(shù)值為0x01表示設(shè)備描述符) ,0x10 ,0x01 //USB規(guī)范版本信息;2個(gè)字節(jié);0x10、0x01表示USB1.1;USB2.0為0X00、0X02; ,0x00 //類別碼,數(shù)值0X01~0XFE為USB定義的類,如打印機(jī)等,0XFF是由廠商指定的類別;0為HID類,它的類別在配置描述符中的接口描述符指定; ,0x00 //子類別碼;這些碼值的具體含義根據(jù)bDeviceClass 域來(lái)看如bDeviceClass 域?yàn)榱愦擞蛞岔殲榱?;如bDeviceClass 域?yàn)镕FH此域的所有值保留 ,0x00 //協(xié)議碼 ,0x08 //端點(diǎn)0的最大信息包大小 ,0x31 //廠商ID ,0x51 ,0x07 //產(chǎn)品ID ,0x20 ,0x00 //設(shè)備版本信息 ,0x03 ,0x01 //索引值 ,0x02 ,0x00 ,0x01 //可能配置的數(shù)目 }; //配置描述符;包括配置描述符、接口描述符、端點(diǎn)描述符,HID設(shè)備還包括HID描述符; unsigned char code ConDes[]={ 0x09, 0x02, 0x29, 0x00, 0x01, 0x01, 0x04, 0xa0, 0x23,//配置描述符;第二字節(jié)為0X02 0x09, 0x04, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x05,//接口描述符;第二字節(jié)為0X04 0x09, 0x21, 0x00, 0x01, 0x00, 0x01, 0x22, 0x22, 0x00,//HID描述符;第二字節(jié)為0X21 0x07, 0x05, 0x82, 0x03, 0x40, 0x00, 0x18, //端點(diǎn)描述符;第二字節(jié)為0X05 0x07, 0x05, 0x02, 0x03, 0x40, 0x00, 0x18 //端點(diǎn)描述符; }; //字符串描述符,報(bào)表描述符; //作鍵盤設(shè)備時(shí),報(bào)表描述符描述了數(shù)據(jù)格式;如鍵盤,則必須發(fā)送8個(gè)字節(jié)的數(shù)據(jù);其中第3個(gè)字節(jié)是要在 //各種文本里顯示的數(shù)據(jù)(如WORD文擋);其余字節(jié)全為0; unsigned char code Hid_des[]={ 0x06, 0x00,0xff, 0x09, 0x01, 0xa1, 0x01, //集合開(kāi)始 0x09, 0x02, //Usage Page 用法 0x15, 0x00, //Logical Minimun 0x26, 0x00,0xff, //Logical Maximun 0x75, 0x08, //Report Size 0x95, 0x40, //Report Counet 0x81, 0x06, //Input 0x09, 0x02, //Usage Page 用法 0x15, 0x00, //Logical Minimun 0x26, 0x00,0xff, //Logical Maximun 0x75, 0x08, //Report Size 0x95, 0x40, //Report Counet 0x91, 0x06, //Output
0xC0 }; unsigned char code LangDes[]={0x04,0x03,0x09,0x04}; //語(yǔ)言描述符 unsigned char code SerDes[]={0x28,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x49,0x00,0x43,0x00,0x42 ,0x00,0x43,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00 }; //字符串描述符
unsigned char mVarSetupRequest; // ;USB請(qǐng)求碼 unsigned char mVarSetupLength; // ;后續(xù)數(shù)據(jù)長(zhǎng)度 unsigned char code * VarSetupDescr;// ;描述符偏移地址 unsigned char buf1[8]; unsigned char VarUsbAddress ; // unsigned char Report_ID=0X01;
sbit key = P3^3; sbit CS = P3^0; sbit WR_DAT = P3^4; sbit RD_DAT = P3^5; sbit A0 = P3^7; sbit CH375_INT_WIRE = P3^2; /* P3.2, INT0, 連接CH375的INT#引腳,用于查詢中斷狀態(tài) */ bit CH375FLAGERR; //錯(cuò)誤清0 bit CH375CONFLAG; unsigned char flag=0; mREQUEST_PACKET request;
unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375數(shù)據(jù)端口的I/O地址 */ void mInitSTDIO( ) { SCON = 0x50; PCON = 0x80; TMOD = 0x20; TH1 = 0xf3; /* 24MHz晶振, 9600bps */ TR1 = 1; TI = 1; } void delay10ms() { unsigned char i,j; for(i=10;i!=0;i--) for(j=100;j!=0;j--) ; }
void Delay1us(){;} /* 延時(shí)2微秒,不精確 */ void Delay2us( ) { unsigned char i; #define DELAY_START_VALUE 1 /* 根據(jù)單片機(jī)的時(shí)鐘選擇初值,20MHz以下為0,30MHz以上為2 */ for ( i=DELAY_START_VALUE; i!=0; i-- ); } /* 延時(shí)50毫秒,不精確 */ void Delay50ms( ) { unsigned char i, j; for ( i=200; i!=0; i-- ) for ( j=250; j!=0; j-- ); } /*以下是帶P0、P1、P2口的單片機(jī)外部讀寫方式、地址的確定和外部擴(kuò)展I/O口地址一樣,見(jiàn)硬件電路*/ void CH375_WR_CMD_PORT( unsigned char cmd ) { //向CH375的命令端口寫入命令,周期不小于4uS,如果單片機(jī)較快則延時(shí) //delay2us(); CH375_CMD_PORT=cmd; Delay2us( ); }
void CH375_WR_DAT_PORT( unsigned char dat ) { // 向CH375的數(shù)據(jù)端口寫入數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時(shí) CH375_DAT_PORT=dat; Delay1us(); // 因?yàn)镸CS51單片機(jī)較慢所以實(shí)際上無(wú)需延時(shí) }
unsigned char CH375_RD_DAT_PORT() { //從CH375的數(shù)據(jù)端口讀出數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時(shí) Delay1us( ); // 因?yàn)镸CS51單片機(jī)較慢所以實(shí)際上無(wú)需延時(shí) return( CH375_DAT_PORT );
}
/* CH375初始化子程序; */ void CH375_Init( ) { /* 設(shè)置USB工作模式, 必要操作 */ CH375_WR_CMD_PORT( CMD_SET_USB_MODE );//向數(shù)據(jù)端口寫設(shè)置CH375命令的數(shù)據(jù)CMD_SET_USB_MODE,數(shù)值大小在頭文件中有定義,說(shuō)明書(shū)中有規(guī)定值 CH375_WR_DAT_PORT( 1 ); /* 0X01設(shè)置為使用內(nèi)置固件的USB設(shè)備方式,說(shuō)明書(shū)中有定義 */ // for ( ;; ) { /* 等待操作成功,通常需要等待10uS-20uS */ // if ( CH375_RD_DAT_PORT( )==CMD_RET_SUCCESS ) break; // } } //串口發(fā)送程序,用于監(jiān)視程序運(yùn)行情況; void Uart_send( unsigned char i ) { TI=0; SBUF=i; while(TI==0); TI=0; } //********************************************************* //端點(diǎn)0數(shù)據(jù)上傳;CH375有端點(diǎn)0、1、2等緩沖區(qū)與計(jì)算機(jī)通訊,個(gè)緩沖區(qū)大小不一樣;詳細(xì)見(jiàn)CH375說(shuō)明書(shū); void mCh375Ep0Up(){ unsigned char i,len; if(mVarSetupLength){ //長(zhǎng)度不為0傳輸具體長(zhǎng)度的數(shù)據(jù) if(mVarSetupLength<=8){ len=mVarSetupLength; mVarSetupLength=0; } //長(zhǎng)度小于8則長(zhǎng)輸要求的長(zhǎng)度 else{ len=8; mVarSetupLength-=8; } //長(zhǎng)度大于8則傳輸8個(gè),切總長(zhǎng)度減8 CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //發(fā)出寫端點(diǎn)0的命令 CH375_WR_DAT_PORT(len); //寫入長(zhǎng)度 for(i=0;i!=len;i++) CH375_WR_DAT_PORT(request.buffer[i]); //循環(huán)寫入數(shù)據(jù) } else{ CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //發(fā)出寫端點(diǎn)0的命令 CH375_WR_DAT_PORT(0); //上傳0長(zhǎng)度數(shù)據(jù),這是一個(gè)狀態(tài)階段
} } //********************************************************* //復(fù)制描述符以便上傳 void mCh375DesUp(){ unsigned char k; for (k=0; k!=8; k++ ) { request.buffer[k]=*VarSetupDescr; //依次復(fù)制8個(gè)描述符, VarSetupDescr++; } } /* CH375中斷服務(wù)程序INT0,使用寄存器組1 */ void mCH375Interrupt( ) //interrupt 0 using 1 { unsigned char InterruptStatus; unsigned char length, c1, len; unsigned char mBuf[8]; CH375_WR_CMD_PORT(CMD_GET_STATUS); /* 向CH375芯片發(fā)送獲取中斷狀態(tài)的命令;CMD_GET_STATUS為命令碼,數(shù)值大小在CH375INC.H 頭文件中*/ InterruptStatus =CH375_RD_DAT_PORT(); /* 讀取中斷狀態(tài) */ switch(InterruptStatus){ // 分析中斷狀態(tài), case USB_INT_EP2_OUT: // 批量端點(diǎn)下傳成功 C
你還是沒(méi)理解我給你說(shuō)的 你就是做一個(gè)鍵盤,測(cè)試很簡(jiǎn)單,你打開(kāi)一個(gè)TXT文件,在你的硬件上做一個(gè)按鍵,按一個(gè)鍵傳一個(gè)鍵碼,不就可以測(cè)試出來(lái)了嗎?
我是按你說(shuō)的方法進(jìn)行測(cè)試的。開(kāi)始的測(cè)試只是測(cè)試電路是不是正確的,驅(qū)動(dòng)是CH372DRV,單片機(jī)里面的程序我沒(méi)有貼出來(lái),是另外的程序。 為了不讓大家誤解,我卸載了CH37DRV.讓后把上面8樓的程序燒到單片機(jī)里面。 當(dāng)我重新把CH375通過(guò)USB線和電腦連接起來(lái),發(fā)現(xiàn)單片機(jī)接收4次中斷,都是0x07,也就是總線復(fù)位,再過(guò)5秒鐘左右又開(kāi)始中斷2次,再過(guò)大約5秒鐘又總線復(fù)位2次,再中斷2次,再過(guò)大約5秒鐘又總線復(fù)位2次。再過(guò)大約5秒鐘設(shè)備管理器中通用串行總線控制器目錄下出現(xiàn)未知設(shè)備(Unknow Device)。 Unknow Device沒(méi)有驅(qū)動(dòng),我把這個(gè)設(shè)備卸載之后,再重新連接一下,依然會(huì)出現(xiàn)上述現(xiàn)象,但不同的是,最后電腦屏幕右下方發(fā)現(xiàn)新硬件,最后還出現(xiàn)硬件可以使用。
首先為什么總是總線復(fù)位呢? 然后為什么硬件可以使用?