PIC24HJ256GP610A の I2C モジュールに問題があります。私のコード (以下のスニペットを参照) は、PIC24HJ256GP610 [注: 610A ではありません] で完全に正常に動作します。DS1374 RTCC との通信に I2C バスを使用しています。しかし、610A では、I2C を使用して RTCC に値を書き込もうとして ACKSTAT ビットをポーリングするとスタックします。また、ほとんどの場合、I2C 経由で値を読み取るときに RTCC 値が増加しません (必要に応じて増加する場合もあります)。何か案は?I2C モジュールを扱う 610 と 610A の間でコンフィグ ビット/モード/設定の違いはありますか? RTCC チップを交換して、プロセッサを交換してみました。したがって、ここでの唯一の違いは、I2C 通信が 610 では機能し、610A では機能しないことです。
610 と 610A の違いは何ですか? 610 はもはや製造されていない旧式の部品ですか、それとも製造され続ける予定ですか?
実験、信号の調査、デバッガーのステップ実行中に気付いたことがいくつかあります。
1)。I2C クロックは、20 番目の送信ビットで無期限に高くなり、デバッガーを一時停止すると ACKSTAT ビットのポーリングで停止します。最初のビットがスタート ビットのように見え、次にさらに 9 ビット、別のスタート/ストップ ビット、さらに 9 ビットが続き、クロック ラインが High になります。
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