又來(lái)麻煩hcn了:
take_pin();//先發(fā)送令牌 do{ if(CH375_INT_WIRE==0) intt0(); //接收數(shù)據(jù) } while(1);
請(qǐng)問(wèn)為什么我接上掃描槍后,執(zhí)行程序,即使令上面程序段(main函數(shù)中一部分)中CH375_INT_WIRE==1,程序仍會(huì)運(yùn)行到intt0()中呢? 這個(gè)中斷好象不管用???
又來(lái)麻煩hcn了:
take_pin();//先發(fā)送令牌 do{ if(CH375_INT_WIRE==0) intt0(); //接收數(shù)據(jù) } while(1);
請(qǐng)問(wèn)為什么我接上掃描槍后,執(zhí)行程序,即使令上面程序段(main函數(shù)中一部分)中CH375_INT_WIRE==1,程序仍會(huì)運(yùn)行到intt0()中呢? 這個(gè)中斷好象不管用???
你是怎么知道在中斷腳為高的時(shí)候還會(huì)執(zhí)行下面的函數(shù)呢?
hcn: 是這樣的,我在下面的一個(gè)子函數(shù)里設(shè)置了斷點(diǎn),發(fā)現(xiàn)最后程序運(yùn)行到那個(gè)地方停止。這不能說(shuō)明么?
實(shí)際上是這樣的,上面的發(fā)送令牌的函數(shù)發(fā)送完成之后,在下面的循環(huán)就一直等待設(shè)備給主機(jī)來(lái)中斷,如果沒(méi)中斷的話就一直在那循環(huán),你在 CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 產(chǎn)生操作完成中斷, 獲取中斷狀態(tài) */ 命令之前設(shè)置一個(gè)斷點(diǎn),在程序運(yùn)行到這個(gè)之前的時(shí)候,你測(cè)下375的INT腳為低電平嗎? 在這個(gè)命令之后,375就將INT#腳由低電平變?yōu)楦唠娖搅耍栽诤竺娴牟僮鞯臅r(shí)候,INT#腳的電壓都是高電平
hcn: 這個(gè)我是知道的,現(xiàn)在有這么一個(gè)問(wèn)題: USB鍵盤程序里好像看不到鍵盤數(shù)據(jù)在何時(shí)被接收? void intt0() { unsigned char len_temp,status,i; unsigned char *BUF=buffer_r; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 產(chǎn)生操作完成中斷, 獲取中斷狀態(tài) */ status=CH375_RD_DAT_PORT();//printf("%02x ",(unsigned int)status);printf("\n"); if(status!=USB_INT_SUCCESS)//&&((status&0xf0)==0x20)) { CH375_WR_CMD_PORT( CMD_CLR_STALL );//printf("13\n"); CH375_WR_DAT_PORT(1); /* 如果設(shè)備端不是CH37X芯片,那么需要修改端點(diǎn)號(hào) */ toggle_recv(1); issue_token_s(( endp_int << 4 ) | DEF_USB_PID_IN);//發(fā)送從中斷端點(diǎn)讀數(shù)據(jù)的令牌 } else len_temp=rd_usb_data(buffer_r); //鍵盤中斷端點(diǎn)數(shù)據(jù)長(zhǎng)度一般為8字節(jié),鼠標(biāo)為4字節(jié) for(i=0;i!=8;i++)printf("%02x ",(unsigned int)buffer_r[i]); printf("\n"); // flag_output=0; tank=((~tank)&0x01); toggle_recv(tank); issue_token_s(( endp_int << 4 ) | DEF_USB_PID_IN);//發(fā)送從中斷端點(diǎn)讀數(shù)據(jù)的令牌 }
這個(gè)數(shù)據(jù)接收子函數(shù)里,好像只能看到接收數(shù)據(jù),但似乎看不到判別用鍵盤鍵入數(shù)據(jù)這個(gè)動(dòng)作。
else len_temp=rd_usb_data(buffer_r); //鍵盤中斷端點(diǎn)數(shù)據(jù)長(zhǎng)度一般為8字節(jié),鼠標(biāo)為4字節(jié) 就是接收數(shù)據(jù),因?yàn)殒I盤一次上傳的數(shù)據(jù)就8個(gè)字節(jié),所以直接就可以一次讀出來(lái)就可以了。
hcn: 我的意思是說(shuō)按一下鍵是否能產(chǎn)生中斷,以便于讓系統(tǒng)知道有數(shù)據(jù)了,然后開(kāi)始接收。 如果按您的意思,那系統(tǒng)怎么才能知道有數(shù)據(jù)可以接收呢? 可能我表達(dá)的不盡完整,敘述不到位。
產(chǎn)生了中斷就說(shuō)明有數(shù)據(jù)了,這時(shí)候就可以通過(guò)單片機(jī)來(lái)讀取數(shù)據(jù)了。
hcn: 哪個(gè)地方的中斷表示有數(shù)據(jù)了? 應(yīng)該不是主函數(shù) take_pin(); //先發(fā)送令牌 do{ if(CH375_INT_WIRE==0) intt0(); //接收數(shù)據(jù) }while(1); 中這個(gè)if(CH375_INT_WIRE==0)語(yǔ)句??; 或者是issue_token_s( ( endp_int << 4 ) | DEF_USB_PID_IN );這個(gè)命令嗎? 而在接收數(shù)據(jù)的子函數(shù)intt0()里也沒(méi)看到有這樣的中斷??; 所以我覺(jué)得應(yīng)該是少了一個(gè)等待掃描槍的中斷語(yǔ)句。 不知我的想法對(duì)不對(duì)。
hcn: 是不是這樣,您看對(duì)不對(duì)? take_pin();//先發(fā)送令牌 do{ if(CH375_INT_WIRE==0) intt0(); //接收數(shù)據(jù) }while(1); take_pin();語(yǔ)句發(fā)IN事務(wù)命令,而后if(CH375_INT_WIRE==0)語(yǔ)句判斷是否有數(shù)據(jù)來(lái)中斷對(duì)嗎?
但是有個(gè)問(wèn)題,緊接著在intt0();子函數(shù)里 CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 產(chǎn)生操作完成中斷, 獲取中斷狀態(tài) */ status=CH375_RD_DAT_PORT(); if(status!=USB_INT_SUCCESS) 這幾個(gè)語(yǔ)句是否重復(fù)判斷了?
你仔細(xì)看下芯片資料說(shuō)明,來(lái)了中斷之后,在中斷里面要先讀取中斷狀態(tài),當(dāng)發(fā)送讀取中斷狀態(tài)的命令的時(shí)候,當(dāng)讀取完中斷狀態(tài)之后,375就將中斷引腳拉高,不存在沖突的問(wèn)題,仔細(xì)看芯片資料說(shuō)明,里面有詳細(xì)的讀取中斷的流程
hcn: 那您能指出哪個(gè)中斷是判別來(lái)數(shù)據(jù)的嗎? 麻煩了。 我就是太笨,呵呵。
intt0(); 函數(shù)就是判斷是數(shù)據(jù),前面的中斷都不是
hcn:
void intt0() { unsigned char len_temp,status,i; unsigned char *BUF=buffer_r; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 產(chǎn)生操作完成中斷, 獲取中斷狀態(tài) */ status=CH375_RD_DAT_PORT();//printf("%02x ",(unsigned int)status);printf("\n"); if(status!=USB_INT_SUCCESS)//&&((status&0xf0)==0x20)) { CH375_WR_CMD_PORT( CMD_CLR_STALL );//printf("13\n"); CH375_WR_DAT_PORT(1); /* 如果設(shè)備端不是CH37X芯片,那么需要修改端點(diǎn)號(hào) */ toggle_recv(1); issue_token_s(( endp_int << 4 ) | DEF_USB_PID_IN);//發(fā)送從中斷端點(diǎn)讀數(shù)據(jù)的令牌 } else len_temp=rd_usb_data(buffer_r); //鍵盤中斷端點(diǎn)數(shù)據(jù)長(zhǎng)度一般為8字節(jié),鼠標(biāo)為4字節(jié) for(i=0;i!=8;i++)printf("%02x ",(unsigned int)buffer_r[i]); printf("\n"); // flag_output=0; tank=((~tank)&0x01); toggle_recv(tank); issue_token_s(( endp_int << 4 ) | DEF_USB_PID_IN);//發(fā)送從中斷端點(diǎn)讀數(shù)據(jù)的令牌 }
這里頭的status是不是就是判斷數(shù)據(jù)到了沒(méi)到呢?如果數(shù)據(jù)到了,status就為USB_INT_SUCCESS嗎?然后就開(kāi)始接收數(shù)據(jù),對(duì)嗎?
如果status==USB_INT_SUCCESS就說(shuō)明有數(shù)據(jù)了
hcn: unsigned char len_temp=4; void intt1() { unsigned char status,i,tank=1; unsigned char *BUF=buffer; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 產(chǎn)生操作完成中斷, 獲取中斷狀態(tài) */ status=CH375_RD_DAT_PORT(); while(status!=USB_INT_SUCCESS) { CH375_WR_CMD_PORT( CMD_CLR_STALL ); // CMD_CLR_STALL 主機(jī)方式:控制傳輸-清除端點(diǎn)錯(cuò)誤 CH375_WR_DAT_PORT(1); /* 如果設(shè)備端不是CH37X芯片,那么需要修改端點(diǎn)號(hào) */ toggle_recv(1); issue_token_s(( 1 << 4 ) | DEF_USB_PID_IN);//發(fā)送從中斷端點(diǎn)讀數(shù)據(jù)的令牌 status=CH375_RD_DAT_PORT(); } while(1); len_temp=rd_usb_data(buffer); // USB掃描槍的數(shù)據(jù)包長(zhǎng)度為8個(gè)字節(jié) while(buffer[0]) { tank=((~tank)&0x01); // ~:按位取反;&:按位與 BUF+=0x08; // 意為指針指向buffer數(shù)組8個(gè)字節(jié)后的數(shù)據(jù) toggle_recv( tank ); /* DATA階段 */ _nop_(); _nop_(); while(issue_token( ( 1 << 4 ) | DEF_USB_PID_IN )!=USB_INT_SUCCESS ); { /* SETUP階段操作成功 */ len_temp=rd_usb_data(BUF); buffer[0]=buffer[0]-len_temp; } } // 該循環(huán)是將描述符逐數(shù)據(jù)逐一讀出,存放在buffer數(shù)組中 tank=((~tank)&0x01); toggle_recv(tank); issue_token_s(( 1 << 4 ) | DEF_USB_PID_IN);//發(fā)送從中斷端點(diǎn)讀數(shù)據(jù)的令牌 }
以上是我關(guān)于接收數(shù)據(jù)的子函數(shù),與您給的鍵盤程序略有區(qū)別,麻煩幫我看下有什么問(wèn)題。 通過(guò)有關(guān)軟件得到的配置描述符中的endp_int值為0x81,所以我直接將子函數(shù)中的endp_int值用其代替了。發(fā)現(xiàn)一個(gè)問(wèn)題,就是我的掃描槍不作任何操作的情況下,程序都會(huì)通過(guò) while(status!=USB_INT_SUCCESS) { CH375_WR_CMD_PORT( CMD_CLR_STALL ); // CMD_CLR_STALL 主機(jī)方式:控制傳輸-清除端點(diǎn)錯(cuò)誤 CH375_WR_DAT_PORT(1); /* 如果設(shè)備端不是CH37X芯片,那么需要修改端點(diǎn)號(hào) */ toggle_recv(1); issue_token_s(( 1 << 4 ) | DEF_USB_PID_IN);//發(fā)送從中斷端點(diǎn)讀數(shù)據(jù)的令牌 status=CH375_RD_DAT_PORT(); } 這是為什么呢?
現(xiàn)在接收不到數(shù)據(jù),即使將該部分代碼換成您給的程序里的那段代碼,也仍然接收不到數(shù)據(jù)。
附注:我的掃描槍數(shù)據(jù)包長(zhǎng)度為8個(gè)字節(jié),全速。