Schönen Abend euch,
ich bin derzeit dabei, einen MPU6050 an meinem STM32F4 Discovery zum
laufen zu bekommen.
Vorerst wollte ich mal die Gyro-Daten auslesen, doch hier bekomme ich
nur 0-Werte zurück.
Hier ist meine Initialisierung:
1 | bool mpu_6050_init()
|
2 | {
|
3 | //Hier wird lediglich i2c initalisiert
|
4 | mpu_init_i2c();
|
5 |
|
6 | //Hier frage ich über das WHO-AM_I Register ab, ob die I2C Verbindung funktioniert
|
7 | if(!verify_mpu_6050_device())
|
8 | {
|
9 | return false;
|
10 | }
|
11 |
|
12 | //Um den IMU zu zurückzusetzen schreibe ich in das Power-Management-Register den Wert 0x80
|
13 | mpu_6050_reset();
|
14 | //Um den IMU aufzuwecken, schreibe ich in das Power-Management-Register den Wert 0x03,
|
15 | //sprich = PLL with Y axis gyroscope reference
|
16 | wakeup_mpu_6050();
|
17 |
|
18 | //Das Register für die ACC Config (0x1C) konfiguriere ich so:
|
19 | // ± 8g Full Scale Range
|
20 | set_accelerometer_config();
|
21 | //Das Register für die Gyro config (0x1B) konfiguriere ich so:
|
22 | // ± 2000 °/s Full Scale Range
|
23 | set_gyro_config();
|
24 |
|
25 | return true;
|
26 | }
|
Testweise habe ich die Werte von den Registern abgerufen, alle meine
Zugriffe wurden übernommen.
Die Gyro-Daten lese ich dann wie folgt aus:
1 | void mpu_6050_get_sensor_data(MPU_Sensor_Data* sensor_data)
|
2 | {
|
3 | uint8_t data[6];
|
4 | const uint8_t gyro_xout_h_register = 0x43;
|
5 |
|
6 | mpu_i2c_multi_read_register(gyro_xout_h_register, data, 6, mpu_slave_address);
|
7 | extract_gyro_sensor_data(data, sensor_data);
|
8 | }
|
In meinem I2C Modul sieht das ganze dann wie folgt aus:
1 | void mpu_i2c_multi_read_register(uint8_t register_name, uint8_t* data, uint16_t data_length, uint8_t slave_address)
|
2 | {
|
3 | i2c_start(I2C_Direction_Transmitter, slave_address, ENABLE);
|
4 | i2c_write_byte(register_name);
|
5 | i2c_stop();
|
6 | i2c_start(I2C_Direction_Receiver, slave_address, ENABLE);
|
7 |
|
8 | while(data_length--)
|
9 | {
|
10 | if(!data_length)
|
11 | {
|
12 | *data++ = i2c_read_nack();
|
13 | }
|
14 | else
|
15 | {
|
16 | *data++ = i2c_read_ack();
|
17 | }
|
18 | }
|
19 |
|
20 | i2c_stop();
|
21 | }
|
Ich schicke jedes mal ein Ack, außer beim letzten Wert, dort schicke ich
ein Nack.
ReadAck sowie ReadNack sehen dann so aus:
1 | static uint8_t i2c_read_nack()
|
2 | {
|
3 | I2C_AcknowledgeConfig(I2C3, DISABLE);
|
4 | wait_until_i2c_byte_received();
|
5 | return I2C_ReceiveData(I2C3);
|
6 | }
|
7 |
|
8 | static uint8_t i2c_read_ack()
|
9 | {
|
10 | I2C_AcknowledgeConfig(I2C3, ENABLE);
|
11 | wait_until_i2c_byte_received();
|
12 | return I2C_ReceiveData(I2C3);
|
13 | }
|
Nun stellt sich mir die Frage warum ich beim Funktionsaufruf
mpu_6050_get_sensor_data() nur NULL-Werte vom I2C Bus bekomme.
Ich habe hier zwei Vermutungen:
1. Irgendetwas stimmt mit meiner Initalisierung nicht
2. Ich mache was falsch, beim senden von Ack und Nack, bzw. Start und
Stop I2c
Ich habe mich an einigen Third-Party Libs orientiert und das beste
(meiner Meinung nach) von allen (etwas abgeändert) übernommen.
Besonders schwer macht es mir, dass so ziemlich jeder bei der
Initialisierung irgendwas anderes treibt.
Hat jemand eine Idee, ich wäre sehr dankbar.
Grüße