2012-09-08 87 views
1

我在PIC24HJ256GP610A上的I2C模塊出現問題。我的代碼(請參閱下面的代碼片段)在PIC24HJ256GP610上運行得非常好[請注意:不是610A]。我正在使用I2C總線與DS1374 RTCC進行通信。但是在610A上,當嘗試使用I2C向RTCC寫入值時輪詢ACKSTAT位時,它會卡住。此外,大多數時候,通過I2C讀取值時RTCC值不會遞增(有時它確實應該增加)。有任何想法嗎?在處理I2C模塊的610和610A之間是否存在配置位/模式/設置差異?我嘗試過切換RTCC芯片,並且切換出處理器。所以,這裏唯一的區別是I2C通訊適用於610,而不是610A。PIC24HJ256GP610/610A差異引起的RTCC I2C讀/寫問題?

610和610A有什麼區別? 610是否已經不再生產,或將繼續生產?

有幾件事情我已經實驗時,探測到的信號,並與調試器步進經過注意到:

1)。 I2C時鐘無限期地在要發送的第20個傳輸位上變高,如果我暫停調試器,則它將停止輪詢ACKSTAT位。第一位看起來是起始位,然後是9位,然後是另一個起始/停止位,然後是9位,然後時鐘線變高。 2)。當時鍾線卡住並使用監視窗口時,I2C1STATbits寄存器中的值爲0x8008,這意味着從從器件接收到NACK,並且最後檢測到啓動(或重複啓動)位。 3)。我總是可以從610和610A讀取從設備(RTCC)。但是,有時610A的值不會增加,而會停留在某個整數值。我相信,當我切斷一切權力並重新編程一切時,RTCC值會發生變化。有時在讀取數值時它保持不變,並且可能有25%的時間實際發生變化,因爲它應該在讀取數值的時候變化。 4)。我無法使用610A通過I2C向RTCC寫入任何內容。處理器卡住輪詢ACKSTAT位(我假設它是因爲它從RTCC收到一個NACK)。610的工作原理非常完美。

工具:MPLAB v8.86,C30 V3.31,ICD3

謝謝 布拉德

//Write RTCC Register: This functions writes a Byte to the DS1374 RTCC 
void Write_RTCC_Register(int Register, unsigned char Byte 
{ 
    unsigned int config2, config1; 
    /* Baud rate is set for 100 Khz */ 
    config2 = 0x97; 
    /* Configure I2C for 7 bit address mode */ 
    config1 = (I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_HLD & 
      I2C1_IPMI_DIS & I2C1_7BIT_ADD & 
      I2C1_SLW_DIS & I2C1_SM_DIS & 
      I2C1_GCALL_DIS & I2C1_STR_DIS & 
      I2C1_NACK & I2C1_ACK_DIS & I2C1_RCV_DIS & 
      I2C1_STOP_DIS & I2C1_RESTART_DIS & 
      I2C1_START_DIS); 

OpenI2C1(config1,config2); 
IdleI2C1(); 
StartI2C1(); 

//Configure RTCC 
//Wait till Start sequence is completed 
while(I2C1CONbits.SEN); 
//Clear interrupt flag 
IFS1bits.MI2C1IF = 0; 
//Write Slave address and set master for transmission 
MasterWriteI2C1(0xD0); 
//Wait till address is transmitted 
while(I2C1STATbits.TBF); // 8 clock cycles 
while(!IFS1bits.MI2C1IF); // Wait for 9th clock cycle 
IFS1bits.MI2C1IF = 0;  // Clear interrupt flag 
while(I2C1STATbits.ACKSTAT);    

OpenI2C1(config1,config2); 
IdleI2C1(); 
StartI2C1(); 
//Wait till Start sequence is completed 
while(I2C1CONbits.SEN); 

//Clear interrupt flag 
IFS1bits.MI2C1IF = 0; 
//Write Slave address and set master for transmission 
MasterWriteI2C1(Register); 

//Wait till address is transmitted 
while(I2C1STATbits.TBF); // 8 clock cycles 
while(!IFS1bits.MI2C1IF); // Wait for 9th clock cycle 

IFS1bits.MI2C1IF = 0;  // Clear interrupt flag 

***while(I2C1STATbits.ACKSTAT); //problem here*** 


//Clear interrupt flag 
IFS1bits.MI2C1IF = 0; 
//Write Slave address and set master for transmission 
MasterWriteI2C1(Byte); 
//Wait till address is transmitted 
while(I2C1STATbits.TBF); // 8 clock cycles 
while(!IFS1bits.MI2C1IF); // Wait for 9th clock cycle 
IFS1bits.MI2C1IF = 0;  // Clear interrupt flag 
while(I2C1STATbits.ACKSTAT); 

StopI2C1(); 
//Wait till stop sequence is completed 
while(I2C1CONbits.PEN); 
CloseI2C1(); 
}; //Write RTCC Register 

回答

1

我發現這個問題。我重新啓用了I2C模塊,並在「... ACKSTAT」之上幾行聲明瞭一個不必要的啓動條件; //這裏是「代碼行」。重新啓用模塊似乎沒有什麼區別,這是重新啓用開始狀態位是問題。

我不知道爲什麼它可以與610而不是610A一起工作。無論如何,問題解決了!

... 
... 
... 
//**DELETED** OpenI2C1(config1,config2); 
//**DELETED** IdleI2C1(); 
//**DELETED** StartI2C1(); 
////**DELETED** Wait till Start sequence is completed 
//**DELETED** while(I2C1CONbits.SEN); 

//Clear interrupt flag 
IFS1bits.MI2C1IF = 0; 
//Write Slave address and set master for transmission 
MasterWriteI2C1(Register); 

//Wait till address is transmitted 
while(I2C1STATbits.TBF); // 8 clock cycles 
while(!IFS1bits.MI2C1IF); // Wait for 9th clock cycle 

IFS1bits.MI2C1IF = 0;  // Clear interrupt flag 

while(I2C1STATbits.ACKSTAT); // ** problem no more! 
... 
... 
...