XMega128D3 TWI/I2C bleibt plötzlich hängen

Gast #3175782
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
Gast #3175796
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
}
Gast #3175800
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)
Gast #3175826
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...
#3177657
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?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.