Forum: Mikrocontroller und Digitale Elektronik STM32F4 I2C Problem


von Alex (Gast)


Lesenswert?

Hallo,

ich versuche gerade mit dem STM32F4 Discovery Board den MMA8452 
Beschleunigungssensor via I2C anzusprechen.
Allerdings passiert hier fast gar nichts.

Vielleicht erstmal das relevante Codeschnipsel:

1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOA, ENABLE);
2
3
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
4
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
5
6
  GPIO_InitTypeDef GPIO_InitStructure;
7
8
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
9
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
10
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
11
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
12
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
13
  GPIO_Init(GPIOB, &GPIO_InitStructure);
14
15
16
17
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
18
19
  I2C_InitTypeDef I2C_InitStruct;
20
21
  I2C_InitStruct.I2C_Ack = I2C_Ack_Disable;
22
  I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
23
  I2C_InitStruct.I2C_ClockSpeed = 100000;
24
  I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
25
  I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
26
  I2C_InitStruct.I2C_OwnAddress1 = 0;
27
28
  I2C_Init(I2C1, &I2C_InitStruct);
29
30
  I2C_Cmd(I2C1, ENABLE);
31
32
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
33
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
34
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
35
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
36
  GPIO_Init(GPIOA, &GPIO_InitStructure);
37
38
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
39
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
40
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
41
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
42
  GPIO_Init(GPIOA, &GPIO_InitStructure);
43
44
  while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0));  //Wait for USER BUTTON
45
46
47
48
      GPIO_SetBits(GPIOA, GPIO_Pin_5); //Trigger for analyzer
49
      I2C_GenerateSTART(I2C1, ENABLE);
50
51
      I2C_Send7bitAddress(I2C1, 0x3A, I2C_Direction_Transmitter);
52
53
      while(1);

Das Problem ist nun folgendes: Wenn ich mir die Busleitungen mit dem 
analyzer anschaue, dann sehe ich lediglich die start condition aber 
danach passiert nichts mehr, keinerlei Übertragung.

Ich hoffe, dass mir jemand helfen kann. Das hat mich gestern schon so 
frustriert!

Grüße,
Alex

von Mike R. (thesealion)


Lesenswert?

Ich weiß nicht genau, ob die F4 Serie die gleichen Probleme wie die F1 
mit dem I2C haben, aber ich vermute mal ja.

Wenn dem so ist, ist das einfachste die I2C Library von ST zu verwenden.

Wenn du es unbedingt per Hand machen willst, hier einmal mein Ausschnitt
für das senden der Adresse (Allerdings bei einem STM32F103)
1
   /*----- Transmission Phase -----*/
2
   /* Send I2Cx START condition */   
3
   I2C_Controller.I2Cx->CR1 |= CR1_START_Set;
4
  
5
   /* Test on I2Cx EV5 and clear it */
6
   while ((I2C_Controller.I2Cx->SR1&0x0001) != 0x0001)
7
      {
8
      if ( I2C_TimeOut == SystemTicks )
9
         {        
10
         return I2C_ERROR_START_ERROR;  
11
         }
12
      }
13
  
14
   /* Send slave address for write */
15
   /* Reset the address bit0 for write*/
16
   slaveAddr &= OAR1_ADD0_Reset;
17
   /* Send the slave address */
18
   I2C_Controller.I2Cx->DR = slaveAddr;

von Michael G. (let)


Lesenswert?

Sie soweit gut aus. Aber du sendest die Adresse sofort nach dem Start 
ohne das Setzen der Startbedingung abzuwarten.

Bei mir sieht das so aus (stm32f407):
1
while (I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
2
I2C_GenerateSTART(I2Cx, ENABLE);
3
while(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);

Und dann:
1
I2C_Send7bitAddress(I2Cx, addr, dir);
2
while (I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);

write:
1
I2C_SendData(I2Cx, data);
2
// wait for I2Cx EV8_2 --> byte has been transmitted
3
while (I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED) !=  SUCCESS);

von Alex (Gast)


Lesenswert?

Vielen Dank für die Antworten!

Es lag tatsächlich an dem nicht abwarten der Startbedingung! Jetzt sehe 
ich endlich was auf den Leitungen.
Gestern ist er da immer drin hänhen geblieben, deshalb hab ichs 
irgendwann einfach rausgeschmissen, da war aber wohl noch irgendwas 
anderes falsch!

Danke

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.