Ich arbeite derzeit an einer Kommunikation zwischen einem STM32F407 (Master) und 6x STM32F103 (Slave) die über I2C im Interrupt / DMA Betrieb und einer RJ45 Verbindung kommunizieren sollen.
Der Master erkennt an den RJ45 Ports wo ein Slave angeschlossen wurde, da ein Pin auf 3.3V gezogen wird und somit ein Interrupt für den RJ45 Port ausgelöst wird.
Da die Slave Platinen alle gleich sind, wird beim einstecken jedem Slave eine neue I2C Adresse zugewiesen, funktioniert auch prima.
Nun mache ich mir über die Kommunikation gedanken.
Der Master schickt einen Abragebefehl für die Softwareversion an den Slave, der Slave soll den Befehl erkennen und entsprechend mit der Softwareversion antworten.
Leider hängt mein Hirn etwas...
Um die Daten auf dem Slave zu empfangen nutze ich folgenden Code:
Fürs Lesen sendet man normalerweise erstmal die Slave Adresse und danach ein Write auf die Registeradresse, danach ein Repeated Start, danach folgt direkt ein Read.
Fürs Lesen sendet man normalerweise erstmal die Slave Adresse und danach
ein Write auf die Registeradresse, danach ein Repeated Start, danach
folgt direkt ein Read.
Bitte?
Ich nutze die HAL-Bibliothek, warum sollte das bitte falsch sein?
Mit der HAL kenne ich ich nicht aus, aber I²C habe ich öfters benutzt und debuggt.
Dein Bild von Variante 1 zeigt, dass der Master nach dem Read 0x18 Kommando 6 Bytes liest. Danach beendet er die Übertragung mit NACK und STOP. Soweit alles gut.
In der zweiten Variante bestätigt der Slave das Read 0x18 Kommando ebenfalls ordentlich mit ACK. Doch danach hält jemand die Taktleitung auf LOW, gibt des Bus nicht mehr frei. Die Spannende Frage ist, wer den Bus blockiert: Master oder Slave?
Trenne den Master oder den Slave vom Bus, der Pull-Up Widersdtand soll aber bleiben. Wenn der SCL Pegel dabei auf High wechselt, dann hat der abgetrennte Busteilnehmer den Bus blockiert. Ansonsten war es der andere.
Für eine etwas schnellere Analyse von Blockaden kann die angehängte Schaltung als Bus-Ersatz hilfreich sein. Wenn du magst, kannst du sie 2x aufbauen so dass du auch an SDA so eine Anzeige hast. Die flackernde LED signalisiert Aktivität auf dem Bus. Eine dauerhaft leuchtende signalisiert eine Blockierung. Damit kannst du das Programm Zeile für Zeile durch steppen und siehst sofort, ab wo der Bus hängt.
Im blockierten Zustand sagt dir der Spannungsabfall an den 47Ω Widerständen der SCL Leitung, welche Seite der Bösewicht ist. Auf der Seite wo Spannung am Widerstand abfällt ist die Blockade.
Was du auch tun kannst:
Prüfe im Debugger, wo deine Code-Ausführung hängen bleibt. Ich vermute in der Zeile