Moin!
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:
Leider empfängt der Master dann null komma garnix, über den Analyzer
sehe ich eben nur das auf den Slave geschrieben wird, aber kein Read...
Weiß jemand zufällig rat, oder stelle ich mich doof an?
Daniel S. schrieb:> über den Analyzer sehe ich eben nur das> auf den Slave geschrieben wird, aber kein Read...
Lass uns auch mal gucken, was du da siehst
Ouh Sorry, hats nicht angehängt.
Bild 1:
Ist die Variante 1 mit:
Hier Empfängt der Master das vom Slave, schickt aber seltsamer weiße
noch ein NACK mit hinterher.. ?!
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.
Ali K. schrieb:> 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?
Der Code für den Master:
Ali K. schrieb:> Ich meine,dass es in der HAL eine Funktion, die sich WriteRead o.ä.> nennt, gibt.> Schau mal bitte, habe es gerade nicht im Kopf.
Achso, du meinst die HAL_I2C_Mem_Write / HAL_I2C_Mem_Read funktion.
Möchte aber beim Polling bleiben..
Daniel S. schrieb:> schickt aber seltsamer weiße noch ein NACK mit hinterher.. ?
Ein Nack wird nicht aktiv gesendet. Ein Nack kommt beim 9. Takt
zustande, wenn der Empfänger das Byte nicht mit Ack bestätigt.
Das Nack hat den passiven High Pegel des Pull-Up Widerstandes.
Daniel S. schrieb:> Ali K. schrieb:>> Ich meine,dass es in der HAL eine Funktion, die sich WriteRead o.ä.>> nennt, gibt.>> Schau mal bitte, habe es gerade nicht im Kopf.>> Achso, du meinst die HAL_I2C_Mem_Write / HAL_I2C_Mem_Read funktion.> Möchte aber beim Polling bleiben..
Memread ist Polling.
Daniel S. schrieb:> die über I2C im Interrupt / DMA> Betrieb und einer RJ45 Verbindung kommunizieren sollen.Daniel S. schrieb:> Möchte aber beim Polling bleiben..
Passt nicht zusammen...merkste selber oder?
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
> while(HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY) {}
Schaue im Quelltext nach, was da genau abgefragt wird und vergleiche das
mit der Doku im Datenblatt.