Forum: Mikrocontroller und Digitale Elektronik for Schleife bleibt stehen


von Fragender (Gast)


Lesenswert?

Hallo
in diesem kleinen Code versteh ich was nicht
1
uint8_t iadr;
2
e=0;
3
for (iadr = 0x10; iadr < 0xF0; iadr ++)
4
  {      
5
  e = i2c_start(iadr);  // Start i2C mit Adresse Slave
6
  i2c_write(0x00);  // Sende Daten
7
  i2c_stop();
8
        
9
  itoa( iadr, Buffer, 10 );
10
  lcd_printlc(4,2,Buffer);  
11
          
12
  _delay_ms(100);
13
  }
ich möchte mit diesem Programm die Adressen im I2C Bus von 16 (0) bis 
239 (254) durch suchen lassen und mir den Wert auf dem display anzeigen 
lassen.
Kommentiere ich diese 3 Zeilen aus
1
e = i2c_start(iadr);  // Start i2C mit Adresse Slave
2
i2c_write(0x00);  // Sende Daten
3
i2c_stop();
läuft die Schleife und die Werte werden auf dem Display angezeigt. 
Innerhalb der 3 Zeilen hängt sich das Programm auf. Gebe ich z.B. für 
iadr die Adresse 0x40 oder 64 ein geht es.
Warum zählt es nicht durch?
LG ???

von Verzweifelter (Gast)


Lesenswert?

Irgendwas funktioniert da nicht.

von Jim M. (turboj)


Lesenswert?

Dazu müsste man die Implementation der i2c_XXX Funktionen kennen. Ich 
erkenne so nicht mal die verwendete Plattform.

von Georg (Gast)


Lesenswert?

Fragender schrieb:
> die Adressen im I2C Bus von 16 (0) bis
> 239 (254) durch suchen lassen

Und was wenn es den Client an der Adresse nicht gibt??

Debuggen und nachschauen wo es stoppt.

Georg

von Sebastian S. (amateur)


Lesenswert?

Kann es sein, dass Du unerlaubte Adressen in: i2c_start(iadr) übergibst?
Habe schon ewig nicht mehr im I²C gearbeitet, aber irgendwie bestimmt 
doch das LSB die Richtung (lesen/schreiben).

von Fragender (Gast)


Lesenswert?

eigentlich ist es Moment egal wie weit gezählt wird, da er bei 16 stehen 
bleibt. Mit dem ganzen Code möchte ich ermitteln welche Adresse am Bus 
anliegt. Wenn ich eine Adresse damit aufrufe und vom Slave ein ACK 
zurück kommt, ist ein Slve vorhanden. Kommt kein ACK zurück geht es mit 
der nächsten Nummer weiter. Die Adresse des Slave wird gespeicher oder 
angezeigt.
Arbeite mit C und dem AVR Studio 7. Die Funktionen von i2c_start und 
andere sind im System drin.

Schreibe ich z.B. das:
1
#define adr1_w 0x40    /64 oder 0x40
und rufe auf mit
1
e = i2c_start(adr1_w);      // Start i2C mit Adresse Slave
2
i2c_write(0x00);      // Sende Daten
3
i2c_stop();
wir mir angezeigt das das Display mit 0x40 vorhanden ist.
LG???

von Curby23523 N. (Gast)


Lesenswert?

Du nutzt bestimmt ein while beim Senden der I²C Adresse.

Etwas wie
1
while(!(TWIC_MASTER_STATUS & (TWI_MASTER_WIF_bm | TWI_MASTER_RIF_bm)));

oder
1
while(!(TWIC_MASTER_STATUS & TWI_MASTER_RIF_bm));

Sprich, wenn es die Adresse nicht gibt, dann warten diese Zeilen bis in 
alle Ewigkeit.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Fragender schrieb:
> und rufe auf mit
> e = i2c_start(adr1_w);      // Start i2C mit Adresse
> Slave
> i2c_write(0x00);      // Sende Daten
> i2c_stop();
> wir mir angezeigt das das Display mit 0x40 vorhanden ist.

In 'e' wird doch das Ergebnis des I²C Startes zurückgegeben. Wenn da ein 
Fehler auftritt (kein ACK), solltest du also gar nicht erst versuchen, 
da noch was hinzusenden, sondern den Misserfolg ausgeben (oder eben 
nicht) und zur nächsten Startadresse weitergehen.

von holger (Gast)


Lesenswert?

>Kommt kein ACK zurück geht es mit der nächsten Nummer weiter.

Vermutlich wartet i2c_start(adr1_w); ewig wenn kein ACK
für die Adresse kommt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Fragender schrieb:
> Innerhalb der 3 Zeilen hängt sich das Programm auf.
Und was passiert auf dem Bus? Mit einem Oszi lässt sich das leicht 
kontrollieren. Hast du sowas?

von Fragender (Gast)


Lesenswert?

Hallo Lothar
habe als Probe adr1_w verwendet. das ist die Adresse meines Display. 
Damit erfolgt das Zählen in der Schleife. Habe jetz zur Probe mal die 
Adresse adr2_w eingegeben (0x42). Es hängt kein physiklisches Gerät mit 
dieser Adresse am Bus. Mit dieser Adresse läuft der Bus korrekt und es 
wird korrekt gezählt.
In dieser Zeile hängt sich das Programm auf:

Fragender schrieb:
> e = i2c_start(iadr);  // Start i2C mit Adresse Slave

leider ist mir vollkommen unklar warum.

von Bernhard S. (dl9rdw)


Lesenswert?

Sebastian S. schrieb:
> Kann es sein, dass Du unerlaubte Adressen in: i2c_start(iadr) übergibst?
> Habe schon ewig nicht mehr im I²C gearbeitet, aber irgendwie bestimmt
> doch das LSB die Richtung (lesen/schreiben).

Die Adressen werden ja nur in den 7 höherwertigen Bits übergeben, also 
vor der Übergabe an die i2c_start Routine einfach den Zähler um 1 nach 
links schieben.

Grüße

Bernhard

von Fragender (Gast)


Lesenswert?

Damit geht es:
1
e = i2c_start(adr2_w);      // Start i2C mit Adresse Slave

von Wolfgang (Gast)


Lesenswert?

Fragender schrieb:
> for (iadr = 0x10; iadr < 0xF0; iadr ++)
>   {
>   e = i2c_start(iadr);  // Start i2C mit Adresse Slave

Wie kommst du drauf, dass der I2C-Bus mit Adressen mit mehr als 7 Bit 
umgehen kann. In der Spezifikation vom I2C steht davon nichts und 
möglicherweise geben deine I2C-Routinen keinen ordenlichen Fehlerstatus 
zurück.

von Fragender (Gast)


Lesenswert?

Habe die Lösung gefunden:
(Sind wahrscheinlich mehrere Fehler die sich gegenseitig beeinflussen)

- abhängig mit welcher Zahl ich starte (gerade oder ungrade/lesen oder 
schreiben)
- muss immer um 2 Zahlen erhöhen (lesen oder schreiben)
- Abfrage Bus blockiert und dadurch blockierd die Schleife

Jetzt läuft die Abfrage korrekt durch und zeigt mir mit e = 1 oder 0 an 
ob eine Adresse vorhanden ist.
Danke für eure Hilfe
LG

von Curby23523 N. (Gast)


Lesenswert?

Fragender schrieb:
> - abhängig mit welcher Zahl ich starte (gerade oder ungrade/lesen oder
> schreiben)
> - muss immer um 2 Zahlen erhöhen (lesen oder schreiben)
> - Abfrage Bus blockiert und dadurch blockierd die Schleife


Das sind aber keine logischen Erklärung für dein Problem, evtl. Punkt 3, 
aber was meinst du damit (genau)?

von Georg (Gast)


Lesenswert?

Fragender schrieb:
> - abhängig mit welcher Zahl ich starte (gerade oder ungrade/lesen oder
> schreiben)
> - muss immer um 2 Zahlen erhöhen (lesen oder schreiben)

Warum das so ist, wurde dir doch von Bernhard Schröcker vor langer Zeit 
schon erklärt. Es lohnt sich doch ab und zu, die Antworten auch zu lesen 
anstatt hier Selbstgespräche zu führen.

Georg

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.