Forum: Mikrocontroller und Digitale Elektronik Atxmega TWI MPU6050


von ATXmega_Fan (Gast)


Lesenswert?

Hallo,

ich möchte gerne ein MPU6050-Modul auslesen. Leider bekomme ich per I2C 
nur
Null raus. Angelehnt ist das ganze an der App.-Note 1308.
1
#ifndef F_CPU
2
#define F_CPU 32000000UL
3
#endif
4
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <string.h>
8
#include <util/delay.h>
9
#include <stdlib.h>
10
#include "usart_driver.h"
11
#include "twi_master_driver.h"
12
#include "avr_compiler.h"
13
14
void init_board(void);
15
void my_itoa(int32_t zahl, char* string);
16
void Wakeup_MPU6050(void);
17
int Read_MPU6050_VALUE(unsigned char Reg);
18
19
// Uart Definitionen
20
#define USART USARTC0                // Uart Port C
21
USART_data_t USART_data;              // Uart Struktur
22
23
// I2C Definitionen
24
#define BAUDRATE    100000
25
#define TWI_BAUDSETTING TWI_BAUD(F_CPU, BAUDRATE)
26
TWI_Master_t twiMasterC;                // TWI master module
27
28
29
//*****************************************************************************
30
// Definitionen fuer MPU6050
31
#define MPU_6050    0x68            // I2C Adresse MPU6050
32
#define MPU_6050_ACC_X  0x3B            // Adresse 
33
#define MPU_6050_ACC_Y  0x3D            // Adresse
34
#define MPU_6050_ACC_Z  0x3F            // Adresse
35
#define MPU_6050_GYR_X  0x43            // Adresse
36
#define MPU_6050_GYR_Y  0x45            // Adresse
37
#define MPU_6050_GYR_Z  0x47            // Adresse
38
39
int ACC_X, ACC_Y,ACC_Z,GYRO_X,GYRO_Y,GYROZ;      // gelesene Werte
40
41
char Zahlenwert[10];
42
43
int main(void)
44
{
45
  init_board();
46
  Wakeup_MPU6050();
47
  usart_puts(&USART_data, "Starte\r\n");
48
  _delay_ms(3000);
49
  while (1)
50
    {
51
    ACC_X=Read_MPU6050_VALUE(MPU_6050_ACC_X);
52
    ACC_Y=Read_MPU6050_VALUE(MPU_6050_ACC_Y);
53
    ACC_Z=Read_MPU6050_VALUE(MPU_6050_ACC_Z);
54
    _delay_ms(2000);
55
    my_itoa(ACC_X, Zahlenwert);
56
    usart_puts(&USART_data, Zahlenwert);
57
    usart_puts(&USART_data, "  ");
58
    my_itoa(ACC_Y, Zahlenwert);
59
    usart_puts(&USART_data, Zahlenwert);
60
    usart_puts(&USART_data, "  ");
61
    my_itoa(ACC_Z, Zahlenwert);
62
    usart_puts(&USART_data, Zahlenwert);
63
    usart_puts(&USART_data, "\r\n  ");
64
    }
65
}
66
67
void Wakeup_MPU6050(void)
68
{
69
  uint8_t sendBuffer[8]={};
70
  sendBuffer[0]  = 0x6B;                // PWR_MGMT_1
71
  sendBuffer[1]  = 0x00;                // auf Null setzen
72
73
  TWI_MasterWriteRead( &twiMasterC, MPU_6050, &sendBuffer[0] , 2,0);
74
  while (twiMasterC.status != TWIM_STATUS_READY) {}
75
}
76
77
int Read_MPU6050_VALUE(unsigned char Reg)
78
{
79
  unsigned char lsb,msb;
80
  int Wert;
81
  uint8_t sendBuffer[8]={};
82
  sendBuffer[0]  = Reg;                // Register
83
84
  TWI_MasterWriteRead( &twiMasterC, MPU_6050, &sendBuffer[0] , 1,2);
85
  while (twiMasterC.status != TWIM_STATUS_READY) {}
86
  msb = twiMasterC.readData[0];          // read byte (msb)
87
  lsb = twiMasterC.readData[1];          // read byte (lsb)}
88
  Wert= (msb << 8) + lsb;
89
  return Wert;
90
}
91
92
void init_board(void)
93
{
94
  
95
  OSC.CTRL |= OSC_RC32MEN_bm;
96
  while(!(OSC.STATUS & OSC_RC32MRDY_bm));
97
  CCP = CCP_IOREG_gc;
98
  CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
99
100
  PORTF.DIRSET = PIN0_bm;
101
102
103
  PORTC.DIRSET = PIN3_bm; /* PD3 (TXD0) as output. */
104
  PORTC.DIRCLR = PIN2_bm; /* PD2 (RXD0) as input. */
105
  
106
107
  /* Use USARTC0 and initialize buffers. */
108
  USART_InterruptDriver_Initialize(&USART_data,&USART,USART_DREINTLVL_LO_gc);
109
  /* USARTC0, 8 Data bits, No Parity, 1 Stop bit. */
110
  USART_Format_Set(USART_data.usart,USART_CHSIZE_8BIT_gc,
111
  USART_PMODE_DISABLED_gc,false);
112
  /* Enable RXC interrupt. */
113
  USART_RxdInterruptLevel_Set(USART_data.usart, USART_RXCINTLVL_LO_gc);
114
  
115
  /* calculate Baudrate = (1/(16*(((I/O clock frequency)/Baudrate)-1) = 12 */
116
  /* BSEL[11:0]-Wert bei 32MHz Takt und BSCALE[3:0]==0: */
117
  /* 207 : 9600 */
118
  /* 103 : 19200 */
119
  /* 51 : 38400 */
120
  /* 34 : 57600 */
121
  /* 16 : 115200 */
122
  USART_Baudrate_Set(&USART, 16 , 0);
123
  
124
  /* Enable both RX and TX. */
125
  USART_Rx_Enable(USART_data.usart);
126
  USART_Tx_Enable(USART_data.usart);
127
  TWI_MasterInit(&twiMasterC, &TWIC, TWI_MASTER_INTLVL_HI_gc, TWI_BAUDSETTING);
128
129
    /* Enable PMIC interrupt level low. */
130
  PMIC.CTRL |= PMIC_HILVLEN_bm |PMIC_MEDLVLEN_bm|PMIC_LOLVLEN_bm;    //Interrupts (Highlevel,Mediumlevel und Lowlevel freigeben)
131
132
  sei();
133
}
134
135
136
void my_itoa(int32_t zahl, char* string)
137
{
138
  uint32_t u;
139
  
140
  if( zahl < 0 )
141
  {
142
    string[0] = '-';
143
    u = ((uint32_t)-zahl);
144
  }
145
  else
146
  {
147
    u = (uint32_t)zahl;
148
    string[0] = ' ';
149
  }
150
  
151
  for(uint8_t i=7; i>=1; i--)
152
  {
153
    // Modulo rechnen & ASCII von '0' addieren
154
    string[i]=(u % 10) +'0';
155
    u /= 10;
156
  }
157
  // String Terminator (optional)
158
  //string[11]='\0';
159
}
160
161
ISR(USARTC0_RXC_vect) // Interrupt Daten empfangen
162
{
163
  USART_RXComplete(&USART_data);
164
}
165
166
ISR(USARTC0_DRE_vect) // Interrupt Daten senden
167
{
168
  USART_DataRegEmpty(&USART_data);
169
}
170
171
ISR(TWIC_TWIM_vect)
172
{
173
  TWI_MasterInterruptHandler(&twiMasterC);
174
}

Vielleicht hat jemand eine Idee....

Gruß Sascha

von Uwe D. (monkye)


Lesenswert?

Der MPU6050 enthält 2 verschiedene Sensoren und beide werden nach dem 
Start zuerst initialisiert. Dieser Teil fehlt bei Dir.

Wenigstens ein Gyro-Reset, Powermanagement und Clocksource musst Du 
einstellen. Beachte dabei, dass die Register MSB first geliefert werden 
- sofern Du AVRs benutzt ist es aber LSB First.

Leider habe ich kein Datenblatt zu Hand, da sollte es aber so 
drinstehen.

Vielleicht kann ja ein ambitionierter Multikopter-Techniker helfen, da 
sind die Teile ja auch verbaut worden...

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.