HAL I2C Daten empfangen? STM32 Nucleo

OP #7127090
Lesenswert?

Hallo,

Ich versuche über ein Nucleo32 Board (STM32G431) per I2C Daten von einem 
BNO055 Sensor zu empfangen. Wenn ich mich nicht täusche muss ich doch 
dafür einmal HAL_I2C_Master_Transmit ausführen und dabei das Register 
mitschicken, welches ich auslesen will, und im Anschluss mit 
HAL_I2C_Master_Receive die Daten empfangen. Oder funktioniert das so 
nicht?

Im Folgenden ist mein Code in der void main:
1
HAL_StatusTypeDef ret;
2
uint8_t  buf[16];
3
uint8_t output[16];
4

5
// hier ist bisschen was autogenerated
6

7
buf[0] = 0x3D;  // Register zum Ändern des Operationmodes
8
buf[0] = 0b00001001 >> 8;        // Operationmode auf COMPASS stellen
9
ret = HAL_I2C_Master_Transmit(&hi2c1, BNO055_ADDR, buf, 2, HAL_MAX_DELAY);
10
HAL_Delay(10);  // es dauert 7ms, den Operationmode von CONFIG auf COMPASS zu stellen
11

12
while(1) {
13
   buf[0] = 0x0E;  // Register MAG_DATA_X_LSB
14
   ret = HAL_I2C_Master_Transmit(&hi2c1, BNO055_ADDR, buf, 1, HAL_MAX_DELAY);
15
   ret = HAL_I2C_Master_Receive(&hi2c1, BNO055_ADDR, output, 1, HAL_MAX_DELAY);
16

17
   sprintf((char*)buf, "%u\r\n", (unsigned int) output[0]);
18
   HAL_UART_Transmit(&huart2, buf, strlen((char*)buf), HAL_MAX_DELAY);
19

20
   HAL_Delay(50);
21
}

Ich hab mich mit den Registern an das Manual vom BNO055 gehalten.
https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bno055-ds000.pdf#%5B%7B%22num%22%3A149%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C68%2C744%2C0%5D

Alle was übers UART ausgegeben wird ist 0.
Nach den I2C Abfragen hab ich jeweils gecheckt, ob
1
ret == HAL_OK
 und falls nicht einen Fehler ausgegeben. Das passt aber scheinbar 
immer, also irgendwas kommt wohl zurück.
Leider weiß ich auch nicht, ob mein Fehler im I2C selber liegt, oder ob 
ich was wichtiges im Manual überseh und einfach den Sensor falsch bedien 
:( Aber vielleicht findet ja wer direkt was.

Ich hoffe mir kann jemand helfen, ich hab leider noch nicht sehr viel 
Ahnung..
#7127127
Lesenswert?

Ich habe das vor langer Zeit mal gemacht. (aber per interrupt). Das lief 
über die HAL mit der Funktion:


ret = HAL_I2C_Mem_Read_IT(p->hi2c, ACC_ADDR<<1, 0x12, 
I2C_MEMADD_SIZE_8BIT, ...

Gibt es auch ohne It, heisst dann HAL_I2C_Mem_Read() Das könnte Dein 
Kandidat für die while loop werden. Dann hast Du auch nur eine Funktion, 
die Du aufrufen musst.

Ich mach nix mehr mit stm32, weil ich die Dinger nicht kaufen kann.

Viel Spaß noch

Martin
Gast #7127522
Lesenswert?

Moin,
ich hatte auch das selbe Problem.
Ich habe auch versucht zuerst transmit und dann recieve zu nehmen.
Mit einem Logic Analyser hab ich gesehen dass das nicht gehen kann.
Habe dann mem_read genommen und dann ging es problemlos.
Mann kann dann auch angeben ob man ein Register oder mehrere auslesen 
will.

Gruß Eckard
Gast #7127578
Lesenswert?

1
buf[0] = 0x3D;  // Register zum Ändern des Operationmodes
2
buf[0] = 0b00001001 >> 8;        // Operationmode auf COMPASS stellen
was soll der Blödsinn?
Wenn man ein uint8_t um acht Bit nach rechts verschiebt, hat es den Wert 
0.
Damit dann noch das erste Byte des des Arrays überschreiben???
OP #7127671
Lesenswert?

STK500-Besitzer schrieb:
>
1
> buf[0] = 0x3D;  // Register zum Ändern des Operationmodes
2
> buf[0] = 0b00001001 >> 8;        // Operationmode auf COMPASS stellen
3
>
> was soll der Blödsinn?
> Wenn man ein uint8_t um acht Bit nach rechts verschiebt, hat es den Wert
> 0.
> Damit dann noch das erste Byte des des Arrays überschreiben???

Das ist es. Keine Ahnung, ich dachte irgendwie, dadurch wird das 
sozusagen an die 2. Stelle vom buf-Array verschoben... dämlich, aber 
ok.. Jetzt funktionierts.

Danke auch an alle anderen für Ideen, ich werd auch die anderen 
Vorschläge mal ausprobieren!

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