Problem mit I2C scan auf Adresse von HTU21D

OP #5921486
Lesenswert?

Hallo,

ich programmiere gerade die I2C-Schnittstelle (Controller = STM32L476RG) 
zum HTU21D Sensor. Als IDE verwende ich Atollic Truestudio.

Mit dem folgenden Codeschnippsel frage ich die Adresse (sollte lt. 
Datenblatt eigentlich 0x40 sein) ab.

Für die Abfrage verwende ich eine HAL-Funktion und übergebe als 
Parameter i für die Adresse. Die Variable i ist global und beginnt bei 
0:
1
  /**
2
    * @brief  Checks if target device is ready for communication.
3
    * @note   This function is used with Memory devices
4
    * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains the configuration information for the specified I2C.
5
    * @param  DevAddress Target device address: The device 7 bits address value in datasheet must be shifted to the left before calling the interface
6
    * @param  Trials Number of trials
7
    * @param  Timeout Timeout duration
8
    * @retval HAL status
9
    */
10
  for (; i<255; i++)
11
  {
12
    if(HAL_I2C_IsDeviceReady(&hi2c1, i, 1, 10) ==  HAL_OK)
13
    {
14
      HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
15
      break;
16
    }
17
  }

Das seltsame dabei ist, dass HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); nie 
ausgeführt wird (Das Programm bleibt hier auch bei einem Breakpoint 
nicht stehen). Die Abfrage wird aber bei i=128 (0x80) beendet.
Gast #5921508
Lesenswert?

Welchen Typ hat i und mit welchem Startwert fängst du an?

Ist Dir bewusst, dass I²C Adressen normalerweise nur 7 Bits haben, also 
niemals den Wert 255 haben können?

Dass dein Pin nie getoggelt wird könnte schlicht daran liegen, dass dein 
Sensor nicht antwortet.

Ich würde Dir empfehlen, die Kommunikation mit einem "8ch logic 
analyzer" zu untersuchen. Was du auch noch ganz fix prüfen solltest, ist 
die Spannung an SDA und SCL. Beide Leitungen müssen vor und nach dem 
Programm-Ablauf auf High Pegel liegen, also deutlich mehr als 2 Volt.
#5921588
Lesenswert?

nun eine Möglichkeit die immer gehen wird wäre z.B die Variable lokal 
als static zu definieren. Und ja mir ist durchaus bekannt dass so ein 
Konstrukt auch eine globale Var erzeugt die halt nur lokal sichtbar ist.

Beispiel:
1
char foo(void)
2
{
3
  char static i = 0;
4
  ...
5
  return i;
6
}
#5921599
Lesenswert?

M. G. schrieb:
> Das ist die Übertragung
> der Adresse 0x40.

und mit 64d kleiner als 127 0x7f

also warum?

M. G. schrieb:
> for (; i<255; i++)

wenn es eh höhere Adressen gibt I2C Erweiterung muss man die oberhalb 
anders ansprechen.....
http://gedankenlyrik.bplaced.net/www/studium/seminararbeit_2008.pdf

nun gilt noch zu klären wie deine SW I2C ansprechen möchte,

entweder mit 7-bit
1
  for(address = 1; address < 127; address++ ) 
2
  { //The i2c_scanner uses the return value of
3
    //the Write.endTransmisstion to see if
4
    //a device did acknowledge to the address.
5
    Wire.beginTransmission(address);
6
    error = Wire.endTransmission();
7

8
    if (error == 0)
9
    { DEBUG_PRINT(F("I2C found at Add. 0x"));

oder mit 8-bit +R/W
1
if(!i2c_start(PCF8574A_0+I2C_READ))  //;  // set device address and write mode
OP #5921649
Lesenswert?

Stefanus F. schrieb:
> M. G. schrieb:
>> Ich interpretiere das als START - 0100 0000 ACK - STOP
>
> Das neunte Bit hat High Pegel, das ist ein NACK. Dein Sensor hat nicht
> geantwortet.

Danke für die Info! Das habe ich wohl falsch interpretiert... 1 = NACK, 
0 = ACK.

Die Initialisierung habe ich über CubeMX gemacht. Eingestellt ist eine 
7-Bit Adressierung.
1
  hi2c1.Instance = I2C1;
2
  hi2c1.Init.Timing = 0x10909CEC;
3
  hi2c1.Init.OwnAddress1 = 0;
4
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
5
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
6
  hi2c1.Init.OwnAddress2 = 0;
7
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
8
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
9
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

Ich habe jetzt 3 Sensoren mit unterschiedlichen Pull-up Widerständen 
(2k2, 4k7 und 10k) getestet.
OP #5921660
Lesenswert?

Wer lesen kann ist klar im Vorteil...

The device 7 bits address value in datasheet must be shifted to the left 
before calling the interface.

Naja, eine gemeine Falle

1
/**
2
  * @brief  Checks if target device is ready for communication.
3
  * @note   This function is used with Memory devices
4
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5
  *                the configuration information for the specified I2C.
6
  * @param  DevAddress Target device address: The device 7 bits address value
7
  *         in datasheet must be shifted to the left before calling the interface
8
  * @param  Trials Number of trials
9
  * @param  Timeout Timeout duration
10
  * @retval HAL status
11
  */
12
HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
Gast #5921663
Lesenswert?

M. G. schrieb:
> The device 7 bits address value in datasheet must be shifted to the left
> before calling the interface.

Guter Hinweis,
dann hätte der Sensor auf die Adresse 0x80 (128) reagieren müssen.

was zu dieser Aussage passt:

> Die Abfrage wird aber bei i=128 (0x80) beendet.

M.G. vielleicht musst du einfach noch ein bisschen üben, den Debugger zu 
bedienen!? Fange mal damit, die Optimierungsstufe des Compilers auf -Og 
oder -O0 zu ändern. Hat deine Projekt nicht genau dafür zwei 
unterschiedliche Konfigurationen vorbereitet? Zumindest bei der System 
Workbench wäre das standardmäßig der Fall.

Siehe 
http://blog.atollic.com/how-to-create-and-modify-a-build-configuration-video-tutorial

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren