在USB設(shè)備模式下,批量上傳數(shù)據(jù)量很多時,比如3000字節(jié),偶爾會出現(xiàn)其中的一次64字節(jié)數(shù)據(jù)沒上傳成功的情況,我用的CH374芯片,請各位大神幫忙分析下原因。
按照CH374傳輸給計(jì)算機(jī)的批量傳輸機(jī)制。如果有一次傳輸失敗那么后續(xù)的數(shù)據(jù)是無法上傳的。上傳數(shù)據(jù)需要你先寫數(shù)據(jù)到CH374里面,啟動CH374傳輸,當(dāng)計(jì)算機(jī)將數(shù)據(jù)取走后。CH374產(chǎn)生中斷。此時才可以上傳下一包數(shù)據(jù)。如果還丟數(shù)據(jù)檢查你上位機(jī)軟件。
大家了解USB2.0協(xié)議嗎?我想可能是沒理解透協(xié)議,批量上傳的時候需要同步翻轉(zhuǎn),一般數(shù)據(jù)上傳成功,同步標(biāo)志位會翻轉(zhuǎn),但是在我試了很多次發(fā)現(xiàn)同步翻轉(zhuǎn)標(biāo)志位沒有順利翻轉(zhuǎn)有可能是兩種情況:第一種是數(shù)據(jù)沒傳成功同步標(biāo)志位沒翻轉(zhuǎn),這種情況自動重新上傳沒傳成功的數(shù)據(jù)。另一種情況是傳成功了,但是同步標(biāo)志位沒有翻轉(zhuǎn)(這種情況不知道為什么會出現(xiàn)),這種情況不會再自動上傳數(shù)據(jù),但是在CH374芯片中發(fā)送緩沖區(qū)里面的數(shù)據(jù)沒有更新,導(dǎo)致下次發(fā)的數(shù)據(jù)還是這次的數(shù)據(jù)。不知道有人碰到過這種情況沒有,望大家指教下。
對于CH374芯片上傳數(shù)據(jù),翻轉(zhuǎn)位是在上傳成功之后在進(jìn)行翻轉(zhuǎn)。也就是說只要前一包數(shù)據(jù)上傳成功,那么CH374一定會產(chǎn)生中斷。產(chǎn)生中斷之后就需要進(jìn)行翻轉(zhuǎn)。
煩請看下我的上傳程序握手包和同步翻轉(zhuǎn)應(yīng)該都沒問題吧?我用的DEBUG372調(diào)試面板,傳數(shù)過程中偶爾會出現(xiàn):當(dāng)我點(diǎn)擊上傳時數(shù)據(jù)沒有讀上來,但是進(jìn)入了該中斷,當(dāng)程序運(yùn)行到清CH374所有中斷標(biāo)志位時,數(shù)據(jù)就讀出來了,然后又自動進(jìn)入這個上傳成功中斷。
下面的程序第一次有初始化RAM_ENDP2_TRAN。
case USB_INT_EP2_IN: //批量端點(diǎn)上傳成功 { if(_TransLenth > RAM_ENDP2_SIZE)//數(shù)據(jù)大于64字節(jié) { _Lenth = _TransLenth >= RAM_ENDP2_SIZE ? RAM_ENDP2_SIZE : _TransLenth; Write_CH374_D_Reg( REG_USB_LENGTH, _Lenth ); Write_CH374_D_Buffer( RAM_ENDP2_TRAN, _Lenth, pData ); _TransLenth -= _Lenth; pData += _Lenth; Write_CH374_D_Reg( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read_CH374_D_Reg( REG_USB_ENDP2 ) ) ^ CH374_EP2_TRAN_TOG); } else { if( _TransLenth != 0 ) { _Lenth = _TransLenth >= RAM_ENDP2_SIZE ? RAM_ENDP2_SIZE : _TransLenth; Write_CH374_D_Reg( REG_USB_LENGTH, _Lenth ); Write_CH374_D_Buffer( RAM_ENDP2_TRAN, _Lenth, pData ); Write_CH374_D_Reg( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read_CH374_D_Reg( REG_USB_ENDP2 ) ) ^ CH374_EP2_TRAN_TOG); _TransLenth = 0; _Lenth = 0; } else { Write_CH374_D_Reg( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read_CH374_D_Reg( REG_USB_ENDP2 ) )^ CH374_EP2_TRAN_TOG ); } } break; }
程序退出中斷程序前清所有中斷。
上面的程序發(fā)上去有點(diǎn)亂 請看這個
case USB_INT_EP2_IN: //批量端點(diǎn)上傳成功 { if(_TransLenth > RAM_ENDP2_SIZE)//數(shù)據(jù)大于64字節(jié) { _Lenth = _TransLenth >= RAM_ENDP2_SIZE ? RAM_ENDP2_SIZE : _TransLenth; Write_CH374_D_Reg( REG_USB_LENGTH, _Lenth ); Write_CH374_D_Buffer( RAM_ENDP2_TRAN, _Lenth, pData ); _TransLenth -= _Lenth; pData += _Lenth; Write_CH374_D_Reg( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read_CH374_D_Reg( REG_USB_ENDP2 ) ) ^ CH374_EP2_TRAN_TOG); } else { if( _TransLenth != 0 ) { _Lenth = _TransLenth >= RAM_ENDP2_SIZE ? RAM_ENDP2_SIZE : _TransLenth; Write_CH374_D_Reg( REG_USB_LENGTH, _Lenth ); Write_CH374_D_Buffer( RAM_ENDP2_TRAN, _Lenth, pData ); Write_CH374_D_Reg( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read_CH374_D_Reg( REG_USB_ENDP2 ) ) ^ CH374_EP2_TRAN_TOG); _TransLenth = 0; _Lenth = 0; } else { Write_CH374_D_Reg( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read_CH374_D_Reg( REG_USB_ENDP2 ) )^ CH374_EP2_TRAN_TOG ); } } break; }
沒什么問題,你的程序,查查別的什么原因
有沒有可能是我上個包計(jì)算機(jī)接收了,設(shè)備清中斷沒清成功,導(dǎo)致下次直接再次進(jìn)入中斷,而數(shù)據(jù)并沒有傳成功,請問如果是這種情況,會是硬件上的問題嗎?因?yàn)檫@種情況并不是每次都有,只是偶爾會在傳數(shù)過程中出現(xiàn)。
如果是這種情況的話,你可以每次檢測下中斷標(biāo)志寄存器的值,看中斷有沒有正真被清除。你可以對中斷次數(shù)做個統(tǒng)計(jì),如果中斷次數(shù)和上傳的包數(shù)一樣的話很有可能是上位機(jī)接收有問題
我測試過了,在清完中斷寄存器后讀中斷標(biāo)志,然后累加清除的中斷次數(shù),每次中斷都是清除成功了的,但是DEBUG732讀上來的數(shù)會少,難道DEBUG372調(diào)試面板的程序有問題嗎?我試過我搭檔寫的上位機(jī)程序,總是會在CH375WriteData和CH375ReadData這兩個地方程序就執(zhí)行不下去了,情況綜合起來看可能是哪里的問題呢?
中斷次數(shù)和發(fā)送的報(bào)數(shù)一樣么?想個辦法檢測下數(shù)據(jù),USB分析儀有么?先把問題找到
我大致發(fā)現(xiàn)問題了,在我程序里面加了對同步標(biāo)志位是否翻轉(zhuǎn)的測試,進(jìn)入批量傳輸成功中斷里面開始會讀一次翻轉(zhuǎn)位,再在結(jié)束的地方讀一次翻轉(zhuǎn)位,發(fā)現(xiàn)翻轉(zhuǎn)位有時并未翻轉(zhuǎn)成功。但是只要進(jìn)入了傳輸完成中斷,都會翻轉(zhuǎn)發(fā)送同步標(biāo)志位,請問這是因?yàn)橛布栴}沒把同步標(biāo)志位寫下去嗎?另外每次批量上傳數(shù)據(jù)之初同步標(biāo)志位必須是0吧,所以上傳次數(shù)必須要保證是偶數(shù)次。
中斷次數(shù)和發(fā)送的包數(shù)是一樣的,同步翻轉(zhuǎn)次數(shù)卻少了
計(jì)算機(jī)或者上位機(jī)是不可能改變CH374端點(diǎn)2控制寄存器發(fā)送同步標(biāo)志位的值的吧?
計(jì)算機(jī)不改變CH374設(shè)備寄存器的值的,計(jì)算機(jī)就是負(fù)責(zé)讀寫數(shù)據(jù)