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..
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.
Daniel S. schrieb:> Die Adresse wird eigentlich nur verschoben...
Binärsystem, Schieben nach links = Multiplikation mit 2.
Aber nach dem, was ich spontan finde, ist der Aufruf schon korrekt. Hast
Du vielleicht das Slave-Device vermurkst? Zeig doch mal, was der Logic
Analyzer ausspuckt.
Daniel S. schrieb:> Wo steht denn DevAddress*2 ?> Die Adresse wird eigentlich nur verschoben...
Dann solltest Du Dich vielleicht noch einmal mit Grundschulmathematik
beschäftigen.
> 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..
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.
> 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)..
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.
Daniel S. schrieb:> der Master hat die Adresse 0x00, und der Slave hat die 0x01.
Die STM-Hardware unterstützt das, damit die Firmware solche Sachen wie
General Call implementieren kann. Aber du solltest trotzdem keine
ungültigen Adressen verwenden.
https://www.i2c-bus.org/addressing/
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.
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.
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?
Daniel S. schrieb:> 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 ?)
Die 7-Bit-Adresse muss die selbe sein. Ob mit oder ohne Shift, musst du
in der jeweiligen Dokumentation nachschauen (wenn sie denn existiert und
auffindbar ist).
Soweit ich sehe, will der STM32-HAL eine geshiftete Adresse.
>> 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:
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...
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