[求助]CH374無(wú)法識(shí)別

小弟的下位機(jī)系統(tǒng)配置如下LPC2132+CH374S實(shí)現(xiàn)USB device,24M晶體,電源3.3V,使用硬件SPI連接。現(xiàn)在已經(jīng)可以正確寫(xiě)入寄存器值,如可以更改CKO,使用CH374EVT中\(zhòng)pub\exam\device下面的代碼,只對(duì)硬件相關(guān)的代碼做了改動(dòng)。初始化374后立即進(jìn)入中斷,讀出中斷狀態(tài)字0xC4,然后根據(jù)終端服務(wù)程序374進(jìn)入休眠狀態(tài)。插入U(xiǎn)SB,又進(jìn)入中斷,讀出中斷狀態(tài)字0xDF,然后374鎖死,中斷線一直為0,PC顯示無(wú)法識(shí)別USB設(shè)備。插入U(xiǎn)SB后大約10秒PC出現(xiàn)無(wú)法識(shí)別的提示,這中間用示波器觀察D+ D-會(huì)看到有波形。

請(qǐng)問(wèn)中斷狀態(tài)字是不是不正確?可能是哪種原因?望前輩不吝賜教

剛開(kāi)始會(huì)進(jìn)入復(fù)位中斷,然后進(jìn)入休眠,喚醒,再進(jìn)入傳輸完成中斷, 再初試化時(shí)要把所有的中斷清除掉,然后進(jìn)入每個(gè)中斷后都要清除,不知道您這樣做了沒(méi) 可以把您的程序貼出來(lái)看看.


void Init374Device( void ) // 初始化USB設(shè)備 { Read374Byte(REG_SYS_INFO); Write374Byte( REG_USB_ADDR, 0x00 ); Write374Byte( REG_USB_SETUP, 0x00 ); Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) ); Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) ); Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清所有中斷標(biāo)志 Write374Byte( REG_INTER_EN, BIT_IE_TRANSFER | BIT_IE_BUS_RESET | BIT_IE_USB_SUSPEND |0x20); // 允許傳輸完成中斷和USB總線復(fù)位中斷以及USB總線掛起中斷,芯片喚醒完成中斷 Write374Byte( REG_SYS_CTRL, BIT_CTRL_OE_POLAR | BIT_CTRL_USB_POWER ); // 對(duì)于CH374T或者UEN引腳懸空的CH374S必須置BIT_CTRL_OE_POLAR為1 Write374Byte( REG_USB_SETUP, BIT_SETP_TRANS_EN | BIT_SETP_PULLUP_EN | BIT_SETP_LED_ACT); // 啟動(dòng)USB設(shè)備 }

void __irq IRQ_Eint0 (void) {

UINT8 s, l; // static UINT8 SetupReq, SetupLen; // static PUINT8 pDescr; UINT8 SetupReq, SetupLen; unsigned char *pDescr; s = Read374Byte( REG_INTER_FLAG ); // 獲取中斷狀態(tài) if ( s & BIT_IF_BUS_RESET ) { // USB總線復(fù)位 Write374Byte( REG_USB_ADDR, 0x00 ); // 清USB設(shè)備地址 Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) ); Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) ); Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_BUS_RESET ); // 清中斷標(biāo)志 } else if ( s & BIT_IF_TRANSFER ) { // USB傳輸完成 s = Read374Byte( REG_USB_STATUS ); switch( s & BIT_STAT_PID_ENDP ) { // USB設(shè)備中斷狀態(tài) case USB_INT_EP2_OUT: { // 批量端點(diǎn)下傳成功 UINT8 buf[64]; if ( s & BIT_STAT_TOG_MATCH ) { // 僅同步包 l = Read374Byte( REG_USB_LENGTH ); Read374Block( RAM_ENDP2_RECV, l, buf ); for ( s = 0; s < l; s ++ ) buf[s] ^= 0xFF; // 數(shù)據(jù)取反由計(jì)算機(jī)驗(yàn)證 Write374Block( RAM_ENDP2_TRAN, l, buf ); // 演示回傳 Write374Byte( REG_USB_LENGTH, l ); Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG ); // Write374Index( REG_USB_ENDP2 ); // 對(duì)于并口連接可以用本行及下面一行代替上一行的程序,減少寫(xiě)一次index的時(shí)間,提高效率 // Write374Data( M_SET_EP2_TRAN_ACK( Read374Data0( ) ) ^ BIT_EP2_RECV_TOG ); } break; } case USB_INT_EP2_IN: { // 批量端點(diǎn)上傳成功,未處理 Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_TRAN_TOG ); // Write374Index( REG_USB_ENDP2 ); // 對(duì)于并口連接可以用本行及下面一行代替上一行的程序,減少寫(xiě)一次index的時(shí)間,提高效率 // Write374Data( M_SET_EP2_TRAN_NAK( Read374Data0( ) ) ^ BIT_EP2_TRAN_TOG ); break; } case USB_INT_EP1_IN: { // 中斷端點(diǎn)上傳成功,未處理 Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) ^ BIT_EP1_TRAN_TOG ); break; } case USB_INT_EP0_SETUP: { // 控制傳輸 USB_SETUP_REQ SetupReqBuf; l = Read374Byte( REG_USB_LENGTH ); if ( l == sizeof( USB_SETUP_REQ ) ) { Read374Block( RAM_ENDP0_RECV, l, (PUINT8)&SetupReqBuf ); SetupLen = SetupReqBuf.wLengthL; if ( SetupReqBuf.wLengthH || SetupLen > 0x7F ) SetupLen = 0x7F; // 限制總長(zhǎng)度 l = 0; // 默認(rèn)為成功并且上傳0長(zhǎng)度 if ( ( SetupReqBuf.bType & DEF_USB_REQ_TYPE ) != DEF_USB_REQ_STAND ) { /* 只支持標(biāo)準(zhǔn)請(qǐng)求 */ l = 0xFF; // 操作失敗 } else { // 標(biāo)準(zhǔn)請(qǐng)求 SetupReq = SetupReqBuf.bReq; // 請(qǐng)求碼 switch( SetupReq ) { case DEF_USB_GET_DESCR: switch( SetupReqBuf.wValueH ) { case 1: pDescr = (PUINT8)( &MyDevDescr[0] ); l = sizeof( MyDevDescr ); break; case 2: pDescr = (PUINT8)( &MyCfgDescr[0] ); l = sizeof( MyCfgDescr ); break; case 3: switch( SetupReqBuf.wValueL ) { case 1: pDescr = (PUINT8)( &MyManuInfo[0] ); l = sizeof( MyManuInfo ); break; case 2: pDescr = (PUINT8)( &MyProdInfo[0] ); l = sizeof( MyProdInfo ); break; case 0: pDescr = (PUINT8)( &MyLangDescr[0] ); l = sizeof( MyLangDescr ); break; default: l = 0xFF; // 操作失敗 break; } break; default: l = 0xFF; // 操作失敗 break; } if ( SetupLen > l ) SetupLen = l; // 限制總長(zhǎng)度 l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen; // 本次傳輸長(zhǎng)度 Write374Block( RAM_ENDP0_TRAN, l, pDescr ); /* 加載上傳數(shù)據(jù) */ SetupLen -= l; pDescr += l; break; case DEF_USB_SET_ADDRESS: SetupLen = SetupReqBuf.wValueL; // 暫存USB設(shè)備地址 break; case DEF_USB_GET_CONFIG: Write374Byte( RAM_ENDP0_TRAN, UsbConfig ); if ( SetupLen >= 1 ) l = 1; break; case DEF_USB_SET_CONFIG: UsbConfig = SetupReqBuf.wValueL; break; case DEF_USB_CLR_FEATURE: if ( ( SetupReqBuf.bType & 0x1F ) == 0x02 ) { // 不是端點(diǎn)不支持 switch( SetupReqBuf.wIndexL ) { case 0x82: Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) ); break; case 0x02: Write374Byte( REG_USB_ENDP2, M_SET_EP2_RECV_ACK( Read374Byte( REG_USB_ENDP2 ) ) ); break; case 0x81: Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) ); break; case 0x01: Write374Byte( REG_USB_ENDP1, M_SET_EP1_RECV_ACK( Read374Byte( REG_USB_ENDP1 ) ) ); break; default: l = 0xFF; // 操作失敗 break; } } else l = 0xFF; // 操作失敗 break; case DEF_USB_GET_INTERF: Write374Byte( RAM_ENDP0_TRAN, 0 ); if ( SetupLen >= 1 ) l = 1; break; case DEF_USB_GET_STATUS: Write374Byte( RAM_ENDP0_TRAN, 0 ); Write374Byte( RAM_ENDP0_TRAN + 1, 0 ); if ( SetupLen >= 2 ) l = 2; else l = SetupLen; break; default: l = 0xFF; // 操作失敗 break; } } } else l = 0xFF; // 操作失敗 if ( l == 0xFF ) { // 操作失敗 Write374Byte( REG_USB_ENDP0, M_SET_EP0_RECV_STA( M_SET_EP0_TRAN_STA( 0 ) ) ); // STALL } else if ( l <= RAM_ENDP0_SIZE ) { // 上傳數(shù)據(jù) Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ), l ) | BIT_EP0_TRAN_TOG ); // DATA1 } else { // 下傳數(shù)據(jù)或其它 Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ) ) | BIT_EP0_RECV_TOG ); // DATA1 } break; } case USB_INT_EP0_IN: { switch( SetupReq ) { case DEF_USB_GET_DESCR: l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen; // 本次傳輸長(zhǎng)度 Write374Block( RAM_ENDP0_TRAN, l, pDescr ); /* 加載上傳數(shù)據(jù) */ SetupLen -= l; pDescr += l; Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( Read374Byte( REG_USB_ENDP0 ), l ) ^ BIT_EP0_TRAN_TOG ); break; case DEF_USB_SET_ADDRESS: Write374Byte( REG_USB_ADDR, SetupLen ); default: Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); // 結(jié)束 break; } break; } case USB_INT_EP0_OUT: { switch( SetupReq ) { // case download: // get_data; // break; case DEF_USB_GET_DESCR: default: Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); // 結(jié)束 break; } break; } default: { break; } } Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); // 清中斷標(biāo)志 } else if ( s & BIT_IF_USB_SUSPEND ) { // USB總線掛起 Write374Byte( REG_INTER_FLAG, BIT


程序中沒(méi)有調(diào)試輸出,您是怎么知道中斷狀態(tài)值的?是仿真的么?若是,那么不要單步,全速跑試試


UINT8 SetupReq, SetupLen; unsigned char *pDescr;

要么設(shè)置為全局變量,要么設(shè)置為靜態(tài)的,修改后估計(jì)會(huì)成功.


我用的開(kāi)發(fā)環(huán)境是ADS1.2,原先這兩個(gè)變量都是靜態(tài)的。跟蹤發(fā)現(xiàn)似乎程序從未跑到s = Read374Byte( REG_USB_STATUS );這一行,一旦插入U(xiǎn)SB線,中斷程序就會(huì)跑到 else { // 意外的中斷,不可能發(fā)生的情況,除了硬件損壞這一行,會(huì)不會(huì)是硬件方面的問(wèn)題呢?


可能與你的硬件有關(guān)系,可以做一下讀寫(xiě)RAM測(cè)試. 你讀出來(lái)的中斷值是多少?


按照紅桃六前輩所說(shuō)的,改成全局變量就好啦!感謝指導(dǎo)??磥?lái)ADS里面靜態(tài)變量和全局變量還不能混用呵呵


還發(fā)現(xiàn)一個(gè)問(wèn)題,不僅僅是變量類型,這個(gè)中斷響應(yīng)一定要特別的快,正如SMC所說(shuō)。用11MHz的CPU主頻跑WCH的傳輸測(cè)試程序根本跑不動(dòng),兩個(gè)包之后就死掉,后來(lái)把CPU速度倍頻到55M,最多3000個(gè)包就會(huì)死掉,后來(lái)把SPI時(shí)鐘速率提高到10M才能穩(wěn)定的跑。


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

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