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
Patrick schrieb: > wie soll ich mit dieser Information umgehen? Lass einfach die Hose runter und zeige den Code (mit .c als Extension) als Anhang.
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 | }
|
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)
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
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...
Glaube ich nich. Bus probleme. Timer mit in die while aufnehmen. Hat bei mir geholfen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.