Forum: Mikrocontroller und Digitale Elektronik 89C52 - I2C HILFE...


von Nickl (Gast)


Lesenswert?

Hallo erstmal!

Wir haben derzeit ein Projekt am laufen, mit dem Thema
Temperaturmessung über I2C mit dem  LM75 Baustein.
Jedoch hat unser Controller (AT89C52) keinen Integrieren I2C bus.
Wir haben also einen I2C-"Simulator" - Source verwendet :
http://www.smartdata.com.au/8051/i2c_sw.zip
Port1.

Jetzt haben wir das Problem, dass das Hinausschrieben auf den Baustein
zwar funktioniert, wir jedoch kein ACK vom Sensor bekommen.
Sichheitshalber haben wir es mit einem I2C-I/O - Expander probiert, der
funktioniert, wissen aber nicht, ob der ein ACK zurücksendet ?!

Hat irgendwer eine Idee ?
lg HonZ, Nickl

von plitzi (Gast)


Lesenswert?

Jeder I2C-Baustein muss auf seine (eingestellte) Adresse ein ACK geben,
egal ob ein Schreib- oder Lesezugriff vom Master erfolgen soll. Also
ersteinmal nur die Adresse ausgeben und kontrollieren, ob der Slave
bestätigt hat. Ohne das ACK geht gar nichts. Gesebdete Adresse
kontrollieren, ggf. mehrer ausprobieren, falls mehrere am Slave möglich
sind.

Jörg

von Nickl (Gast)


Lesenswert?

Hi, danke für die Antwort, das ist eben das Problem, wir bekommen kein
ACK. Auch mit nur einem Slave, die Adressen stimmen.
Ich glaube, dass irgenwie das einlesen vom Port1 am µP nicht
funktioniert. Doch wir haben alles versucht, zusätzlich noch einen
PullUp geschaltet. Aber keine Chance...

lg niki

von Jim (Gast)


Lesenswert?

Poste doch mal die Schaltung und den I2C-Source.

von Nickl (Gast)


Lesenswert?

Schaltung:
http://ourworld.compuserve.com/homepages/Dominique_CHARLET/8051.gif
(i2c - im Bild links unten)
habs auch ohne widerstände versucht.... keine Chance etwas
einzulesen... kein ACK, nix...




Source:


#ifndef READ
    #define READ   1
#endif

#ifndef WRITE
    #define WRITE  0
#endif

#ifndef I2CCLK
    #define I2CCLK 0xA0
#endif

#ifndef SCL
    static bit SCL  @ 0x96;
#endif

#ifndef SDA
    static bit SDA  @ 0x97;
#endif

unsigned char _i2c_error;      // bit array of error types

void          _I2CBitDly(void);
void          _I2CSCLHigh(void);
void           I2CSendAddr(unsigned char addr, unsigned char rd);
void           I2CSendByte(unsigned char bt);
unsigned char _I2CGetByte(unsigned char lastone);
void           I2CSendStop(void);
#define I2CGetByte()     _I2CGetByte(0)
#define I2CGetLastByte() _I2CGetByte(1)

void _I2CBitDly(void)         // wait 4.7uS, or thereabouts
{                             // tune to xtal. This works at
11.0592MHz
  asm("   NOP");              // delay is 5.4uS, only 4.3uS without
  return;
}

void _I2CSCLHigh(void)        // set SCL high, and wait for it to go
high
{
  register int err;
  SCL = 1;
  while (! SCL)
  {
    err++;
    if (!err)
    {
      _i2c_error &= 0x02;     // SCL stuck, something's holding it
down
      return;
    }
  }
}

void I2CSendAddr(unsigned char addr, unsigned char rd)
{
  SCL = 1;
  _I2CBitDly();
  SDA = 0;               // generate start
  _I2CBitDly();
  SCL = 0;
  _I2CBitDly();
  I2CSendByte(addr+rd);  // send address byte
}

void I2CSendByte(unsigned char bt)
{
  register unsigned char i;
  for (i=0; i<8; i++)
  {
    if (bt & 0x80) SDA = 1;      // send each bit, MSB first
    else SDA = 0;
    _I2CSCLHigh();
    _I2CBitDly();
    SCL = 0;
    _I2CBitDly();
    bt = bt << 1;
  }
  SDA = 1;                       // listen for ACK
  _I2CSCLHigh();
  _I2CBitDly();
  if (SDA)
    _i2c_error &= 0x01;          // ack didn't happen, may be nothing
out there
  SCL = 0;
  _I2CBitDly();
}

unsigned char _I2CGetByte(unsigned char lastone) // lastone == 1 for
last byte
{
  register unsigned char i, res;
  res = 0;
  for (i=0;i<8;i++)          // each bit at a time, MSB first
  {
    _I2CSCLHigh();
    _I2CBitDly();
    res *= 2;
    if (SDA) res++;
    SCL = 0;
    _I2CBitDly();
  }
  SDA = lastone;             // send ACK according to 'lastone'
  _I2CSCLHigh();
  _I2CBitDly();
  SCL = 0;
  SDA = 1;
  _I2CBitDly();
  return(res);
}

void I2CSendStop(void)
{
  SDA = 0;
  _I2CBitDly();
  _I2CSCLHigh();
  _I2CBitDly();
  SDA = 1;
  _I2CBitDly();
}

// test code
//void main(void)
//{
//  unsigned char b;
//  I2CSendAddr(1,WRITE);
//  I2CSendByte(0);
//  I2CSendStop();
//  I2CSendAddr(1,READ);
//  b = I2CGetByte();
//  b = I2CGetLastByte();
//  I2CSendStop();
//}

/

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.