Forum: Mikrocontroller und Digitale Elektronik I2C/TWI zwischen ATmega16 und PCA9685 funktioniert nicht


von Johannes R. (jr17oo)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

um per Mikrocontroller mehrere RGB-LEDs gezielt ansteuern zu können habe 
ich mir einige NXP PCA9685 beschafft. In einem ersten Versuch will ich 
nun die Kommunikation zwischen einem ATmega16 und einem der 
PCA9685-Chips testen, leider bislang erfolglos. Mit TWI/I2C habe ich 
noch nie gearbeitet, denke aber das zugrunde liegende Konzept verstanden 
zu haben.

Meine Konfiguration:
* PCA9685 auf selbstgeätztem "Breakout-Board"
  -> A0 auf Vcc
  -> A1, A2, A3, A4, A5 EXTCLK und OE auf GND
* ATmega16 steckt in STK500
  -> PC0 (SCL) per 4k7 Ohm an Vcc und an Pin 26 des PCA9685
  -> PC1 (SDA) per 4k7 Ohm an Vcc und an Pin 27 des PCA9685

Das Testprogramm habe ich angehängt. Der Code entstammt im wesentlichen 
dem hiesigen Tutorial:
http://www.mikrocontroller.net/articles/AVR_TWI

Das Problem ist nun, dass das Programm bereits beim Senden der 
START-Bedingung in der Funktion i2c_send() "hängenbleibt".
1
void i2c_send (uint8_t adresse, uint8_t anzahl_datenbytes) {
2
  // I2C-Bus initialisieren und START-Bedingung senden
3
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
4
  PORTD |= (1 << PD5);      // <-- Befehl an dieser Stelle wird ausgeführt
5
  while  (!(TWCR & (1<<TWINT)));
6
  PORTD |= (1 << PD6);      // <-- Befehl an dieser Stelle wird NICHT ausgeführt
7
8
9
  // Ziel-Slave adressieren
10
  if ((TWSR & 0xF8) != TW_START)
11
    ERROR();      // Fehlerbehandlung
12
  TWDR = adresse + I2C_WRITE;
13
  TWCR = (1<<TWINT) | (1<<TWEN);
14
  while (!(TWCR & (1<<TWINT)));
15
16
  // Daten übertragen
17
  for (uint8_t i = 0; i < anzahl_datenbytes; i++) {
18
    if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
19
      ERROR();
20
    TWDR = i2c_befehlspuffer[i];
21
    TWCR = (1<<TWINT) | (1<<TWEN);
22
    while (!(TWCR & (1<<TWINT)));
23
  }
24
25
  // STOP-Bedingung senden und Übertragung abschließen
26
  if ((TWSR & 0xF8) != TW_MT_DATA_ACK)
27
    ERROR();
28
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
29
}

Ich weiß nicht, wie ich das Problem näher eingrenzen soll. Enthält der 
Code offensichtliche Fehler? Könnte der IC defekt sein (meine 
SMD-Lötkünste sind stark ausbaufähig...)? Ich wäre dankbar für jeden 
Hinweis!

von Johannes R. (jr17oo)


Lesenswert?

In meiner Bastelkiste habe ich eben einen DS1307 gefunden (der liegt da 
schon länger, ist aber unbenutzt, also vermutlich intakt), den ich an 
Stelle des PCA9685 angeschlossen habe.
Nun wird der Code vollständig ausgeführt, wobei allerdings beim 
Übertragen der Daten und dem Senden der STOP-Bedingung die Funktion 
ERROR() aufgerufen wird. Da der adressierte Empfänger nicht 
angeschlossen ist, war das wohl auch zu erwarten.

Sobald ich den PCA99685 nun parallel zum DS1307 anschließe (was 
theoretisch möglich sein sollte), tritt das ursprünglich geschilderte 
Verhalten wieder auf.

Daraus schließe ich nun, dass der IC defekt ist. Wahrscheinlich habe ich 
ihn beim Einlöten "gegrillt" (war mein erstes Bauteil in TSSOP-Bauform). 
Habe zum Glück noch drei Stück da, mit denen ich jetzt weitertesten 
kann...

von Johannes R. (jr17oo)


Angehängte Dateien:

Lesenswert?

Mit einem neuen IC klappt nun alles so wie ich mir das vorstelle. TSSOPs 
zu (ent-)löten ist garnicht so schwer, wenn man weiß wie...

Da das Programm aus dem ersten Beitrag noch einige kleine Fehler 
enthielt, habe ich hier nochmal eine korrigierte Version angehängt. 
Vielleicht nützt es ja jemandem, der sich mit dem PCA9685 beschäftigen 
will.

Danke an alle die sich die Mühe gemacht haben, einen Blick auf meinen 
Code zu werfen!

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.