mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 I2C Bus bleibt hängen


Autor: Michi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich möchte mit dem STM32 Cortex M3 einen I2C Sensor auslesen. Allerdings 
scheitere ich schon an der Konfiguration der Schnittstelle. Ich nutze 
folgenden Code:
I2C_InitTypeDef  I2C_InitStructure;
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x03A2;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
I2C_Init(I2C1, &I2C_InitStructure);   
I2C_Cmd(I2C1, ENABLE);
  

I2C_GenerateSTART(I2C1, ENABLE);
  
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  

Das Programm bleibt immer an der while Schleife hängen.
I2C1 und GPIO Clock habe ich im RCC eingeschaltet. SDA, SCL (PB6, PB7) 
sind als GPIO_Mode_AF_OD konfiguriert. Die SDA und SCL sind mit 4k7 Ohm 
Pull Ups beschalten.
Ich habe heute schon den ganzen Nachmittag nach dem Fehler gesucht, aber 
nichts gefunden. Kann mir bitte jemand einen Hinweis geben, was ich 
falsch mache?

Vielen Dank

Autor: Plan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht so einfach nicht....

Du musst ALLE Bits der Register I2C_SR1 und I2C_SR2 EINZELN 
auswerten und eine Fehlerbehandlung implementieren.

Dieses I2C_CheckEvent() klappt nur wenn die Bits haar genau so sind wie 
hier in I2C_EVENT_MASTER_MODE_SELECT definiert. Ist noch irgend ein 
anderes Bit gesetzt, dann bleibt das ganze für immer hängen.

Schreibe diese beiden Register immer noch in eine extra Variable, dann 
kannst Du debuggen was für ein Bit da noch nervt und bedient werden 
möchte.

Autor: Michi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich konnte das ganze etwas eingrenzen, eine Lösung habe ich aber immer 
noch nicht gefunden:
Nach dem Senden der Startbedingung wird das SB Bit nicht gesetzt. Lt. 
Reference Manual soll das per Hardware geschehen.

Autor: Mike R. (thesealion)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich mir das angehöngt Bild ansehe, sieht es so aus, also ob der I2C 
Bus Busy ist. Vielleicht solltest du bevor du versuchst das Start zu 
senden erst warten, bis der Bus frei ist.
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

Ansonsten sah meine Testroutine genauso aus und die hat lauf Scope 
funktioniert.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Häng mal versuchsweise die Initialisierung der Portpins auf AF hinter 
die des I2C-Moduls. Ich meine mich zu erinnern, dass beim Initialisieren 
vom I2C-Modul die Pins kurz auf GND gehen.

Autor: Plan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist das Bit RxNE im I2C_SR1 gesetzt?
Wenn ja, dann musst Du erst ein Dummy Read machen.

Ist im I2C_SR1 ein Fehlerbit gesetzt?
Wenn ja, dann schreibe 0 auf das Register.

Autor: Michi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke schonmal für die Antworten.
In den SR Registern ist nur das Busy Flag gesetzt.
Ich habe sowohl die Initialisierung der GPIO nach der I2C 
Initialisierung als auch das Warten bis der Bus frei wird versucht. Ohne 
Erfolg.
Sobald ich initialisiere geht der Bus auf Busy. Ich hab wirklich keine 
Ahnung woran das liegen kann. Ich hab auch schon versucht, wie in der 
Reference Manual beschrieben, ein Stop Signal zu senden wenn der Bus 
Busy ist, aber das hat auch nichts gebracht. Hat noch jemand einen Tipp 
für mich?

Autor: Christoph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Michi

ich weiß nicht ob es dir hilft aber ich hatte mal Probleme beim lesen 
von 2 Byte Daten. Bei mir hat das Vorziehen von I2Cx->CR1 = 0xC01; vor 
die Start Bedingung Abhilfe geschaffen.


  /* Send START condition */
  I2Cx->CR1 = 0xC01; /* ACK=1, POS =1, PE = 1  */
  I2C_GenerateSTART(I2Cx, ENABLE);
  while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

Viel Erfolg
Christoph

Autor: Plan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, bei mir kam das auch vor.
Da ist wohl noch ein Device im Sende-Mode und zieht eine Leitung auf 
LOW.

Da muss der Port-Pin auf GPIO umgeschaltet werden und es muss manuell so 
viele Clocks generiert werden bis der Bus frei ist (DAT auf Hi).
Dann muss manuell ein STOP erzeugt werden, dann wieder die PortPins auf 
IIC Funktion umschalten.

Es ist schon eine verfluchte fummelei wenn der Bus irgendwo im nirwana 
hängt bis der wieder geht.

Es gibt auch noch ein Reset-Bit mit dem man den gesammten IIC Controller 
reseten kann. (Siehe I2C_DeInit())

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.