was passiert bei fehlerhafter Adresse im I2C-Bus?

OP #3745589
Lesenswert?

Aha.

Es besteht folgendes Problem: Ein Display mit unbekannter Adresse soll 
angesteuert werden. Es werde eine Startcondition und dann eine Adresse 
gesendet. Ein Nack würde Klarheit schaffen. Wenn nichts gesendet wird, 
kann ich bis zum St.Nimmerleinstag warten. Ich will aber alle max. 128 
Adressen testen. Die erkannte Adresse antwortet also mir ACK. Wie lange 
muss ich denn warten, bis ich den nächsten Adressenwert senden kann und 
der slave diesen auch prüft?

Grüsse

Robert
#3745607
Lesenswert?

R. Freitag schrieb:
> Aha.
>
> Es besteht folgendes Problem: Ein Display mit unbekannter Adresse soll
> angesteuert werden. Es werde eine Startcondition und dann eine Adresse
> gesendet. Ein Nack würde Klarheit schaffen.

Dann sieh dir doch einfach mal an, wie die Sache mit NACK bzw. ACK am 
I2C Bus technisch funktioniert. Dann sollte dir die Antwort auf deine 
Frage eigentlich unmittelbar ins Auge springen.

> Wenn nichts gesendet wird,
> kann ich bis zum St.Nimmerleinstag warten. Ich will aber alle max. 128
> Adressen testen. Die erkannte Adresse antwortet also mir ACK. Wie lange
> muss ich denn warten, bis ich den nächsten Adressenwert senden kann und
> der slave diesen auch prüft?

Weniger als eine halbe Stunde :-)
(Firma: Vescomp) #3745629
Lesenswert?

R. Freitag schrieb:
> kann ich bis zum St.Nimmerleinstag warten. Ich will aber alle max. 128
> Adressen testen. Die erkannte Adresse antwortet also mir ACK. Wie lange
> muss ich denn warten, bis ich den nächsten Adressenwert senden kann und
> der slave diesen auch prüft?

 Auweia.
 Erst schreiben, dann nachdenken (bezieht sich auf mich und meinen
 geloschten Beitrag).

 Selbst mit Clock stretching muss ACK oder NACK in max. 10 CLK kommen,
 Wenn du mit 100KHz arbeitest ist das genau ?
#3746482
Lesenswert?

Wenn kein Baustein antwortet entsteht durch den pullup Widerstand an SDA 
automatisch ein NACK.

Versuche mal testweise die Adresse 0, einige Bausteine akzeptieren die 
als general call. Dann kann man zumindest schon mal sehen ob überhaupt 
eine Antwort kommt.

Durchprobieren der Adressen kann man ohne großartige Pausen. Nach einem 
"Stop" mal 5 Takte (50µs) warten und dann wieder "Start"en.
#3746486
Lesenswert?

i2cdetect -y 0 macht an jedem Rechner ziemlich genau das: einfach alle 
Adressen durchprobieren und schauen wo was antwortet:

# time i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- 08 -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- 44 -- -- -- -- -- -- -- -- -- -- --
50: 50 51 -- -- -- -- -- -- -- -- -- -- 5c 5d 5e 5f
60: -- 61 -- -- -- -- -- -- -- 69 -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
0.00user 0.00system 0:00.02elapsed

Besonders lang dauert es auch nicht, du kannst die Adressen direkt 
nacheinander durchprobieren. Ich finde so immer die Adressen von 
i2c-Clients, geht schneller als das Datenblatt lesen ;)
Gast #3746697
Lesenswert?

R. Freitag schrieb:
> i2cdetect ist wo verfügbar?

Linux. Wobei das für einen µC auch schnell selbst geschrieben ist. Meins 
sieht so aus:
1
/* Suchen von I2C-Devices und Darstellen auf LCD */
2
void i2c_scan(void)
3
{
4
  I2C_TypeDef* I2Cx = I2C1;
5

6
  uint8_t status;
7

8
  status = I2C_init(I2Cx); // initialize I2C peripheral
9
    if(status) goto error;
10

11
  printf_P(PSTR("\fScan I2C adresses\n\a"));
12

13
  /* Check for I2C devices */
14
  printf_P(PSTR("I2C=\a"));
15
  for(uint8_t i=0x00; i<0x7F; i++) {
16
    printf_P(PSTR("0x%2x\a"),i<<1);
17

18
    status = I2C_ping(I2Cx,i<<1);
19

20
    switch (status) {
21
    case i2c_ok:
22
      printf_P(PSTR("\nI2C=\a"));
23
      break;
24
    case i2c_ackTimeout:   // NACK
25
    case i2c_noAck:        // auch NACK
26
      printf_P(PSTR("\b\b\b\b\a"));
27
      break;
28
    case i2c_otherTimeout: // Busfehler: Konnte START nicht senden
29
      // fallthrough
30
    default:               // Unterwarte Faelle
31
      I2C_reset(I2Cx);
32
      printf_P(PSTR("TO=%2x,%2x \a"),i<<1,status);
33
    }
34

35
    delay_us(50000);
36
  }
37
  printf_P(PSTR("\b\b\b\bdone.    \a"));
38

39
  while(!key_getstroke());
40
  return;
41

42

43
  error:
44
  I2C_reset(I2Cx);
45
  printf_P(PSTR("\nError scanning I2C bus\nerror code 0x%x\npress key to leave\a"),status);
46
  while(!key_getstroke());
47
}
und
1
/* I2C-Adresse kurz anpingen um zu sehen, ob Geraet vorhanden
2
 *
3
 * return: i2c_ok          : Device vorhanden und hat mit ACK bestaetigt
4
 *         i2c_busyTimeout : Bus nicht frei
5
 *         i2c_otherTimeout: Unerwarteter Fehler
6
 *         i2c_ackTimeout  : NACK, Device nicht vorhanden */
7
uint_fast8_t
8
I2C_ping(I2C_TypeDef *I2Cx, uint8_t slaveaddr)
9
{
10
  uint_fast8_t status;
11

12
  // i2c_ok oder i2c_busyTimeout
13
  status = I2C_waitbusy(I2Cx);
14
  if(status) {
15
      status |= (2<<4);
16
      goto error;
17
  }
18

19
  // Startbedingung
20
  // i2c_ok           : ACK empfangen, Teilnehmer vorhanden
21
  // i2c_ackTimeout   : kein ACK empfangen, keine Antwort vom Teilnehmer
22
  // i2c_otherTimeout : Start-Bedingung konnte nicht gesendet werden.
23
  // Senderfehler.
24
  status = I2C_start(I2Cx,slaveaddr,I2C_Direction_Transmitter);
25
  I2C_stop(I2Cx);
26

27
  error:
28
  return status;
29
}
für einen AVR.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren