Forum: Mikrocontroller und Digitale Elektronik XMega128D3 TWI/I2C bleibt plötzlich hängen


von Patrick (Gast)


Lesenswert?

Hallo Controller-Gemeinde,

ich versuche gerade kläglich mithilfe eines XMega128 eine stabile 
Kommunikation mit einem Gyro/ACC MPU6050 aufzubauen. Hierzu habe ich die 
Treiber von Atmel (twi_master_driver) verwendet.

Nach dem Schreiben bzw. einem Reset werden die Daten auch für eine 
gewisse Zeit(immer unterschiedlich, aber im Bereich von 10-30s) 
ordnungsgemäß vom Sensor gelesen. Nach eben dieser Zeit bleibt der 
Controller in der

while(twiMaster->status != TWIM_STATUS_READY);

hängen. Ich hab an allen Ecken und Enden rumprobiert und komm einfach 
nicht weiter. Habt ihr Ratschläge oder Vermutungen, wonach ich suchen 
muss bzw. was ich ändern kann, damit die Verbindung stabil läuft?

Vielen Dank und freundliche Grüße

von Michi (Gast)


Lesenswert?

Fehler in Zeile 42

von Patrick (Gast)


Lesenswert?

Servus,

wie soll ich mit dieser Information umgehen?

von Michi (Gast)


Lesenswert?

Patrick schrieb:
> wie soll ich mit dieser Information umgehen?

Lass einfach die Hose runter und zeige den Code (mit .c als Extension) 
als Anhang.

von Patrick (Gast)


Lesenswert?

Dies ist die Funktion mit der die Daten vom Sensor geholt werden:
1
void readMPU6050(TWI_MSTR_t *twiMaster)
2
{
3
  int intTemperature;
4
  
5
  sendBuffer[0] =  MPU6050_RA_GYRO_XOUT_H;
6
  sendBuffer[1] =  MPU6050_RA_GYRO_XOUT_L;
7
  
8
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[0],1);
9
  while(twiMaster->status != TWIM_STATUS_READY);
10
  
11
  
12
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
13
  while(twiMaster->status != TWIM_STATUS_READY);
14
15
  MPU6050.gyro[X_AXIS] = (int16_t)twiMaster->readData[0];
16
  
17
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[1],1);
18
  while(twiMaster->status != TWIM_STATUS_READY);
19
  
20
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
21
    while(twiMaster->status != TWIM_STATUS_READY);
22
  
23
  MPU6050.gyro[X_AXIS] = (int16_t)((MPU6050.gyro[X_AXIS] <<8 | twiMaster->readData[0])/32.8);
24
  
25
  
26
  
27
  sendBuffer[0] =  MPU6050_RA_GYRO_YOUT_H;
28
  sendBuffer[1] =  MPU6050_RA_GYRO_YOUT_L;
29
  
30
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[0],1);
31
  while(twiMaster->status != TWIM_STATUS_READY);
32
  
33
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
34
  while(twiMaster->status != TWIM_STATUS_READY);
35
  
36
  MPU6050.gyro[Y_AXIS] = (int16_t)twiMaster->readData[0];
37
  
38
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[1],1);
39
  while(twiMaster->status != TWIM_STATUS_READY);
40
  
41
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
42
  while(twiMaster->status != TWIM_STATUS_READY);
43
  
44
  MPU6050.gyro[Y_AXIS] = (int16_t)((MPU6050.gyro[Y_AXIS] <<8 | twiMaster->readData[0])/32.8);
45
  
46
  
47
  sendBuffer[0] =  MPU6050_RA_GYRO_ZOUT_H;
48
  sendBuffer[1] =  MPU6050_RA_GYRO_ZOUT_L;
49
  
50
  
51
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[0],1);
52
  while(twiMaster->status != TWIM_STATUS_READY);
53
  
54
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
55
  while(twiMaster->status != TWIM_STATUS_READY);
56
  
57
  MPU6050.gyro[Z_AXIS] = (int16_t)twiMaster->readData[0];
58
  
59
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[1],1);
60
  while(twiMaster->status != TWIM_STATUS_READY);
61
  
62
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
63
  while(twiMaster->status != TWIM_STATUS_READY);
64
  
65
  MPU6050.gyro[Z_AXIS] = (int16_t)((MPU6050.gyro[Z_AXIS] <<8 | twiMaster->readData[0])/32.8);
66
  
67
  
68
  sendBuffer[0] =  MPU6050_RA_ACCEL_XOUT_H;
69
  sendBuffer[1] =  MPU6050_RA_ACCEL_XOUT_L;
70
  
71
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[0],1);
72
  while(twiMaster->status != TWIM_STATUS_READY);
73
  
74
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
75
  while(twiMaster->status != TWIM_STATUS_READY);
76
  
77
  MPU6050.acc[X_AXIS] = (int16_t)twiMaster->readData[0];
78
  
79
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[1],1);
80
  while(twiMaster->status != TWIM_STATUS_READY);
81
  
82
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
83
  while(twiMaster->status != TWIM_STATUS_READY);
84
  
85
  MPU6050.acc[X_AXIS] = (int16_t)((MPU6050.gyro[X_AXIS] <<8 | twiMaster->readData[0])/4.096);
86
  
87
  
88
  sendBuffer[0] =  MPU6050_RA_ACCEL_YOUT_H;
89
  sendBuffer[1] =  MPU6050_RA_ACCEL_YOUT_L;
90
  
91
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[0],1);
92
  while(twiMaster->status != TWIM_STATUS_READY);
93
  
94
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
95
  while(twiMaster->status != TWIM_STATUS_READY);
96
  
97
  MPU6050.acc[Y_AXIS] = (int16_t)twiMaster->readData[0];
98
  
99
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[1],1);
100
  while(twiMaster->status != TWIM_STATUS_READY);
101
  
102
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
103
  while(twiMaster->status != TWIM_STATUS_READY);
104
  
105
  MPU6050.acc[Y_AXIS] = (int16_t)((MPU6050.gyro[Y_AXIS] <<8 | twiMaster->readData[0])/4.096);
106
  
107
  
108
  sendBuffer[0] =  MPU6050_RA_ACCEL_ZOUT_H;
109
  sendBuffer[1] =  MPU6050_RA_ACCEL_ZOUT_L;
110
  
111
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[0],1);
112
  while(twiMaster->status != TWIM_STATUS_READY);
113
  
114
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
115
  while(twiMaster->status != TWIM_STATUS_READY);
116
  
117
  MPU6050.acc[Z_AXIS] = (int16_t)twiMaster->readData[0];
118
  
119
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[1],1);
120
  while(twiMaster->status != TWIM_STATUS_READY);
121
  
122
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
123
  while(twiMaster->status != TWIM_STATUS_READY);
124
  
125
  MPU6050.acc[Z_AXIS] = (int16_t)((MPU6050.gyro[Z_AXIS] <<8 | twiMaster->readData[0])/4.096);
126
  
127
  sendBuffer[0] =  MPU6050_RA_TEMP_OUT_H;
128
  sendBuffer[1] =  MPU6050_RA_TEMP_OUT_L;
129
  
130
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[0],1);
131
  while(twiMaster->status != TWIM_STATUS_READY);
132
  
133
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
134
  while(twiMaster->status != TWIM_STATUS_READY);
135
  
136
  intTemperature = (int16_t)twiMaster->readData[0];
137
  
138
  TWI_MasterWrite(twiMaster,MPU6050_ADDRESS,&sendBuffer[1],1);
139
  while(twiMaster->status != TWIM_STATUS_READY);
140
  
141
  TWI_MasterRead(twiMaster,MPU6050_ADDRESS,1);
142
  while(twiMaster->status != TWIM_STATUS_READY);
143
  
144
  intTemperature = (int16_t)((intTemperature <<8 | twiMaster->readData[0])/4.096);
145
  
146
  MPU6050.temperature = (float)intTemperature/340.0+36.53;
147
  
148
  
149
}

von Patrick (Gast)


Lesenswert?

Hier die main:
1
#define F_CPU 32000000UL
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <string.h>
6
#include <stdint.h>
7
#include <stdbool.h>
8
#include <avr/interrupt.h>
9
#include "twi_master_driver.h"
10
#include "GyroAcc.h"
11
12
13
TWI_MSTR_t twiMaster;
14
15
16
ISR(TWIC_TWIM_vect)
17
{
18
  TWI_MasterInterruptHandler(&twiMaster);
19
}
20
21
void setClockTo32MHz() {
22
 
23
  
24
  OSC.CTRL |= OSC_RC32MEN_bm;
25
  while(!(OSC.STATUS & OSC_RC32MRDY_bm));
26
  CCP = CCP_IOREG_gc;
27
  CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
28
}
29
30
int main(void)
31
{
32
  
33
  setClockTo32MHz();
34
 
35
 
36
  
37
  PORTC.DIRSET   |= PIN0_bm;  // Als Ausgang  TWI SDA
38
  PORTC.DIRSET   |= PIN1_bm;   // Als Ausgang TWI SCL
39
  
40
  
41
  setup_MPU6050(&twiMaster);
42
  test_MPU6050(&twiMaster);
43
  
44
    while(1)
45
    {
46
       
47
    readMPU6050(&twiMaster);
48
  
49
    }
50
}

initialisiert wird das TWI-Modul mit:
1
TWI_MasterInit(twiMaster,&TWIC,TWI_MASTER_INTLVL_HI_gc(F_CPU/(2*100000))-5;
2
PMIC.CTRL |= PMIC_HILVLEN_bm |PMIC_MEDLVLEN_bm|PMIC_LOLVLEN_bm;
3
sei();

Die Daten werden über die UART Schnittstelle rausgegeben(hab ich hier 
aber weggelassen)

von Christian H. (christian_h)


Lesenswert?

Bin mir nicht sicher, scheint aber ein Hardwarebug zu sein, wie im 
Thread Beitrag "ATXMega, TWI (I2C) bleibt hängen" besprochen wurde. 
Schau mal da rein.

Gruß,
Christian

von Patrick (Gast)


Lesenswert?

Danke für die Antwort!

Den Beitrag hatte ich auch schon gelesen, aber eine wirkliche Lösung ist 
dabei ja nicht rausgekommen. Den Hi-Level Interrupt verwende ich ja, wie 
im letzten Post des Beitrages beschrieben...

von Jackfritt (Gast)


Lesenswert?

Glaube ich nich. Bus probleme. Timer mit in die while aufnehmen. Hat bei 
mir geholfen.

von Thomas F. (tomasf)


Lesenswert?

Du solltest erstmal den Code vereinfachen, deine ganze Kommunikation 
kannst Du auf etwa folgendes zusammenfassen.
1
uint8_t writeData[1];
2
writeData[0] = AX;
3
RETURN_ON_TWI_ERROR(waitForTWIReady());
4
if (!TWI_MasterWriteRead(twiMaster, I2CADDRESS, writeData, 1, 14)) return 1;
5
RETURN_ON_TWI_ERROR(waitForTWIReady());

In welcher Zeile genau bleibt denn Dein Code hängen?
Wie ist der Sensor mit dem xmega verbunden?
Wie ist im Fehlerfall der TWI-Status?

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.