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)
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.
Sinnvoll wäre hier zuerst mal der Schaltplan. Alles andere ist Glaskugel! Und der PullUp sollte eher kleiner als größer ausfallen. Gruß TK
TK schrieb: > Und der PullUp sollte eher kleiner als größer ausfallen. darüber denken wir nochmal nach...
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
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 */ |
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.
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
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
|
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
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.
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
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?
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.