Re: I2C的問題
|
||||
---|---|---|---|---|
版主
|
I2C Slave 再接收完一個完整的 Byte 資料時會自動將 SCL 拉Low (Slave進入Busy狀態)直到清除 CKP 位元 SCL 才變 Hi。詳細的 Timming 圖可以參考PIC16F877 的 7-bit I2C Slave receive timming 看看 SCL 的凖位變換情形。
發表於: 2007/6/8 21:55
|
|||
|
Re: I2C的問題
|
||||
---|---|---|---|---|
高級會員
|
請問是否在master端因某些原因拉長了clock的送出(例如送出了6個clock後,第7個clock可能由master延遲了一段時間才送出),就會造成PIC slave端的錯誤??
例如可能sspif中斷旗標不會產生,或是sspov被置1,或是wcol被置1的出現?? 以致於sspbuf無法寫入新的資料,造成ckp置0,scl持續拉為low. 因為我看示波器的波形,在我自己用pic16f873a寫的master與客戶所寫的master上的不同就只有這個地方不一樣,不知道是不是這個關係造成了pic16f873a的slave產生錯誤. 我有試過,如果在主程式裡判斷ckp是否為0,如果為0時就重設I2C,將sspcon<SSPEN>清零並將一些狀態重置後在將sspcon<SSPEN>置1,這樣測試了一個晚上後發現動作還是正常的,所以我現在我換個方式去測,就是在主程式的地方去判斷ckp是否為0,如果為0時就將pir1<SSPIF>置1產生中斷條件,強迫進入中斷中去執行副程式.
發表於: 2007/6/8 11:23
|
|||
|
Re: I2C的問題
|
||||
---|---|---|---|---|
高級會員
|
謝謝kbat524的建議,雖然程式上看起來好像是不會出現這個問題,不過我會去檢查看看是否是因為這樣出現這個問題。
發表於: 2007/6/6 18:31
|
|||
|
Re: I2C的問題
|
||||
---|---|---|---|---|
高級會員
|
slave會一直拉low只有一個可能,就是slave沒有丟出data給master,所以你可以去確認看看,是不是你在丟dtata給master之前,你的buffer是空的了!!
發表於: 2007/6/6 18:24
|
|||
|
Re: I2C的問題
|
||||
---|---|---|---|---|
高級會員
|
謝謝hellowanz的回覆,不過這個方法應該是行不通的,因為他還是需要在每隔0.5s來polling i2c slave來取得資料。我的客戶是跟我說,會出現這種狀況的時候,都是在訪問完address後在準備接收第一筆data時才會有這種情形發生。
發表於: 2007/6/6 18:14
|
|||
|
Re: I2C的問題
|
||||
---|---|---|---|---|
資深會員
|
雖然不是解決根源的方法,不過你可以請他在檢查pull high的地方加入Time Out機制,超過sck兩倍時間就放棄該筆資料,重新再收,這樣子就不會在死迴圈繞。
發表於: 2007/6/6 17:19
|
|||
|
I2C的問題
|
||||
---|---|---|---|---|
高級會員
|
小弟我最近遇到一個在I2C上的問題,就是我用ccs c寫了一個I2C slave 的程式及I2C master的程式個別燒錄在兩顆16f873A中,動作方式是由master發送一個address+R後,接收5筆data,我本身在測試的時候沒有問題,可是送到客戶端時,客戶他用他寫的master(非microchip的mcu)與我的slave做通信時卻發現,有機會將I2C SCL 拉為low而且是一直持續,並且使他的程式進入了死迴圈,然後就得reset電源,而且狀態是隨機出現的,可是小弟自己也在公司用自己寫的master程式,測試了一兩天就是不會有這樣的狀況發生,然後小弟我就去查datasheet上面說明只有在I2C 在準備資料要送出的時候會將SCL 拉為low只有到sspbuf裝好資料並且將ckp置為1時,SCL才會被slave釋放,然後我有稍微瞭解了客戶的程式,當他的程式進入死迴圈時,會先將scl釋放並且一直偵測scl是否pull high,以至於造成了他的程式出不了迴圈,所以當他把scl這條線由他的裝置上拔掉後,他的程式又能正常執行了,由這點來看,會造成這種現象的元兇應該是我寫的slave程式出了問題,可是我卻模擬不了他的狀況,所以想請問各位有沒有遇過這種情形,並且是否有什麼好方法可以解決呢,以下是我slave的程式片段希望給各位參考後能發現什麼問題。
#int_SSP // <-----進入i2c中斷副程式 void SSP_isr(void) { static byte m; if(!bit_test(SSPSTAT,S))//stop?? { if(bit_test(SSPSTAT,R_W))//read?? { if(!bit_test(SSPSTAT,D_A))//address?? { sspbuf=I2C_buf[0]; m=1; } else { sspbuf=I2C_buf[m]; m++; } } } bit_set(SSPCON1,CKP); }
發表於: 2007/6/6 14:23
|
|||
|