1

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
4

1 に答える 1

1

問題が見つかりました。I2C モジュールを再度有効にして、コードの "...ACKSTAT); //problem here" 行の数行上で不要な開始条件をアサートしていました。モジュールを再度有効にしても違いはないようです。問題は開始条件ビットの再アサートでした。

610A ではなく 610 で動作する理由がわかりません。とにかく、問題は解決しました!

...
...
...
//**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!
...
...
...
于 2012-09-10T22:34:20.540 に答える