Hallo,
ich versuche vier AVRs (Slaves) mit einem STM32 (Master) über I2C
kommunizieren zu lassen.
Die Kommunikation läuft immer eine Zeit lang (etwa 10 sec), bis einer
der Slaves die SDA-Leitung permanent auf Low zieht (auf dem einen Bild
ist die letzte Aktion auf dem Bus dargestellt).
Was mir auch aufgefallen ist, dass manchmal ein größerer Abstand
zwischen Slave-Adresse+W und Datenbyte ist, woran liegt das? (siehe
Bild)
Um das Ganze wieder laufen zu lassen, bringt es nur was den Slave zu
finden und zu resetten der gegen Low zieht, den STM32 zu resetten bringt
nix.
Zwischen STM32 und AVRs ist ein PCA9515, auf der 3,3V-Seite mit
4,7k-Pullups und auf der 5V-Seite 3,6k-Pullups.
Hab das ganze bereits mit 10kHz, 100kHz und 400kHz Busfrequenz probiert,
immer dasselbe Ergebnis.
Den Quell-Code für den STM32 findet man in dem Thread hier:
Beitrag "STM32: I2C-Error-Handling IRQ wird nicht aufgerufen"
Der Quell-Code von den AVR-Slaves ist hier:
Servus,
mh schrieb:> Zwischen STM32 und AVRs ist ein PCA9515, auf der 3,3V-Seite mit> 4,7k-Pullups und auf der 5V-Seite 3,6k-Pullups.> Hab das ganze bereits mit 10kHz, 100kHz und 400kHz Busfrequenz probiert,> immer dasselbe Ergebnis.
Die beiden stm32 pins sind 5 Volt tolerant. Man braucht nur einmal einen
Pullup anzuschließen. Bei 400khz und 5 Volt kannst du so 1,8K einmal an
SDA und SCL anschließen! Aber du hast ja ein Scope und dadurch kannst du
die Widerstände perfekt anpassen.
1
i2c_BusyFlag=0;
2
bldc_communication_enable=0;
3
bldc_communication_BusyFlag=0;
sind diese Var volatile?
Sonst fange an zu debuggen und gucke das Programm stehen bleibt.
mfg
Ohne dein Problem jetzt im Detail analysiert zu haben, ich hatte mal in
einer ähnlichen Konstellation (STM32 I2C Master, AVR Slave) das Problem
dass der STM32 zu schnell gesendet hat, und der AVR nicht mit gekommen
ist und dann die Kommunikation blockiert hat. Versuch mal Pausen
zwischen Adresse senden und Bytes übertragen, und zwischen die Bytes,
einzubauen, damit der AVR Zeit hat zu reagieren.
Danke für die Antworten.
Oben im Code muss bei default:
1
default:
2
ACK_ENABLE;
3
}
stehen, sonst tut sich überhaupt nix ;)
aSma>> schrieb:> Die beiden stm32 pins sind 5 Volt tolerant. Man braucht nur einmal einen> Pullup anzuschließen. Bei 400khz und 5 Volt kannst du so 1,8K einmal an> SDA und SCL anschließen! Aber du hast ja ein Scope und dadurch kannst du> die Widerstände perfekt anpassen.
Ok, wusste ich nicht.
> i2c_BusyFlag = 0;> bldc_communication_enable = 0;> bldc_communication_BusyFlag = 0;>> sind diese Var volatile?
Ja, sind alle volatile.
> Sonst fange an zu debuggen und gucke das Programm stehen bleibt.
Ich vermute mal dass es am STM32 liegt, da alles mit nem AVR als Master
funktionierte.
Dr. Sommer schrieb:> Ohne dein Problem jetzt im Detail analysiert zu haben, ich hatte mal in> einer ähnlichen Konstellation (STM32 I2C Master, AVR Slave) das Problem> dass der STM32 zu schnell gesendet hat, und der AVR nicht mit gekommen> ist und dann die Kommunikation blockiert hat. Versuch mal Pausen> zwischen Adresse senden und Bytes übertragen, und zwischen die Bytes,> einzubauen, damit der AVR Zeit hat zu reagieren.
Kommen daher die Pausen? Kann der Slave da Pausen erzwingen? (siehe
gepostetes Bild)
Ich finds seltsam, dass der Slave (siehe Bild der letzten Aktion auf dem
Bus) einfach die SDA-Leitung auf Low zieht, obwohl der ja noch nix zu
sagen hat. Hier versucht der Master ein neues Telegram zu schicken,
verschickt ein Start-Signal und beim ersten Datenbit geht irgendwas beim
Slave schief.
mh schrieb:> Hier versucht der Master ein neues Telegram zu schicken,> verschickt ein Start-Signal und beim ersten Datenbit geht irgendwas beim> Slave schief.
Das passiert gerne, wenn ein Read nicht mit einem NAK beim letzten Byte
abgeschlossen wird. Der Slave will unbedingt noch etwas loswerden. Da
hilft dann nur, per Bitbanging auf SCL den Rest des Bytes auf dem Slave
"herauszutakten". Wenn man dabei SDA offen lässt, ergibt sich ein NAK
und der Spuk ist vorbei.
MfG Klaus
Klaus schrieb:> mh schrieb:>> Hier versucht der Master ein neues Telegram zu schicken,>> verschickt ein Start-Signal und beim ersten Datenbit geht irgendwas beim>> Slave schief.>> Das passiert gerne, wenn ein Read nicht mit einem NAK beim letzten Byte> abgeschlossen wird. Der Slave will unbedingt noch etwas loswerden. Da> hilft dann nur, per Bitbanging auf SCL den Rest des Bytes auf dem Slave> "herauszutakten". Wenn man dabei SDA offen lässt, ergibt sich ein NAK> und der Spuk ist vorbei.>> MfG Klaus
Ok, gut zu wissen.
Der Fehler passiert hier im reinen Sendebetrieb, also Master sendet zum
Slave.
Falls SDA permanent auf Low ist, reagiert das I2C-Modul vom STM32 auch
nicht mehr.
Dr. Sommer schrieb:> Ohne dein Problem jetzt im Detail analysiert zu haben, ich hatte mal in> einer ähnlichen Konstellation (STM32 I2C Master, AVR Slave) das Problem> dass der STM32 zu schnell gesendet hat, und der AVR nicht mit gekommen> ist und dann die Kommunikation blockiert hat. Versuch mal Pausen> zwischen Adresse senden und Bytes übertragen, und zwischen die Bytes,> einzubauen, damit der AVR Zeit hat zu reagieren.
Hab das mit der Pause mal ausprobiert, leider kein Erfolg...
Bei einem STM32F4 hat mich das IIC-Interface einmal so genervt, daß ich
die betreffenden Pins per Software hab wackeln lassen, wie vor
Jahrzehnten beim 8051 (o.ä.).
Dann lief der Kram fehlerfrei ;-)
m.n. schrieb:> Bei einem STM32F4 hat mich das IIC-Interface einmal so genervt,> daß ich> die betreffenden Pins per Software hab wackeln lassen, wie vor> Jahrzehnten beim 8051 (o.ä.).> Dann lief der Kram fehlerfrei ;-)
Den Gedanken hatte ich auch schon, bin aber wohl noch nicht so weit ;-)
Stimmt das Programm des I2C-Slaves eigentlich so wie ich ihn
programmiert hab (also wie ich ACK enable)? Hab das ganze mal zu einem
Minimalprogramm zusammengekürzt:
Achtung, desto mehr Bauteile vorhanden sind, desto größer die
Wahrscheinlichkeit einen Fehler zu erzeugen.
Am besten erstmal eine minimal Schaltung mit 1 slave und 1 master und
zwei Pullups bei 100khz.
Nicht vergessen sollte man, dass die Slaves alle eine andere Slave_Add
haben müssen!
mfg
mh schrieb:>> Bei einem STM32F4 hat mich das IIC-Interface einmal so genervt,>> daß ich>> die betreffenden Pins per Software hab wackeln lassen, wie vor>> Jahrzehnten beim 8051 (o.ä.).>> Dann lief der Kram fehlerfrei ;-)>> Den Gedanken hatte ich auch schon, bin aber wohl noch nicht so weit ;-)
Mit Deiner Warterei machst Du den gleichen Fehler wie ich ;-)
m.n. schrieb:> mh schrieb:>>> Bei einem STM32F4 hat mich das IIC-Interface einmal so genervt,>>> daß ich>>> die betreffenden Pins per Software hab wackeln lassen, wie vor>>> Jahrzehnten beim 8051 (o.ä.).>>> Dann lief der Kram fehlerfrei ;-)>>>> Den Gedanken hatte ich auch schon, bin aber wohl noch nicht so weit ;-)>> Mit Deiner Warterei machst Du den gleichen Fehler wie ich ;-)
Ich bezweifel inzwischen dass es am STM32 liegt.
Die AVR-Slaves steuern BLDC-Motoren an. Falls die Motoren stillstehen
funktioniert die Kommunikation ohne Probleme.
Falls die Motoren laufen (es laufen somit andere IRQs im Hintergrund
mit), kommt es zu Verzögerungen in der Kommunikation von Seiten der
AVRs.
Hab hier nochmal ein neues Bild angehängt. Hier sieht man den Ausfall
der Kommunikation nach einem vollständigen Telegramm (der passende Slave
hat vorher sogar mit ACK quittiert). Alle! Slaves ziehen dann SDA gegen
Low (SDA geht nur wieder auf High, falls alle Slaves resettet wurden).
aSma>> schrieb:> Servus,> man könnte noch folgendes ausprobieren:void> I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
Hab ich ohne Erfolg getestet.
> Achtung, desto mehr Bauteile vorhanden sind, desto größer die> Wahrscheinlichkeit einen Fehler zu erzeugen.>> Am besten erstmal eine minimal Schaltung mit 1 slave und 1 master und> zwei Pullups bei 100khz.>> Nicht vergessen sollte man, dass die Slaves alle eine andere Slave_Add> haben müssen!>> mfg
Alle haben unterschiedliche Adressen (Kommunikation geht ohne
Motorbetrieb).
Ok, es liegt definitiv am STM32 ;-)
Hab jetzt einen AVR als Master und der kann alles ansteuern, ohne dass
etwas jemals ausfällt.
Ich versteh aber dann nicht was da genau schief läuft.
Warum verleitet der STM32 die Slaves dazu sich aufzuhängen, bzw. SDA auf
Low zu ziehen??
Hab hier noch ein paar Bilder.
Die Lücken entstehen offensichtlich aus den Bearbeitungszeiten im Slave.
"Lücke1" lässt sich zumindest damit erklären und damit kommt scheinbar
der STM32 auch zurecht.
Der STM32 scheint "Lücke2" nicht zu vertragen und hängt dann.
Der AVR als Master wartet einfach ab.
Weiß jemand wie man das lösen kann??
Aus meiner Erfahrung kann ich nur sagen Finger weg von I2C in Umgebungen
mit elektrischen Störungen. I2C zusammen mit Motoren o.ä. ist eine
einzige Katastrophe. Wenn du noch die Möglichkeit hast etwas zu ändern
dann nimm lieber was anderes.
sorry, das ist ulk.
Motor+I2C wird bei uns in einem Blutbehandlungsgerät seit Jahren
eingesetzt.
Läuft einfach.
Habe hier STM32F4 (Master) gegen 8051(Slave) mit 100KHz I2C laufen.
Wenn der 8051 den Motor "bearbeitet" wird SCL auf Low gezogen und der
Master wartet dann schon mal 100us bis es weitergeht.
VG
Pieter
Pieter schrieb:> Habe hier STM32F4 (Master) gegen 8051(Slave) mit 100KHz I2C laufen.> Wenn der 8051 den Motor "bearbeitet" wird SCL auf Low gezogen und der> Master wartet dann schon mal 100us bis es weitergeht.
Wie hast du den I2C vom STM32 initialisiert?
Meine Routinen sind hier zu finden:
Beitrag "STM32: I2C-Error-Handling IRQ wird nicht aufgerufen"
Ich sag mal nach der passenden Adressierung+W macht die Lücke oder das
Warten auf den Slave ja Sinn.
Aber die Lücke im Bild "Luecke2" tritt ja vor der eigentlichen
Adressierung auf. Ich schätz mal dass der STM32 damit auch nicht
zurechtkommt, der AVR aber schon (warum auch immer).
Servus,
dein SDA Leitung hat voll die Störungspeaks. Du könntest es mal mit
einen Wellenwiderstand versuchen.
Weiterhin muss bei einer Störung der Master ein Reset machen! Ich kennen
jetzt nicht genau, ob der f4 einen festen Timeout hat.
1
voidI2C1_ER_IRQHandler(void)
Wie sieht es aus wird dieser Handler aktiviert? Kannst mal eine LED
togglen.
Als alternative kann man ein Timeout in deine while(busy) Schleife
reinprügeln.
Sonst EMV Vorschriften beachten.
mfg
aSma>> schrieb:> Servus,> dein SDA Leitung hat voll die Störungspeaks. Du könntest es mal mit> einen Wellenwiderstand versuchen.
Die Peaks entstehen vermutlich, da zu dem Zeitpunkt der Master die
Leitung loslässt, der Slave die aber wieder auf Low zieht (= ACK).
> Weiterhin muss bei einer Störung der Master ein Reset machen! Ich kennen> jetzt nicht genau, ob der f4 einen festen Timeout hat.void> I2C1_ER_IRQHandler(void)>> Wie sieht es aus wird dieser Handler aktiviert? Kannst mal eine LED> togglen.
Die wird leider nicht aufgerufen. Laut Reference_Manual ist der
Fehlerfall wenn eine Leitung von einem Slave auf Low gezogen wird nicht
im Error-Handler mit drin.
Reset beim STM32 bringt leider nix, da ja der Slave weiterhin auf Low
zieht. Gibt es eine Routine o.ä., wo einfach 9 Takte bei SCL ausgegeben
wird? Das könnte die Situation beheben.
Ein anderer Ansatz wäre das Auftreten von den Lücken vor den
Adressdaten, am Slave zu beheben. Aber wie?
das Clock-Stretching nur im Slave-Mode oder auch im Master-Mode?
Wenn es für den Master-Mode auch geht, was macht es da genau?
Aus der Doku werd ich nicht so recht schlau...
Servus,
mach mal beim avr ein timeout rein. Aber das ist nur als
Vorsichtsmaßnahme im Fehlerfall anzusehen und soll nicht als Dauerlösung
angesehen werden!
Clockstrech sollte natürlich der Slave drauf haben.
Sonst versuche es mit den Wellenwiderstand oder Optokoppler.
aSma>> schrieb:> mach mal beim avr ein timeout rein. Aber das ist nur als> Vorsichtsmaßnahme im Fehlerfall anzusehen und soll nicht als Dauerlösung> angesehen werden!>> Clockstrech sollte natürlich der Slave drauf haben.>> Sonst versuche es mit den Wellenwiderstand oder Optokoppler.
Das ist doch alles Stochern mit der Stecknadel im Heuhaufen aber keine
Lösung des Problems.
mh schrieb:> Keine eine Idee??
Doch, s.o.
Da muß man auch keinen Wellenwiderstand kaufen ;-)
Servus,
danke für die Antwort!
Hab was interessantes rausgefunden.
Falls ich beim AVR noch zusätzlich Bus-Error in den case behandle und
dort dann das Stop-Bit setz, dann gibt er den Bus wieder frei.
Dann genügt es nur den STM32 zu resetten und alles läuft wieder für ne
Zeit.
Beim STM32 muss ich dann im Event-IRQ das STOPF-Flag abfragen, da er
dann da reinspringt, falls der Fehler auftaucht.
Also es funktioniert jetzt scheinbar.
Ich initialisiere das I2C-Modul bei der STOPF-Abfrage im EV-IRQ neu.
Dann funktioniert alles (anscheinend).
Aber kommt mir trotzdem ein wenig gefrickelt vor...