Forum: Mikrocontroller und Digitale Elektronik I2C an STM32F4 hängt beim Senden


von Robert (Gast)


Lesenswert?

Hallo,

ich bin gerade beim einarbeiten in den STM32F4. Dabei ferwende ich das 
STM32F4 Discovery Board. Zurzeit versuche ich I2C zum laufen zu bringen, 
scheitere aber daran, dass der STM32 nach dem Senden der Geräteadresse 
hängt.

Folgende Initialisierung verwende ich:
1
void i2c_init(void)
2
{
3
  GPIO_InitTypeDef GPIO_InitStructure;
4
  I2C_InitTypeDef I2C_InitStructure;
5
  
6
  // Enable Clk
7
  RCC_APB1PeriphClockCmd(IMU_I2C_CLK, ENABLE);
8
  RCC_AHB1PeriphClockCmd(IMU_I2C_SCL_GPIO_CLK | IMU_I2C_SDA_GPIO_CLK, ENABLE);
9
10
  // Performing a Reset
11
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
12
  RCC_APB1PeriphResetCmd(IMU_I2C_CLK, ENABLE);
13
  RCC_APB1PeriphResetCmd(IMU_I2C_CLK, DISABLE);
14
    
15
  // Remap Pins
16
  GPIO_PinAFConfig(IMU_I2C_SCL_GPIO_PORT, IMU_I2C_SCL_SOURCE, IMU_I2C_SCL_AF);
17
  GPIO_PinAFConfig(IMU_I2C_SDA_GPIO_PORT, IMU_I2C_SDA_SOURCE, IMU_I2C_SDA_AF);  
18
  
19
  // Initialize SCL
20
  GPIO_InitStructure.GPIO_Pin = IMU_I2C_SCL_PIN;
21
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
22
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
23
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
24
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
25
  GPIO_Init(IMU_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
26
27
  // Initialize SDA
28
  GPIO_InitStructure.GPIO_Pin = IMU_I2C_SDA_PIN;
29
  GPIO_Init(IMU_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
30
      
31
  // I2C configuration
32
  I2C_InitStructure.I2C_Mode        = I2C_Mode_I2C;
33
  I2C_InitStructure.I2C_DutyCycle   = I2C_DutyCycle_2;
34
  I2C_InitStructure.I2C_OwnAddress1 = 0;
35
  I2C_InitStructure.I2C_Ack         = I2C_Ack_Enable;
36
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
37
  I2C_InitStructure.I2C_ClockSpeed = 100000;
38
  
39
  I2C_Cmd(IMU_I2C, ENABLE);
40
  I2C_Init(IMU_I2C, &I2C_InitStructure);
41
}

Beim Versuch ein Byte zu senden, hängt STM32 bei 
while(!I2C_CheckEvent(I2C1, 
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
1
void i2c_write_buf(uint8_t address, uint8_t* buf, int32_t len)
2
{
3
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
4
  
5
  /* Send I2C1 START condition */
6
  I2C_GenerateSTART(I2C1, ENABLE);
7
  
8
  /* Test on I2C1 EV5 and clear it */
9
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
10
    
11
  /* Send slave Address for write */
12
  I2C_Send7bitAddress(I2C1, address, I2C_Direction_Transmitter);
13
  
14
  /* Test on I2C1 EV6 and clear it */
15
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //Hier hängt das I2C Modul
16
  
17
  while(len--)
18
  {
19
    /* Send I2C1 slave register address */
20
    I2C_SendData(I2C1, *buf++);
21
    
22
    /* Test on I2C1 EV8_2 and clear it */
23
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
24
  }
25
  
26
  /* Send I2C1 STOP Condition */
27
  I2C_GenerateSTOP(I2C1, ENABLE);  
28
}

Ich habe mich beim der Initialisierung sowie beim Senden and das 
Beispiel der Standard Peripheral Library gehalten. Am I2C Bus hängt ein 
Kompass-IC. Externe Pullups sind vorhanden.

Ich finde leider den Fehler nicht. Hat jemand eine Idee woran es liegen 
könnte?

Danke im Voraus
Robert

von Robert (Gast)


Lesenswert?

Als Hinweis noch. Ich verwende einen MPU6050 Sensor am I2C Bus mit der 
7-Bit Adresse 0x68. Beim Aufruf der Senderoutine verwende ich die um 
1-Bit nach links verschobene Adresse 0xD0.

von Robert (Gast)


Lesenswert?

Ich hab die Lösung gefunden. Leider hatte der Schaltplan den ich zum 
verwendeten MPU6050 Modul einen Fehler. Nach dem Durchklingeln der 
Platine fand ich heraus, dass der MPU6050 Adresse 0x69 verwendet!! Nun 
funktioniert alles :)

von John W. (halfpastseven)


Lesenswert?

Danke für deinen Beitrag hier!

Ich habe vorher noch nie I2C verwendet und hatte genau das selbe Problem 
mit dem hängen bleiben mit meinem STM32F4.

Lösung:
Die meisten Beispielprogramme vom I2C mit STM32F4 erwarten ein 
Acknowledge vom Slave, wenn dieses nicht empfangen wird werden die 
restlichen Daten nicht gesendet!
-> Slave muss angeschlossen sein und die Adresse muss stimmen!

Vielleicht hilft dieser Hinweis noch jemanden!

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.