Forum: Mikrocontroller und Digitale Elektronik i2c_start() Problem


von DanielM. (Gast)


Lesenswert?

Guten Abend,

ich versuche gerade mit dem STK500 über i2c den MPU6050 auszulesen.
Leider scheitert es schon beim starten.
Gibt es möglicherweiße irgendwas STK500 spezifischen, damit i2c dort 
auch funktioniert? Hat jemand sonst noch irgendwelche Ideen, wie ich dem 
Problem auf die Schliche kommen kann?

Wie ich sehe, sind auf dem Sensorboard bereits die PullUps drauf:
https://docs.google.com/file/d/0B3ASxBYiXsrDX3oyMzhfLWtiTkE/image?pagenumber=1&w=800 
(R1 und R2).
Das kann also schonmal ausgeschlossen werden.

Vom Code her kann da eigentlich auch nicht viel falsch sein,
da ich Peter Fleurys Code benutze.

Die i2c_start habe ich nur etwas verändert, damit ich sehe, wo er 
abbricht (zweites return 1 => return 2):
1
unsigned char i2c_start(unsigned char address)
2
{
3
    uint8_t   twst;
4
5
  // send START condition
6
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
7
8
  // wait until transmission completed
9
  while(!(TWCR & (1<<TWINT)));
10
11
  // check value of TWI Status Register. Mask prescaler bits.
12
  twst = TW_STATUS & 0xF8;
13
  if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
14
15
  // send device address
16
  TWDR = address;
17
  TWCR = (1<<TWINT) | (1<<TWEN);
18
19
  // wail until transmission completed and ACK/NACK has been received
20
  while(!(TWCR & (1<<TWINT)));
21
22
  // check value of TWI Status Register. Mask prescaler bits.
23
  twst = TW_STATUS & 0xF8;
24
  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 2; // Hier tritt immer der Fehler auf!
25
26
  return 0;
27
28
}
1
int main(void)
2
{
3
  unsigned char ret;
4
  
5
  uart_init();
6
  
7
    i2c_init();
8
  
9
  delay_ms(1000);
10
  
11
  ret = i2c_start(adrMPU6050/*+I2C_WRITE*/);
12
13
  switch(ret) {
14
    case 0:    uart_puts("Works!\n"); break;
15
    case 1:    uart_puts("Error1!\n"); break;
16
    case 2:    uart_puts("Error2!\n"); break;
17
    default:  uart_puts("Something else ... \n"); break;
18
  }    
19
  
20
    i2c_stop();
21
  
22
    for(;;);  
23
}

Kann es sein, dass ich mit #define SCL_CLOCK  100000L die Taktrate zu 
groß/klein gewählt habe?

Ansonsten bin ich mit meinem Latein am Ende.
Irgendwelche Ideen um den Fehler einzugrenzen?

Liebe Grüße!

PS: Das Datenblatt gibt es hier:
http://invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf

von DanielM. (Gast)


Lesenswert?

Übrigends:

Ein "Error2" wird auch ausgegeben, wenn ich ein anderen Sensor nehme 
oder die Adresse überhaupt nicht funktioniert.

von Stefan (Gast)


Lesenswert?

Welchen Wert benutzt du für adrMPU6050?

Ansonsten würde ich die Software I2C Implementierung von Peter Fleury 
benutzen. TWI für ein I2C Master bringt meines Erachtens keinen Vorteil. 
Man ist dagegen auf die beiden TWI Pins angewiesen und der Code ist 
sogar größer.

von (prx) A. K. (prx)


Lesenswert?

Was steht denn dann in TW_STATUS tatsächlich drin?

Adressbits verschoben? Da gibts zwei Konventionen, eine betrachtet die 7 
Bits der Adresse und das R/W Bit separat, die andere kombiniert es.

Das Datasheet verwendet die 7-Bit Konvention 110100X = 0x68, die 
Software die 8-Bit Konvention 110100XW = 0xD0 (bei AD=0).

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.