Forum: Mikrocontroller und Digitale Elektronik TWI / I2C mit Atmega328P für PCA9685


von Amin L. (amin_l)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

Ich versuche schon seit einigen Stunden meinen PCA9685 zum laufen zu 
bringen.
Steuern wollte ich den Schaltkreis mittels ATmega328p.
Dafür verwende ich die i2cmaster Libary von Peter Fleury.

Um erstmal klein anzufangen, habe ich nur versucht den PCA9685 
anzusprechen.
Ich habe ihn über die A-Ports so konfiguriert das er die Adresse 0x40 
hat.
Das habe ich auch mit dem Arduino und dem I2C - Scanner überprüft.

Leider bekomme ich vom PWM Chip nie ein ACK zurück.

1
#define  F_CPU 16000000                          // CPU Frequenz = 16 Mhz  
2
3
4
#include <avr/io.h>                            // Bibiliothekseinbindung
5
#include <avr/interrupt.h>
6
#include <util/delay.h>
7
#include <util/twi.h>
8
#include <i2cmaster.h>
9
#include "twimaster.c"
10
11
#define ADR_1  0x40
12
13
14
15
int main(void)
16
{  
17
  sei();
18
  i2c_init();
19
  
20
  i2c_start_wait(ADR_1+I2C_WRITE);    // PCA9685 ansprechen
21
  i2c_write(0x00);            // Mode1 Register aufrufen
22
  i2c_write(0x10);            // in normal Mode versetzen
23
  i2c_stop();
24
  
25
    while (1) 
26
    {
27
  
28
    } 
29
30
}



Seltsamerweise läuft das ganze auch dauerhaft ab, obwohl es nicht in der 
Loop steht.
Hat einer ne Idee was ich falsch mache, und wie ich es berichtigen kann?
Im Anhang findet ihr die Busanalyse von meinem Oszi.


Danke schonmal im Vorraus.

von spess53 (Gast)


Lesenswert?

Hi

>#define ADR_1  0x40

Lt.Datenblatt ist die Adresse aber 0x80.

MfG Spess

von Amin L. (amin_l)


Lesenswert?

Hallo Spess und Danke für deine Antwort

wo hast du diese Information gefunden?

Lt meinem Datenblatt kann man über die Pins A[5:0] die Slave Adresse 
selbst konfigurieren.
Die Adresse setzt sich dort wie folgt zusammen:

[ 1 | A5 | A4 |...| A0 ]

https://cdn-shop.adafruit.com/datasheets/PCA9685.pdf

Gruß

von Hmmm (Gast)


Lesenswert?

Die Wiederholungen liegen daran, dass i2c_start_wait() im Gegensatz zu 
i2c_start() so lange probiert, bis ein ACK kommt, siehe Doku.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Amin L. schrieb:
> Die Adresse setzt sich dort wie folgt zusammen:
>
> [ 1 | A5 | A4 |...| A0 ]

Bit 0 bei I2C ist immer R/!W, deswegen verschieben sich die Adressen . 
Das ist leider immer wieder ein Quell von Mißverständnissen...

von Amin L. (amin_l)


Lesenswert?

Danke für deine Antwort
das habe ich wohl in seiner Doku überlesen.
Hast du eine Idee weshalb der Slave nicht bestätigt?

von Hmmm (Gast)


Lesenswert?

Wenn er mit der falschen Adresse angesprochen wird, gibt's kein ACK, 
nach der Korrektur sollte es klappen.

von Amin L. (amin_l)


Lesenswert?

Michael R. schrieb:
> Amin L. schrieb:
>> Die Adresse setzt sich dort wie folgt zusammen:
>>
>> [ 1 | A5 | A4 |...| A0 ]
>
> Bit 0 bei I2C ist immer R/!W, deswegen verschieben sich die Adressen .
> Das ist leider immer wieder ein Quell von Mißverständnissen...

Das weiß ich
deshalb habe ich im Quelltext ja auch
1
i2c_start_wait(ADR_1+I2C_WRITE);

das I2C_Write ist als 1 definiert

deshalb müsste es ja eigentlich auch funktionieren

[ 1 | A5 | A4 |...| A0 ] damit lege ich ja nur die Slave Adresse für den 
PCA9685 fest.

von Hmmm (Gast)


Lesenswert?

Du musst die Adresse ein Bit nach links schieben. Bit 0 ist R/!W, erst 
Bit 1 ist A0 etc.

von Amin L. (amin_l)


Lesenswert?

Aber wird die nicht Quellcodebegingt schon eins nach links verschoben?

Also wenn bei mir A5 High ist kommt doch folgende Adresse raus

[ 1 | 0 | 0 | 0 | 0 | 0 | 0 | W ]
__________________________
dieser Block ergibt meine ADR
also 0x40

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Amin L. schrieb:
> Aber wird die nicht Quellcodebegingt schon eins nach links verschoben?

Hängt von der Lib ab. Fleury macht das (aus meiner sicht) falsch

von Hmmm (Gast)


Lesenswert?

Amin L. schrieb:
> [ 1 | 0 | 0 | 0 | 0 | 0 | 0 | W ]
> ____________________________
> dieser Block ergibt meine ADR
> also 0x40

Nein, 0x80 bzw. 0x81, rechne nochmal nach.

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Amin L. schrieb:
> Die Adresse setzt sich dort wie folgt zusammen:
>
> [ 1 | A5 | A4 |...| A0 ]

Gut erkannt.

Für Dich markiert:

Gelb - Bit 7, fest vorgegeben
Blau - Bit 6 bis 1 - von Dir konfigurierbar
Rot  - Bit 0 - Lesen / Schreiben - gleichfalls von Dir beinflussbar

Adressen < 0x80 können also gar nicht vorkommen.

von Amin L. (amin_l)


Lesenswert?

Danke erstmal
Kann es sein das bei Fleury nur 1 auf das LSB addiert wird?

Dann glaube ich durch eure Hilfe den Fehler verstanden zu haben
Wenn ich das eben mal zusammenfasse

Bei I2C wird mit 8 Bit addressiert
Die eigentliche  Adresse ist 7 Bit lang + R/W als LSB
Beim PWM IC ist das MSB immer 1
Danach folgt meine frei gewählte Adresse + R/W

Wenn meine 7 Bit lange Adresse und 0x40 ist und ich eins Addiere komme 
ich auf 0x41 korrekt?
Um auf die die 8 Bit zu kommen wird mein MSB also 0 und der PCA kann es 
gar nicht detektieren?

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Amin L. schrieb:
> Bei I2C wird mit 8 Bit addressiert
> Die eigentliche  Adresse ist 7 Bit lang + R/W als LSB

Ja - und damit in Summe 8 Bit lang. 8 Bit = 1 Byte :-)
Wenn MSB immer = 1 (fix vorgegeben), dann Adresse immer >= 0x80.

Amin L. schrieb:
> Wenn meine 7 Bit lange Adresse und 0x40 ist und ich eins Addiere komme
> ich auf 0x41 korrekt?

Nein - s. o.

von Amin L. (amin_l)


Lesenswert?

Erscheint mir erstmal logisch.

Danke

Aber wie kann es sein, dass beim I2C scannen 0x40 als Adresse erkannt 
wurde?

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Amin L. schrieb:
> Bei I2C wird mit 8 Bit addressiert
> Die eigentliche  Adresse ist 7 Bit lang + R/W als LSB

Nein (meiner Meinung nach) eben nicht: eine I2C-Adresse ist 7 bit lang, 
von Ausnahmen (Global Call und so) abgesehen gibt es also etwas weniger 
als 127 Adressen. Das R/W Bit ist NICHT Bestandteil der Adresse, sonst 
hätte jedes Device ja zwei Adressen.

Deswegen meine ich, Fleury ist falsch (und zumindest teilschuld am 
Chaos)

Aber das thema hat potential für einen Glaubenskrieg :-)

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Amin L. schrieb:
> Aber wie kann es sein, dass beim I2C scannen 0x40 als Adresse erkannt
> wurde?

Womit hast du gescannt? Vermutlich mit etwas, welches die "richtige" 
Adressierung verwendet ;-)

von Amin L. (amin_l)


Lesenswert?

Das mit den 2 Adressen leuchtet mir erstmal ein.
Soweit habe ich auch noch gar nicht gedacht
Also wäre meine "Adresse" ja theoretisch wirklich 0x40 aber durch die 
Verschiebung nach links ist sie tatsächlich 0x80 oder 0x81?
Was bedeuten würde das jeder der sich an Fleurys Beispiel orientiert das 
gleiche Problem hat wie ich?

Mit dem Arduino und einem I2C Scanner Sketch

von Hmmm (Gast)


Lesenswert?

Amin L. schrieb:
> Aber wie kann es sein, dass beim I2C scannen 0x40 als Adresse erkannt
> wurde?

Die Adresse ist ja auch 0x40.

Bei der Adressierung auf dem Bus wird sie bloss zusammen mit dem 
R/!W-Bit gesendet und daher (bei Darstellung als Byte) ein Bit nach 
links geschoben.

Wenn Deine Telefonnummer 123456 ist, bleibt sie das auch dann, wenn der 
Anrufer aus dem Nachbarort eine Vorwahl davorsetzen muss.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Amin L. schrieb:
> Was bedeuten würde das jeder der sich an Fleurys Beispiel orientiert das
> gleiche Problem hat wie ich?

Bingo!

Richtigerweise müsstest du schreiben:
1
i2c_start_wait(ADR_1<<1 + I2C_WRITE);    // PCA9685 ansprechen

dann passts wieder

von Äxl (geloescht) (Gast)


Lesenswert?

Die 0x40, die dort "erkannt" wird, ist das "feste" MSB, welches sowieso 
gesetzt ist, oder? Wenn Du deine 0x40<<1 schiebst, landet das eine Bit 
genau an dieser Stelle. Der Logger wird das zur Anszeigezwecken schon 
wieder richtig nach rechts schieben. Um allen Eventualitäten aus dem Weg 
zugehen, nimm doch statt dessen 0x20 oder so. Das um ein Bit nach links 
geschoben, bringt dich nicht in Konflikt mit dem sowie "stehenden" 
MSB(bit7).
So - in der Art (nur laut gedacht)...

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Äxl (geloescht) schrieb:
> (nur laut gedacht)

zu laut?

die 0x40 ist schon genau seine Adresse, und nicht nur das MSB 
(vermutlich liegen die Ax alle auf GND)

von Amin L. (amin_l)


Lesenswert?

Hallo, und Danke erstmal für alle Antworten

ich habe A5 jetzt noch auf V+ gehangen, sodass ich eine 7 Bit Slave 
Adresse von 60h habe. Wenn ich lesen will ist mein achtes Bit "1" beim 
Schreiben "0".
Also habe ich den Quelltext wie folgt verändert
1
 i2c_start_wait(0xC0);
und plötzlich bekomme ich auch ein "ACK" zurück ;)

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.