Forum: Mikrocontroller und Digitale Elektronik I2C Kommunikation


von HeikoP (Gast)


Lesenswert?

Hallo. Ich brauche dringend Hilfe.

Ich habe das STM32VL Discovery, dort angeschlossen ist momentan ein LCD 
und ein Ultraschallsensor (SRF02).

LCD funktioniert alles.

Das Problem ist der SRF02, der über den I2C Bus angeschlossen ist.

Hier die Initialisierung
1
GPIO_InitTypeDef GPIO_InitStructure;
2
3
void I2C_InitConf(void)
4
{
5
  /* ************ Initialisierung/Konfiguration I2C ***************** */
6
  // I2C Konfiguration/Initialisierung
7
  I2C_InitTypeDef  I2C_InitStructure;
8
  
9
  // I2C clock enable
10
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
11
  // PORT B clock enable
12
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
13
  
14
  /* Konfiguration I2C1 Pins: SCL and SDA ----------------------------------------*/
15
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
16
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
17
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // Open Drain, I2C bus pulled high extern
18
  GPIO_Init(GPIOB, &GPIO_InitStructure);
19
  
20
  /* Enable I2C1 -------------------------------------------------------------*/
21
  I2C_Cmd(I2C1, ENABLE);
22
  
23
  /* I2C1 Konfiguration ------------------------------------------------------*/
24
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
25
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
26
  I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
27
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
28
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
29
  I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;
30
  I2C_Init(I2C1, &I2C_InitStructure);
31
}

Hier die Funktion fürs Senden:
1
void send(u8 *daten,int maxl)
2
{
3
  int i;
4
  /* Send I2C1 START condition */
5
  I2C_GenerateSTART(I2C1, ENABLE);
6
7
  /* Test on I2C1 EV5 and clear it */
8
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
9
10
  /* Send EEPROM slave Address for write */
11
  I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7, I2C_Direction_Transmitter);
12
13
  /* Test on I2C1 EV6 and clear it */
14
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
15
16
  /* Send I2C1 EEPROM internal address */
17
  for(i=0;i<maxl;i++)
18
  {
19
    I2C_SendData(I2C1, daten[i]);
20
  
21
    /* Test on I2C1 EV8 and clear it */
22
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
23
  }
24
  /* Send I2C1 STOP Condition */
25
  I2C_GenerateSTOP(I2C1, ENABLE);  
26
}

Und hier der Aufruf aus der main.c
1
...
2
u8 daten[5] = { 0x00,0xA0,0xAA,0xA5,0xE2 };
3
I2C_InitConf();
4
send(daten,5);
5
...

Beim Debuggen habe ich auch gesehen, das die Werte ins DR geschrieben 
werden, aber irgendwie bekommt der Slave die nicht.

Die Befehle, die in daten drin stehen sind die Befehlsfolge zum Ändern 
der Slave-Id, doch wenn ich den SRF02 danach neustarte, hat er immer 
noch die alte ID 0xE0.

Ich hoffe, mir kann irgendjemand einen Tipp geben, wie ich den I2C-Bus 
zum Laufen bekomme.

Vielen Dank, MfG Heiko

von HeikoP (Gast)


Lesenswert?

Wie muss ich die Registeradresse des SRF02 ansprechen, ebenfalls indem 
ich ein Datenwort mit der Registeradresse sende?

Leider ist in dem Datenblatt nichts dazu beschrieben oder gehen 
Schreibbefehle automatisch ans Register 0.

Wie teile ich dem SRF02 mit, aus welchem Register ich lesen möchte?
Vielen DAnk, MfG

von HeikoP (Gast)


Lesenswert?

So auslesen der Register scheint zu funktionieren. Bei Abfrage des 
Registers 1 bringt er h5 als Wert, was auch nach Google-Recherche mit 
der Software Firmware Revision übereinstimmt. Bei Abfrage des Registers 
1 sollte laut Datenblatt h80 geliefert werden, jedoch bekomme ich h18.
1
u8 read(int reg)
2
{ 
3
  u8 pBuffer;
4
  /*!< While the bus is busy */
5
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
6
 
7
  /*!< Send START condition */
8
  I2C_GenerateSTART(I2C1, ENABLE);
9
 
10
  /*!< Test on EV5 and clear it */
11
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
12
  
13
  /*!< Send EEPROM address for write */
14
  I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7, I2C_Direction_Transmitter);
15
16
  /*!< Test on EV6 and clear it */
17
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
18
19
  //send the reg select COMMAND byte
20
  I2C_SendData(I2C1, reg);   
21
 
22
  /*!< Test on EV8 and clear it */
23
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
24
 
25
  //send START condition a second time
26
  I2C_GenerateSTART(I2C1, ENABLE);
27
 
28
  /*!< Test on EV5 and clear it */
29
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
30
 
31
  /*!< Send EEPROM address for read */
32
  I2C_Send7bitAddress(I2C1, I2C1_SLAVE_ADDRESS7, I2C_Direction_Receiver);
33
 
34
  /*!< Test on EV6 and clear it */
35
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
36
 
37
  /*!< Disable Acknowledgement */
38
  I2C_AcknowledgeConfig(I2C1, DISABLE);
39
     
40
  /*!< Send STOP Condition */
41
  I2C_GenerateSTOP(I2C1, ENABLE);
42
43
  /*!< While there is data to be read */
44
  while ((I2C_GetLastEvent(I2C1) & 0x0040) != 0x000040); 
45
  
46
  /*!< Read a byte from the EEPROM */
47
  pBuffer = I2C_ReceiveData(I2C1);
48
49
  /*!< Enable Acknowledgement to be ready for another reception */
50
  I2C_AcknowledgeConfig(I2C1, ENABLE);
51
52
  return pBuffer;
53
}

Vielleicht kann sich ja mal jemand das anschauen, ob das vom Code her 
passt. Vielen Dank

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.