0

私は奇妙な問題に直面しています。PIC16F1459 で常にビット バンギン I2C 機能を使用していましたが、今は MSSP (SPI、I2C マスター スレーブ ペリフェラル) を使用したいと考えています。だから私は、データシート、開始、停止などに従って関数を書き始めました。私が抱えている問題は、PICがI2C EEPROMに送信したデータにACKを返さないことです。ACK ステータスは SSPCON2.ACKSTAT で確認できることがデータシートに明確に記載されています。したがって、スレーブがデータに応答するまでこのビットをポーリングすると推測しましたが、プログラムは while ループでハングします。

 void vReadACK (void)
  {
   while (SSPCON2.ACKSTAT != 0);
  }

そして、これが私の書き込み関数、私の I2CCheck 関数、および I2C マスター初期化関数です。

void vI2CEcrireOctet (UC ucData, UC ucRW)
 {
   vI2CCheck();
   switch (ucRW)
    {
      case READ:
        SSPBUF = ucData + 1;
      break;
      case WRITE:
        SSPBUF = ucData + 0;
      break;
    }
   vReadACK();
 }

void vI2CCheck (void)
 {
   while (SSPCON2.ACKEN);     //ACKEN not cleared, wait
   while (SSPCON2.RCEN);      //RCEN not cleared, wait
   while (SSPCON2.PEN);       //STOP not cleared, wait
   while (SSPCON2.SEN);       //Start not cleared, wait
   while (SSPCON2.RSEN);      //Rep start not cleared, wait
   while (SSP1STAT.R_NOT_W);  //TX not done wait
 }

void vInitI2CMaster (void)
 {
   TRISB4_bit = 1;        //SDA IN
   TRISB6_bit = 1;        //SCL IN
   SSP1STAT.SMP = 1;      //No slew rate
   SSP1STAT.CKE = 0;      //Disable SMBus inputs
   SSPADD = 0x27;         //100 KHz
   SSPCON1 = 0b00101000;  //I2C Master mode
   SSPCON3 = 0b00000000;  //Rien de slave
 }

ご存知のように、24LC32A WriteProtect は VSS に接続され、A2-A1-A0 は GND に接続されているため、アドレスは 0xA0 です。4k7 プルアップは I2C ラインにあります。16MHz INTOSC の PIC16F1459。

私は完全に立ち往生しています。MSSP データシートを 5 ~ 6 回確認しましたが、問題は見つかりませんでした。手伝ってくれませんか?

そして、これが私のロジックアナライザーのプレビューです( vReadAck() 内の while を削除しています)

4

2 に答える 2

0

「PICはI2C EEPROMに送信したデータにACKを送信しない」ことを「完全に知っている」という事実にもかかわらず、想定されていないため、I2C確認応答がどのように機能するかをまだ誤解しているようです。肯定応答 (ACK) と否定応答 (NAK) の両方が可能であるため、肯定応答と呼ばれます。投稿したアナライザーのスクリーンショットを見ると、送信される各バイトが送信機によって NAK されたものとして明確にラベル付けされていることがわかります。

I2C ACK を適切にチェックするには、ビットの後縁をポーリングし、ビットをACKTIMチェックしてACKSTAT、スレーブが ACK または NAK ビットを送信したかどうかを確認する必要があります。このようなもの:

int
vReadACK() {
    while(!SSPCON3.ACKTIM);
    while(SSPCON3.ACKTIM);
    return SSPCON2.ACKSTAT;
}

スレーブデバイスが明らかに各バイトを NAK している理由については、投稿したコードからは明らかではありませんが、コードにはいくつかの顕著な省略があります。開始条件と停止条件を生成する必要がありますが、これを行うコードは示されていません。

于 2014-08-19T00:48:05.023 に答える
0

私の質問に対する答えが見つかったようです。私がしていたことは、これを行う正確な方法でした。問題は、スレーブが応答するために必要な Bus Free Time 遅延にあるようです。16Mhz では、私の I2C はおそらく EEPROM メモリに対して速すぎました。そのため、停止操作の直後に小さな遅延機能を追加したので、書き込みシーケンスが遅延され、BAM が機能しました。

バスの空き時間: 新しい送信を開始する前に、バスが空いていなければならない時間。

于 2014-08-19T00:38:43.117 に答える