mikrocontroller.net

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


Autor: Nickl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: plitzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Nickl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Poste doch mal die Schaltung und den I2C-Source.

Autor: Nickl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schaltung:
http://ourworld.compuserve.com/homepages/Dominique...
(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();
//}

/

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.