Forum: Mikrocontroller und Digitale Elektronik AVR TWI: Hängt nach dem Flaschen


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von Manfred L. (manni)


Lesenswert?

Hallo,

ich habe einen ATmega32 der als Master arbeitet und einen ATmega8 der 
als Slave arbeitet. Die Kommunikation zwischen beiden läuft gänzlich 
ohne Probleme.
Da ich die Software für ATmega32 derzeit noch weiter entwickle, flashe 
ich ihn über das Atmel-Studio 7 mittels eines DIAMEX Programmer.

Jetzt das Problem:
Nach dem Flashen klemmt das TWI Interface, da der Slave anscheinend noch 
was erwartet, was durch das Flashen nicht mehr vom Master geliefert 
wird. Wenn ich die Versorgungsspannung von beiden Controllern aus- und 
wieder einschalte, funktioniert wieder alles wie gewünscht.

Frage: Das Ein- und Ausschalten möchte ich vermeiden. Gibt es eine 
Möglichkeit während des Boot-Vorganges des Masters den TWI Bus so zu 
resetten, dass der Slave das merkt und sich auch resettet ?

Ich bedanke mich schon jetzt für die vielen hifreichen Kommntare !

Gruß Manni

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Es wäre natürlich günstig, wenn du das Problem mit einem Logic Analyzer 
erstmal aufzeichnen und verstehen könntest.

Ansonsten braucht man bei I²C eigentlich immer irgendwo eine 
Rückfallebene über einen Timeout, falls die Kommunikation mal nicht das 
machen sollte, was man erwartet. Theoretisch kann ja beispielsweise auch 
per clock stretching das angeschlossene Gerät sich beliebig lange Zeit 
für eine Reaktion lassen – nach einer bestimmten Zeit sollte der 
Controller dann aber besser „kalte Füße bekommen“ und die gesamte 
Kommunikation als gescheitert betrachten.

von Jochen (hermann_kokoschka)


Lesenswert?

Manfred L. schrieb:
> Gibt es eine
> Möglichkeit während des Boot-Vorganges des Masters den TWI Bus so zu
> resetten, dass der Slave das merkt und sich auch resettet ?

Nein, eine explizite "RESET-CONDITION" gibt es nicht.

Wie Jörg schrieb sollte ein vernünftiges Timeout-Handling in jedem Slave 
vorhanden sein, manchmal hilft es aber auch wenn der Master den Slave 
mit einigen "STOP-CONDITIONS" zutrommelt, was natürlich nur greifen kann 
wenn der Slave des Bus nicht bereits blockiert.

von Steve van de Grens (roehrmond)


Lesenswert?

Google nach "i2c freitakten"

von Oliver S. (oliverso)


Lesenswert?

Steve van de Grens schrieb:
> Google nach "i2c freitakten"

In der reinen Lehre sollte das funktionieren.In der Praxis mit AVRs ist 
ein timeout sicherer.

Oliver

von Manfred L. (manni)


Angehängte Dateien:

Lesenswert?

Hallo,

Eure Kommentare waren Gold wert !

Steve van de Grens schrieb:
> Google nach "i2c freitakten"

Siehe auch: Beitrag "Wie funktioniert das Freitaken bei I2C" vom 22.12.2013 
10:23

Ich habe die NPX Application Note AN19216-01 für das Freitaken des I2C 
Busses verwendet, siehe attached auf Seite 17, und den unten angehängten 
Code eingefügt, bevor das I2C Interface im Master initiiert und 
verwendet wird. Basierend darauf wird der Bus vom "hängenden" Slave 
wieder frei gegeben und die drei angeschlossenen Slaves können dann ohne 
Einschränkungen angesprochen werden.

Ich danke nochmals allen, die mir hier weiter geholfen haben, toller 
Service von Euch !

Grüße Manni
1
struct BitsOfByte
2
  {
3
  uint8_t b0:1;
4
  uint8_t b1:1;
5
  uint8_t b2:1;
6
  uint8_t b3:1;
7
  uint8_t b4:1;
8
  uint8_t b5:1;
9
  uint8_t b6:1;
10
  uint8_t b7:1;
11
  } __attribute__((__packed__));
12
13
#define SBIT(port,pin) ((*(volatile struct BitsOfByte*)&port).b##pin)
14
#define  SCL_DDR    SBIT(DDRC, 0)
15
#define  SCL_DATA  SBIT(PORTC, 0)  
16
#define  SDA_DDR    SBIT(DDRC, 1)
17
#define  SDA_DATA  SBIT(PORTC, 1)
18
void Reset_I2C (void)  // used for ATmega32 working as Master
19
  {
20
  uint8_t  i;
21
22
  SDA_DDR = 1;      // Set SDA line to output
23
  SDA_DATA = 1;      // Set SDA line to high
24
  SCL_DDR = 1;      // Set SCL line to output
25
26
  for (i=0; i<9; i++)    // Hammer out nine SCL clocks
27
    {
28
    Delay_us (150);
29
    SCL_DATA = 0;
30
    Delay_us (150);
31
    SCL_DATA = 1;
32
    }
33
34
  SCL_DDR = 0;      // Set SCL line to input
35
  SDA_DATA = 0;      // Set SDA line to low;
36
  SDA_DDR = 0;      // Set SDA line to input;
37
38
  //TWIM_Stop ();      // Wenn jetzt noch I2C STOP gesendet wird,
39
          // hängt der Slave wieder
40
  return;
41
  }

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Eine I2C-Leitung aktiv auf high setzen ist nicht so empfehlenswert, auch 
wenn es auf SCL nicht ganz so kritisch ist. Sollte aber doch mal ein 
Slave im Clock-Stretch hängen, gewinnt halt der stärkere.

Oliver

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.