Forum: Mikrocontroller und Digitale Elektronik Verhallten auf dem TWI Bus


von Christoph H. (webturtle)


Lesenswert?

Ich habe nun ein System laufen mit einem Atmega644 als Master, 3 
Atmega48 und ein Atmega32 als Slaves per I2C.
Ich verwende die TWI Quellen hier aus dem Forum.
Das System funktioniert eigentlich recht gut, aber ab und an habe ich 
Hänger, so dass ich alles resetten muss.
Nun ist es so: Der Master und 3 Slaves (AT48) haben die gleiche VCC und 
jeder Slave macht sein TWI Init 200 ms verzögert. Also 200, 400, 600 ms.
Der Master macht sein Init direkt und wartet dann 1 Sekunde.
Der Atmega32 hat eine andere (eigene) VCC. Hier hat sich gezeigt, dass 
das System am stabilsten funktioniert wenn ich den Atmega32 zuerst 
einschalte und dann den Master.
Das versteh ich eigentlich schon nicht so ganz warum, aber hab es so 
hingenommen.

Ach so einschub: Mit anderer VCC meine ich nur, dass die von nem eigenen 
Netzteil kommt. Alle VCC sind 5V.

Nun habe ich in die TWI Routinen mal Timeouts reingemacht damit 
zumindest die anderen Funktionen noch gehen wenn es auf dem TWI Bus mal 
hängt.

Meine Frage iist eigentlich wie ich in einem solchen Fehlerfall den TWI 
Bus komplett neu initialisieren kann um nicht jedesmal die Stecker 
ziehen zu müssen.

Meine Fragen nochmal ganz konkret:

1. In welcher Reihenfolge sollten die TWI Teilnehmer initialisiert 
werden?
2. Wie kann man per Software auf Fehler reagieren und den Bus wieder 
lauffähig machen?
3. Würde es Sinn machen alle TWI Teilnehmer mit identischer VCC zu 
versorgen?
4. Evtl. die Slaves durch einen µC PIN ein und aus zu schalten? Mit nem 
BC247 dazwischen? Dann könnte ich im Fehlerfall nen Resett der Slaves 
machen.
5. Wie sichert ihr den TWI Bus gegen Fehler ab?

Chris

von Sauger (Gast)


Lesenswert?

Moin,

Schaltplan, Kabellängen und verwendete Software. Sonst wird das ein 
Ratespiel.

MfG

von Christoph H. (webturtle)


Lesenswert?

Okay:
Schaltplan kann ich leider erst heute Abend liefern, da ich hier kein 
Zugriff drauf habe.
Erklärung: vorab: Der Master ist der Pollin Webserver mit der Software 
von Ulli Radig. Hier habe ich die TWI Routinen aus dem Forum 
eingearbeitet. (Poste ich gleich hier).
Die Slaves sind eigentlich minimal beschaltet. VCC, GND, SCL und SCA. 
Sie steuern RGB Led Strips über Hardware PWM. (OC0A, OC0B und OC2A)
Der Mega32 steuert noch einige einzelne LEDs über Schieberegister. 
(Sternenhimmel).
TWI PullUps habe ich am Master 10K an VCC.
Kabellängen: Zu den 48er ca. 15 cm und zum 32 Vielleicht 50 cm.

Kommunikation eigentlich sauber möglich. Ich nutze den Webserver über 
rs232 zu einstellen der Farben. Dann auf einmal nach einigen Stunden 
kommen entweder Timeouts oder er kann den Bus nicht zum schreiben/lesen 
starten.

Quellcodes sind angehängt in folgenden Beiträgen zur Besseren Übersicht.

Chris

von Christoph H. (webturtle)


Angehängte Dateien:

Lesenswert?

Quellen des Atmega48 Slave
Exakt so sieht auch das TWI beim Mega32 aus, daher lass ich diese 
Quellen mal weg sonst wird es zu viel.

von Christoph H. (webturtle)


Angehängte Dateien:

Lesenswert?

Quelen des TWI Masters (nur die TWI Teile weil ich ja nicht den ganzen 
Webserver hochladen kann...)

Hier die Teile aus der cmd.c welche TWI nutzen:
1
void command_refresh (void)
2
{
3
  twi_send(LESESTERNE, TwiAdr_Sternenhimmel);  
4
  _delay_ms(TWI_DELAY);
5
  twi_read_s();
6
  _delay_ms(TWI_DELAY);
7
  twi_send(LESEROTBLAU, TwiAdr_Sternenhimmel);  
8
  _delay_ms(TWI_DELAY);
9
  twi_read_rb();
10
  _delay_ms(TWI_DELAY);
11
  twi_send(LESEWEISS, TwiAdr_Sternenhimmel);  
12
  _delay_ms(TWI_DELAY);
13
  twi_read_w();
14
  usart_write("PWM Stufen Sterne: ");
15
  for (uint8_t i=0;i<8;i++)
16
  {
17
    usart_write("%4i ", pwmtableStars[i]);
18
  }
19
  usart_write("\n\r");
20
  usart_write("PWM Stufen Weiss:  ");
21
  for (uint8_t i=0;i<8;i++)
22
  {
23
    usart_write("%4i ", pwmtableWhite[i]);
24
  }
25
  usart_write("\n\r");
26
  usart_write("PWM Stufen Blau:   ");
27
  for (uint8_t i=0;i<8;i++)
28
  {
29
    usart_write("%4i ", pwmtableBlue[i]);
30
  }
31
  usart_write("\n\r");
32
  usart_write("PWM Stufen Rot:    ");
33
  for (uint8_t i=0;i<8;i++)
34
  {
35
    usart_write("%4i ", pwmtableRed[i]);
36
  }
37
  usart_write("\n\r");
38
}
39
void command_rgb(void)
40
{
41
  char code[16];
42
  if ((*((unsigned int*)&variable[0]) >= 0) && (*((unsigned int*)&variable[0]) < 256))
43
  {
44
    if ((*((unsigned int*)&variable[1]) >= 0) && (*((unsigned int*)&variable[1]) < 256))
45
    {
46
      if ((*((unsigned int*)&variable[2]) >= 0) && (*((unsigned int*)&variable[2]) < 256))
47
      {
48
        code[0] = *((unsigned int*)&variable[0]);
49
        code[1] = *((unsigned int*)&variable[1]);
50
        code[2] = *((unsigned int*)&variable[2]);
51
        twi_send(code, *((unsigned int*)&variable[4]));
52
      }
53
      else
54
      { 
55
        usart_write ("\n\rFalsche Eingabe\r\n");
56
      }
57
    }  
58
    else
59
    { 
60
      usart_write ("\n\rFalsche Eingabe\r\n");
61
    }    
62
  }
63
  else
64
  {
65
    usart_write ("\n\rFalsche Eingabe\r\n");  
66
  }
67
//  EssStrip[7][10][3]
68
}

von Christoph H. (webturtle)


Lesenswert?

Vielleicht hat auch jemand ohne Schaltplan einen Tip wie er seine TWI 
Kommunikation Softwaremässig gegen Fehler absichert.
Das ist ja eher ein allgemeines Thema.


Chris

von Sauger (Gast)


Lesenswert?

Hallo,

Frühstückspause ist rum. Bin mal kurz über die Quellen geflogen. Auf den 
ersten Blick sieht es so aus das es keine Fehlerbehandlung für den TWI 
gibt. Klemm mal einen Slave ab und starte neu, hängt dann das ganze 
System?

MfG

von Christoph H. (webturtle)


Lesenswert?

Das kann ich auch erst heute Abend testen. Aber danke für den Tip.

Zur Fehlerbehandlung: Ich habe wenigstens mal dafür gesorgt dass er in 
keine Endlos While Schleife mehr läuft durch den Timeout.
Der Master gibt dann über rs232 auch aus wo der Timeout aufgetreten ist.

Sonst hab ich ich zur Zeit keine andere Idee der Fehlerbehandlung, 
weshalb ich da auf ne Anregung hier hoffe.

Chris

von Klaus2m5 (Gast)


Lesenswert?

Hangs treten bei einem Read auf? Wenn der Slave sich bei den Clocks 
verzählt und selbst SDA=0 setzt, kann er Stop/Start vom Master nicht 
sehen. In diesem Fall hilft es, 9 Clocks mit SDA=1 an den Slave zu 
senden, damit er mindestens ein NAK sieht. Danach sollte er auf 
Stop/Start wieder reagieren.

von Christoph H. (webturtle)


Lesenswert?

Klaus2m5 schrieb:
> In diesem Fall hilft es, 9 Clocks mit SDA=1 an den Slave zu
> senden, damit er mindestens ein NAK sieht. Danach sollte er auf
> Stop/Start wieder reagieren.

Ups. Wäre es unhöflich zu fragen wie das in C Code aussehen würde? Das 
muss ja sicher irgendwie manuell gemacht werden. Und mit Clocks ist ja 
sicher die TWI Frequenz gemeint.

Kennt jemand ein Projekt welches TWI verwendet? Dann würde ich da mal 
ein wenig schnusen....

von Klaus2m5 (Gast)


Lesenswert?

Christoph Hoell schrieb:
> Wäre es unhöflich zu fragen wie das in C Code aussehen würde?

Kann ich Dir leider nicht sagen, denn ich programmiere alles in 
Assembler.

Im Prinzip werden SDA und SCL über DDR gesteuert (open collector). 
Dadurch ist SDA und SCL invertiert. Zwischen den SCL Impulsen ein Delay 
mit der halben Periode der I2C-Frequenz.

SDA_DDR=0, SCL_DDR=0, 9*(SCL_DDR=1, SCL_DDR=0)

Einfach einen Start/Write mit 0xFF machen geht leider nicht, da der 
Master wegen Bus-Arbitration denken würde, dass ein anderer Master SDA=0 
setzt.

Nach meiner Erfahrung wären auch kleinere Pullups hilfreich. Versuchs 
mal mit 1k8 (~3mA bei 5V)

von Christoph H. (webturtle)


Lesenswert?

Danke. Prima Tips.
Da hab ich heute Abend einiges zu testen.
Mit den Pull Ups bin ich nach einiger Lektüre erst von 4K7 auf 10K 
hochgegangen.

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.