Forum: Mikrocontroller und Digitale Elektronik I2C Konfiguration STM32F4


von Student (Gast)


Lesenswert?

Abend,

ich habe Probleme damit den I2C Bus auf einem STM32 zum Laufen zu 
bekommen. Ich Arbeite mit der STD von STM sowie unter SW4STM. Meine 
Initialisierungsfunktion habe ich beigefügt.
1
void i2c_init(void)
2
{
3
  GPIO_InitTypeDef GPIO_InitStructure;
4
  NVIC_InitTypeDef NVIC_InitStructure;
5
  I2C_InitTypeDef I2C_InitStructure;
6
7
  SystemInit();
8
9
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
10
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
11
  RCC_AHB1PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
12
13
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
14
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
15
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
16
  GPIO_Init(GPIOB, &GPIO_InitStructure);
17
18
  //GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
19
20
  NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
21
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
22
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
23
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
24
  NVIC_Init(&NVIC_InitStructure);
25
26
  NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
27
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
28
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
29
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
30
  NVIC_Init(&NVIC_InitStructure);
31
32
  I2C_DeInit(I2C1);
33
34
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
35
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
36
  I2C_InitStructure.I2C_ClockSpeed = 100000;
37
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
38
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
39
  I2C_InitStructure.I2C_OwnAddress1 = 0;
40
  I2C_Init(I2C1, &I2C_InitStructure);
41
42
  I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
43
  I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
44
  I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
45
46
  I2C_Cmd(I2C1, ENABLE);
47
}

Probleme verursacht:
1
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
Hier finde ich in der Definition der Funktion keinerlei äquivalentes 
Argument, es ist so wie es dort im Aufruf steht nicht bekannt.

Für
1
  GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
 fehlt mir leider der Ersatz. Die Initialisierung habe ich von einer 
Internetseite größtenteils übernommen und angepasst auf den Controller. 
Bei diesen zwei Problemen komme ich nun schon länger nicht weiter und 
weiß auch nicht so recht in welchem Dokument ich dies erfahren kann. 
Daher bitte ich mir auch einen Tipp zu geben, wo ich es hätte selbst 
finden können. Ich bin was diese Thematik angeht noch recht unerfahren 
und hoffe dass ich bald Land sehen werde.

Freundliche Grüße!

von Dr. Sommer (Gast)


Lesenswert?

Student schrieb:
> und
> weiß auch nicht so recht in welchem Dokument ich dies erfahren kann.
Im STM32F4 Reference Manual. Da steht das genau erklärt. Der Code ist 
für den STM32F1, da funktioniert die Pin-Zuordnung anders. Beim F4 
funktioniert das nicht über "Remapping" sondern über die "Alternate 
Function" Konfiguration der einzelnen Pins. Also erst Anleitung lesen, 
dann Beispiele kopieren.

Du möchtest das I²C asynchron (mit Interrupts) nutzen? Viel Spaß, das 
ist sehr kompliziert. Und wenn du schon an der Pin-Konfiguration 
scheiterst...

von Student (Gast)


Lesenswert?

Wie kann ich das I2C sonst nutzen? Alternativ könnte ich mir vorstellen 
es rudimentär über GPIO's zu lösen. Letztendlich muss ich zyklisch über 
dem I2C Bus mit einem Sensor kommunizieren (Befehl Messung Starten / 
Messwert ausgeben, Auslesen der Ausgabe). Wie könnte ich dies denn 
simpler machen?

von Dr. Sommer (Gast)


Lesenswert?

Student schrieb:
> Wie kann ich das I2C sonst nutzen?
Na synchron, ohne Interrupts. Man fragt in Warteschleifen ab, ob das 
jeweilige Event schon eingetreten ist. Das geht z.B. über die Funktionen 
HAL_I2C_Master_Transmit / HAL_I2C_Master_Receive. Siehe dazu die 
Beispiele von ST selbst für den STM32F4, die bei der HAL mitgeliefert 
sind. Ist so dann halt ineffizient (Energie/Laufzeit) aber einfach.

von Student (Gast)


Lesenswert?

Ich habe den Rest bisher mit der Standard periphery library von STM 
umgesetzt, es fehlt quasi nur noch die Abfrage des Sensors. Weiß jemand, 
ob es auch mit dieser eine derart simple Möglichkeit gibt?

von Dr. Sommer (Gast)


Lesenswert?

Student schrieb:
> Weiß jemand,
> ob es auch mit dieser eine derart simple Möglichkeit gibt?

Warum öffnest du nicht mal den dazugehörigen Header und schaust nach? 
Oder vielleicht sogar die mitgelieferten Beispielcodes?

von Harry L. (mysth)


Lesenswert?

Wenn du schon SW4STM32 nutzt, warum dann nicht auch CubeMX?
Der generiert dir korrekten Initialisierungs-Code für I²C, und du kannst 
alles Relevante (Speed, Adressmode etc) einstellen.

Damit ist das in wenigen Minuten erledigt.
Lief bei mir auf Anhieb.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.