Forum: Mikrocontroller und Digitale Elektronik Probleme mit Ack bei I2C und MAX3373


von mike (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe einen µC von Atmel (5V) und einen Beschleunigungssensor von 
freescale (3,3V), dazischen einen Pegelwandler Max3373. Ich bekomme 
keine Übertragung hin, weil der Acknowledge nicht ankommt.

Vorab: Die 5V brauche ich, weil die meisten anderen Schaltungsteile über 
5V laufen.

Ich habe auf der 5V-Seite und auch auf der 3,3V Seite jeweils einen 
Pullup von 4k7 gemäß Datenblatt an SCL und SDA hängen.

Ich habe den max3373 sowohl mit, als auch ohne three-state ausprobiert.
Lege ich den Threestate auf Masse, kommt keine Übertragung zu stande, 
weil auf der 3,3V Seite nichts ankommt.
Lege ich den threestate auf 3,3V werden die Daten übertragen, wenn 
jedoch der Acknowledge kommt, wird die Leitung nicht auf 0V gezogen, 
sondern auf 1,65V. Der Max3373 erkennt das nicht als Low und gibt das 
natürlich nicht weiter.
Ich habe auch schon probiert die externen Widerstände wegzulassen bzw. 
10k-Widerstände einzusetzen, die dann mit den internen parallel 
arbeiten, alles ohne Erfolg.

Ich verstehe auch nicht, wenn ich die internen wegschalte (threestate 
low), warum dann keine Signale übertragen werden.

Ich arbeite zum ersten mal mit dem max3373. Mache ich etwas falsch? wie 
geht es richtig?

Im Anhang ist das Oszilloskopbild der 3,3V Seite mit threestate high 
(3,3V)

von Michael H. (michael_h45)


Lesenswert?

Das Ack kommt nicht vom Max, sondern vom angeschlossenen Teilnehmer. 
Wenn der die 4,7k nicht auf Masse ziehen kann, ist er entweder falsch 
angeschlossen, kaputt, oder braucht größere Pullups.

von TK (Gast)


Lesenswert?

Sinnvoll wäre hier zuerst mal der Schaltplan. Alles andere ist 
Glaskugel! Und der PullUp sollte eher kleiner als größer ausfallen.

Gruß
TK

von Michael H. (michael_h45)


Lesenswert?

TK schrieb:
> Und der PullUp sollte eher kleiner als größer ausfallen.
darüber denken wir nochmal nach...

von TK (Gast)


Lesenswert?

Denk,denk...
stimmt - PullUp sollte eher kleiner sein, als größer (hast Du schon mal 
in der IIC Spec gelesen? Da stehen solche Kleinigkeiten nämlich drin)

TK

von mike (Gast)


Lesenswert?

Hallo zusammen,

ich bins nochmal.
Mein Problem bleibt.
Nach einigen Wochen habe ich mich noch einmal an den I2C bzw. TWI Bus 
gewagt.
Die Voraussetzungen sind jetzt völlig andere, aber die Probleme bleiben 
die Gleichen.

- Ich programmieren einen AT90CAN128 auf einem EVAL-Board (nicht wie 
zuvor auf einer eigenen Platine).
- Ich möchte per I2C mit einem Sensor kommunizieren, es ict nicht der 
Gleiche wie in #1 sondern ein Sensor von ST
- Die Kommunikation läuft diesmal direkt: Beides wird an 3V betrieben 
(erzeugt vom EVAL-Board), beide Bausteine sind direkt verbunden - ohne 
Pegelwandler

Ergebnis:
Mein Atmel sendet die Adresse des Sensors, dieser reagiert mit einem ACK 
- aber er zieht SDA nicht auf 0V sondern "nur" auf 1,76 V. Das Bild aus 
Posting 1 ist also noch immer aktuell. Sende ich eine andere Adresse 
erfolgt kein ACK und SDA bleibt durch PullUp auf 3V.

Ich habe verschiedene Pull-Up Varianten ausprobiert:
-(Die internen vom AT90CAN habe deaktiviert)
- Externe Pull-Ups vom Board (4k7) über Jumper hinzu
- Externe Pull-Ups 10k
- Externe Pull-Ups  1k

Leider ohne Erfolg. Interessant: Der Spannungspegel bei ACK von 1,76V 
hat sich bei keinem Pull-Up Wert verändert und ist immer gleich 
geblieben.

Was kann das sein?
- Den Sensor schließe ich aus, da ich verschidene ausprobiert habe.
- Mein eigenes Board schließe ich aus, weil ich aktuell ein EVAL-Board 
von Atmel nutze (DK90CAN1)
==> Muss wohl am Code/ an der Programmierung oder irgendwelchen 
Einstellungen liegen.
Ich benutze bei der Programmierung die LIB von P.Fleury
Hier meine Kommentare zum Code:
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
--> OK
8
9
  // wait until transmission completed
10
  while(!(TWCR & (1<<TWINT)));
11
--> OK
12
13
  // check value of TWI Status Register. Mask prescaler bits.
14
  twst = TW_STATUS & 0xF8;
15
  if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
16
--> OK
17
18
  // send device address
19
  TWDR = address;
20
  TWCR = (1<<TWINT) | (1<<TWEN);
21
--> OK
22
23
  // wail until transmission completed and ACK/NACK has been received
24
  while(!(TWCR & (1<<TWINT)));
25
--> OK
26
27
  // check value of TWI Status Register. Mask prescaler bits.
28
  twst = TW_STATUS & 0xF8;
29
  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return twst;
30
--> Hier liefert mir die Return Funktion 0x20 zurück
31
    Bedeutung: Not Acknowledge received after the slave adress
32
    Bild hierzu: siehe Posting 1
33
    Spannung bei erwartetem ACK= 1,76V 
34
35
  return 0;
36
37
}/* i2c_start */

von mike (Gast)


Lesenswert?

Ich bins nochmal, mit der Lösung des Problems!

Leider hat mir niemand geantwortet bzw. helfen können.
Um das Thema abzuschliessen möchte ich nun aber das Rätsel lösen. Ich 
habe das Problem gefunden.

Das Problem lag an der Port-Definition bzw. der Datenrichtung.
Ich habe die Ports als Ausgang definiert (SDA/SCL). Hier zeigte sich das 
angesprochene Fehlerbild.

Nachdem ich die Ports als Eingang definiert und die Pull-Ups 
ausgeschaltet habe, lief die Kommunikation problemlos und der Slave 
konnte die SDA-Line auf Low ziehen.
Nun läuft meine I2C Kommunikation wie gewünscht.

von spess53 (Gast)


Lesenswert?

Hi

>Das Problem lag an der Port-Definition bzw. der Datenrichtung.
>Ich habe die Ports als Ausgang definiert (SDA/SCL). Hier zeigte sich das
>angesprochene Fehlerbild.

Kann ich nicht wirklich glauben.

Datenblatt eines AVRs (Alternate Port Functions):

SDA, 2-wire Serial Interface Data: When the TWEN bit in TWCR is set 
(one) to enable the 2-wire Serial Interface, pin PD1 is disconnected 
from the port and becomes the Serial Data I/O pin for the 2-wire Serial 
Interface. In this mode, there is a spike filter on the pin to suppress 
spikes
shorter than 50ns on the input signal, and the pin is driven by an open 
drain driver with slew-rate Limitation.

Die internen PullUp-Widerstände lassen sich einschalten, aber die 
restlichen Portfunktionen werden vom TWI übernommen.

MfG Spess

von mike (Gast)


Lesenswert?

Hallo spess53,

doch es ist so. Nach deinem Beitrag habe ich das sofort ausprobiert. Und 
schon habe ich wieder das Phänomen, dass die Kommunikation nicht läuft 
und der Acknowledge ca. auf halber Spannungshöhe ist.

Hier der Code:
1
DDRD  = 0x00; // Set as Input
2
PORTD = 0x00; // alle Pull ups aus
3
DDRD  = 0x03; // mit dieser Zeile keine Kommunikation möglich
4
              // ohne dieser Zeile läuft die Kommunikation einwandfrei

von spess53 (Gast)


Lesenswert?

Hi

>doch es ist so.

Tut mir Leid, ich kann das nicht nachvollziehen. Gerade mal schnell mit 
einem ATMega644P getestet: DDRC0/1 (SDA/SCL) als Ausgang gesetzt. Egal, 
wie ich die Port-Bits setze, kein Unterschied. TWI läuft wie geschmiert.

MfG Spess

von mike (Gast)


Lesenswert?

Dann weiß ich auch nicht :(

Wie oben beschrieben, kann ich diesen "Fehler" bzw. ungewünschte 
Reaktion mit der Direction-Umschaltung(DDR) jederzeit rekonstruieren.
Ich arbeite übrigens mit dem AT90CAN. Vielleicht regiert der 
empfindlicher.

von spess53 (Gast)


Lesenswert?

Hi

>Ich arbeite übrigens mit dem AT90CAN. Vielleicht regiert der
>empfindlicher.

Unwahrscheinlich. Das einzige, was ich mir vorstellen kann ist ein 
Problem mit den Pull-Up-Widerständen. Die internen sind nur aktiv, wenn 
die Pins als Eingang konfiguriert sind. Bei Ausgang sind die 
weggeschaltet.

MfG Spess

von mike (Gast)


Lesenswert?

2. Update:

Ich habe mit dieser Erkenntnis die TWI-Schnittstelle auf meinem eigenen 
Board (siehe 1. Posting) mit dem Pegelwandler MAX3373 in Betrieb 
genommen.
Prozessor der Gleiche, Platine = eigenes Design, MAX3373, Beschl.Sensor 
von freescale.
Auch hier funktioniert die I2C - Kommunikation sobald ich die Ports 
(SDA/SCL von PortD) nicht mehr als Ausgang setze, sondern DDR auf 0 
belasse.

Kann das jemand nachvollziehen, der ebenfalls einen AT90CAN einsetzt?

von Peter D. (peda)


Lesenswert?

mike schrieb:
> Ich arbeite übrigens mit dem AT90CAN.

Da scheint tatsächlich ein Bug drin zu sein.
In der Tabelle (Table 9-14. Overriding Signals for Alternate Functions 
in PD3..PD0) ist für PD0,1 das DDOE = 0.
D.h. das Output-Enable wird nicht durch TWEN umgeschaltet.
Ist wohl bisher nicht aufgefallen, da der Resetzustand ja disabled ist. 
Und (fast) niemand dreht an Bits ohne Grund.
Fragt sich aber bloß, wie die Pins vom TWI auf low gezogen werden, laut 
Schaltbild (Figure 9-5. Alternate Port Functions) ist das dann 
unmöglich.

Z.B. beim ATmega8 ist dagegen für PC4,5 das DDOE = TWEN, wie es sich 
gehört.

von Marcus (Gast)


Lesenswert?

Hallo,

ich bin zufällig (auf der Suche nach Hilfe bei einem Problem mit dem TWI 
am AT90CAN128) über diesen Beitrag gestolpert.

Ich habe einen ATmega128 und einen AT90can128, beide sollen miteinander 
über TWI reden.

Beim ATmega128 lief das TWI sofort.
Den Code für den AT90can128 kompiliert..., funktionierte gar nicht.
Der AT90can128 als SLAVE, hat die SDA immer auf halben Pegel gezogen.

Mit der Erkenntnis von mike lief die Kommunikation auf Anhieb.

Gruß
Marcus

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.