I2C Scanner / STM32 Adressproblem..

OP #7543663
Lesenswert?

Moin Zusammen,

Habe einen STM32F407VET6 und programmiere in C++

Aktuell habe ich mich gewundert, warum mein Slave mit der I2C Adresse 0x01 nicht von meinem Scanner gefunden wird.

Der Fehler war über den Logicanalyzer schnell gefunden. Mein Scanner scannt in 2er Schritten die I2C Adressen bis 128... Aber warum? Für meinen I2C Bus nutze ich das 7-Bit Addressing..

1
int i2c_RailScanner()
2
{
3
  uint8_t i = 0;
4
  int found = 0;
5

6
  for(i=1; i<128; i++)
7
  {
8
    if(HAL_I2C_IsDeviceReady(&hi2c2, (uint16_t)(i<<1), 2, 50) == HAL_OK)
9
    {
10
      if(i2c_deviceFound(i))
11
      {
12
        found++;
13
      }
14
    }
15
  }
16

17
  if(found == 0)
18
    error = true;
19

20
  return found;
21
}

Scannt dann jewels 0x02, 0x04, 0x06,0x08,0xA0,0xC0 etc...

#7543675
Lesenswert?

Daniel S. schrieb:

(uint16_t)(i<<1)

Da wird die 7-Bit-Adresse ein Bit nach links geschoben, die sieht dann also so aus, wie sie auf dem Bus übertragen wird (Bit 7-1 I2C-Adresse, Bit 0 R/!W).

Welche Variante (nackte 7-Bit-Adresse oder 1 Bit nach links geschoben) HAL_I2C_IsDeviceReady() haben will, musst Du in der Dokumentation nachlesen.

OP #7543722
Lesenswert?

Dann solltest Du Dich vielleicht noch einmal mit Grundschulmathematik beschäftigen.

Na wenn du das sagst..! :)

Binärsystem, Schieben nach links = Multiplikation mit 2.

Ah okay, wusste ich nicht, muss selten etwas schieben.

Generell funktioniert mein Slave, der Master hat die Adresse 0x00, und der Slave hat die 0x01.

Wenn ich dem Slave die Adresse 0x02 gebe, wir er auch gefunden... Mich wundert eben nur, warum bei meinem STM32 in 2er Schritten gezählt wird, selbst wenn ich die Schiebung nach links weg lasse..

Angehängte Dateien:
#7543726
Lesenswert?

Daniel S. schrieb:

Mich wundert eben nur, warum bei meinem STM32 in 2er Schritten gezählt wird, selbst wenn ich die Schiebung nach links weg lasse..

Weil Du die I2C-Adressierung nicht begreifst?

Zeig doch endlich mal, was der Logic Analyzer anzeigt. Und zwar das rohe Signal, nicht nur das Log des Decoders.

Nochmal zur Verdeutlichung: Bit 0 ist R/!W. Wenn Dein Slave die 7-Bit-Adresse 0x01 hat, wird er auf dem Bus mit 0x02 (write) und 0x03 (read) angesprochen.

OP #7543770
Lesenswert?

Weil Du die I2C-Adressierung nicht begreifst?

Scheinbar, arbeite jedoch öfters mit I2C, auch erfolgreich.. scheinbar verstehe ich Sie wohl wirklich nicht... Warum aber, zählt der selbige Code auf einem ESP32 die Adressen von 1 bis 128 durch?

Zeig doch endlich mal, was der Logic Analyzer anzeigt. Und zwar das rohe Signal, nicht nur das Log des Decoders.

Im Anhang, da findest du nicht viel, da der Slave mit 0x01 beim Scannen nicht gefunden wird, da:

i=1 ... Mein Master hat die Adresse 0x00 und mein Slave hat die Adresse 1, also 0x01 (Steht so auch im I2C Register des Slaves)..

Angehängte Dateien:
#7543780
Lesenswert?

Daniel S. schrieb:

Warum aber, zählt der selbige Code auf einem ESP32 die Adressen von 1 bis 128 durch?

Weil es wie gesagt zwei Schreibweisen von I2C-Adressen gibt, die rohe 7-Bit-Adresse und die um 1 Bit nach links verschobene, wie man sie auf dem Bus findet.

Bei fremden Libraries musst Du immer darauf achten, welche benötigt wird.

Daniel S. schrieb:

Im Anhang, da findest du nicht viel, da der Slave mit 0x01 beim Scannen nicht gefunden wird

Da wird 0x01 (7-Bit-Adresse) zum Schreiben angesprochen (-> 0x02) und liefert kein ACK.

Dein Problem ist der Slave.

#7543813
Lesenswert?

Ein Problem sind die reservierten Bereiche bei der Adressierung beim I2C. Gültige Slave-Adressen sind größer als 0x07 und kleiner als 0x78. Die Adresse 0x01 ist als CBUS Addresse reserviert. Die CBUS-Adresse wurde reserviert, um das Mischen von CBUS-kompatiblen und I2C-Bus-kompatiblen Geräten im selben System zu ermöglichen. I2C-Bus-kompatible Geräte dürfen beim Empfang dieser Adresse nicht antworten.

OP #7546721
Lesenswert?

Moin,

Hm okay... verstehen tu ich es immer noch nicht ganz.

Zu meinem Verständnis, der HAL I2C Treiber erwartet ja eine geshiftete Adresse 8-Bit.

Ich stelle nun im Master also die Adresse 0x10 ein. (Ohne <<1 ?) In meinem Slave stelle ich dann nun die Adresse 0x20 ein (Ohne <<1 ?)

Beim Transmit vom Master gebe ich dann als Adresse 0x20<<1 an? Der HAL Treiber macht ja somit daraus "0x40" also das doppelte, aber der Slave hat ja dann nur die Adresse "0x20"... oder denke ich falsch?

vielen lieben Dank.

#7547110
Lesenswert?

Daniel S. schrieb:

Zu meinem Verständnis, der HAL I2C Treiber erwartet ja eine geshiftete Adresse 8-Bit.

Tut er das? Steht das irgendwo, oder reimst Du Dir das irgendwie zusammen? Woher stammt der Code, den Du am Anfang gezeigt hast? Hast Du den selbst geschrieben, oder hast Du den /irgendwo/ im Internet gefunden, oder wird explizit darauf hingewiesen, daß der für genau den von Dir verwendeten HAL-Treiber passt?

#7547151
Lesenswert?

Die Dokumentation (https://www.disca.upv.es/aperles/arm_cortex_m3/llibre/st/STM32F439xx_User_Manual/group__i2c__exported__functions__group2.html#gade6a669a25f0e99ef7fd52724acb3dec)

schreibt bei allen Funktionen, denen eine Geräteadresse übergeben wird, dies hier:

DevAddress Target device address The device 7 bits address value in datasheet must be shifted to the left before calling the interface

Die /einzige Ausnahme/ ist die Funktion HAL_I2C_IsDeviceReady. Da steht nur:

DevAddress Target device address

Absicht oder Versehen?

OP #7547522
Lesenswert?

DevAddress Target device address The device 7 bits address value in datasheet must be shifted to the left before calling the interface

So stehts auch in den Funktionen.. nichts neues?

Die /einzige Ausnahme/ ist die Funktion HAL_I2C_IsDeviceReady. Da steht nur:

DevAddress Target device address

Absicht oder Versehen?

Stimmt für die HAL_I2C_IsDeviceReady funktioniert.

Leider wurden meine Fragen aber nicht beantwortet.

https://controllerstech.com/stm32-as-i2c-slave-part-1/

Hier wird der STM32 Slave lediglich mit 0x12 Adresse eingerichtet,

Master-Code:

1
  /* USER CODE BEGIN 2 */
2

3
  uint16_t slaveADDR = 0x12<<1;
4
  uint8_t TxData[6] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6};
5
  while (1)
6
  {
7
    HAL_I2C_Master_Transmit(&hi2c1, slaveADDR, TxData, 6, 1000);
8
    HAL_Delay (1000);
9
  }

Hier wird die Adresse mit 0x12<<1 geshiftet... Aber der Slave wird gar nicht erreicht, selbst wenn ich den Code Original nachbaue, sagt mir mein Saleae Analyzer das beim Transmit die Adresse 0x24 angesprochen wird (Verdoppelt) aber er kann die Adresse 0x24 garnicht erreichen, weil der Slave hat die Adresse 0x12 hat...!

Wenn ich nun den Master Code um die Funktion HAL_I2C_IsDeviceReady erweitere und die 0x12 prüfe, erhalte ich vom Slave ein ACK.

Prüfe ich mit 0x12<<1 wird die 0x24 geprüft und es folgt ein NAK.

Welche Adresse wäre denn nun korrekt?

Ich bin mittelmäßig verwirrt...

#7547602
Lesenswert?

Daniel S. schrieb:

Welche Adresse wäre denn nun korrekt?

Ich bin mittelmäßig verwirrt...

Das ist dabei üblich. Die offizielle Spec nennt für die Adresse 7 Bits, die im Telegramm ein Bit links geschiftet übertragen wird, mit dem red/write-Bit hinten dran.

99% aller Libs implementieren den Shift aber nicht, die erwarten die Adresse als linksgeschifteten 8-Bit-wert.

Insofern hilft da RTFM, oder einfach ausprobieren.

Oliver

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